From: John Kohl Date: Wed, 20 Feb 1991 14:46:30 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: krb5-1.0-alpha4~236 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=c9290698eb986daed9b720eb16c478b56f2fe6ff;p=krb5.git *** empty log message *** git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@1736 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/tests/hammer/Imakefile b/src/tests/hammer/Imakefile new file mode 100644 index 000000000..3c31b4645 --- /dev/null +++ b/src/tests/hammer/Imakefile @@ -0,0 +1,13 @@ +# $Source$ +# $Author$ +# $Id$ +# +# Copyright 1990 by the Massachusetts Institute of Technology. +# +# For copying and distribution information, please see the file +# . +# + DEPLIBS = $(DEPKLIB) +LOCAL_LIBRARIES = $(KLIB) + +SimpleProgramTarget(kdc5_hammer) diff --git a/src/tests/hammer/kdc5_hammer.c b/src/tests/hammer/kdc5_hammer.c new file mode 100644 index 000000000..0da45b287 --- /dev/null +++ b/src/tests/hammer/kdc5_hammer.c @@ -0,0 +1,407 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990,1991 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * For copying and distribution information, please see the file + * . + * + * Initialize a credentials cache. + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_hammer_c [] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include + +#include +#include +#include +#include /* for TGTNAME */ +#include +#include + +#include + +#define KRB5_DEFAULT_OPTIONS 0 +#define KRB5_DEFAULT_LIFE 60*60*8 /* 8 hours */ +#define KRB5_RENEWABLE_LIFE 60*60*2 /* 2 hours */ + +extern int optind; +extern char *optarg; +char *prog; + +static int brief; + +krb5_error_code +krb5_parse_lifetime (time, len) + char *time; + long *len; +{ + *len = atoi (time) * 60 * 60; /* XXX stub version */ + return 0; +} + +krb5_data tgtname = { + sizeof(TGTNAME)-1, + TGTNAME +}; + +int verify_cs_pair(char *, krb5_principal, char *, int, int, int, krb5_ccache); +int get_tgt (char *, krb5_principal *, krb5_ccache); + +static void +usage(who, status) +char *who; +int status; +{ + fprintf(stderr, + "usage: %s -p prefix -n num_to_check [-d dbpathname] [-r realmname]\n", + who); + fprintf(stderr, "\t [-D depth] [-k keytype] [-e etype] [-M mkeyname]\n"); + fprintf(stderr, "\t [-r repeat_count]\n"); + + exit(status); +} + +static krb5_enctype etype = 0xffff; +static krb5_keytype keytype; + +void +main(argc, argv) + int argc; + char **argv; +{ + krb5_ccache ccache = NULL; + char *cache_name = NULL; /* -f option */ + int option; + int errflg = 0; + krb5_error_code code; + int num_to_check, n, i, j, repeat_count, counter; + int n_tried, errors, keytypedone; + char prefix[BUFSIZ], *client, *server; + int depth; + char ctmp[4096], ctmp2[BUFSIZ], stmp[4096], stmp2[BUFSIZ]; + krb5_principal client_princ; + + krb5_init_ets(); + + if (strrchr(argv[0], '/')) + prog = strrchr(argv[0], '/')+1; + + num_to_check = 0; + depth = 1; + repeat_count = 1; + brief = 0; + n_tried = 0; + errors = 0; + keytypedone = 0; + + while ((option = getopt(argc, argv, "D:p:n:c:r:k:e:bv")) != EOF) { + switch (option) { + case 'b': + brief = 1; + break; + case 'v': + brief = 0; + break; + case 'r': + repeat_count = atoi(optarg); /* how many times? */ + break; + case 'D': + depth = atoi(optarg); /* how deep to go */ + break; + case 'p': /* prefix name to check */ + strcpy(prefix, optarg); + break; + case 'n': /* how many to check */ + num_to_check = atoi(optarg); + break; + case 'k': + keytype = atoi(optarg); + keytypedone++; + break; + case 'e': + etype = atoi(optarg); + break; + case 'c': + if (ccache == NULL) { + cache_name = optarg; + + code = krb5_cc_resolve (cache_name, &ccache); + if (code != 0) { + com_err (prog, code, "resolving %s", cache_name); + errflg++; + } + } else { + fprintf(stderr, "Only one -c option allowed\n"); + errflg++; + } + break; + case '?': + default: + errflg++; + break; + } + } + + if (!(num_to_check && prefix[0])) usage(prog, 1); + + if (!keytypedone) + keytype = DEFAULT_KDC_KEYTYPE; + + if (!valid_keytype(keytype)) { + com_err(prog, KRB5_PROG_KEYTYPE_NOSUPP, + "while setting up keytype %d", keytype); + exit(1); + } + + if (etype == 0xffff) + etype = krb5_keytype_array[keytype]->system->proto_enctype; + + if (!valid_etype(etype)) { + com_err(prog, KRB5_PROG_ETYPE_NOSUPP, + "while setting up etype %d", etype); + exit(1); + } + + if (ccache == NULL) { + if (code = krb5_cc_default(&ccache)) { + com_err(prog, code, "while getting default ccache"); + exit(1); + } + } + + memset(ctmp, 0, sizeof(ctmp)); + memset(stmp, 0, sizeof(stmp)); + + for (counter = 0; counter < repeat_count; counter++) { + fprintf(stderr, "\nRound %d\n", counter); + + for (n = 1; n <= num_to_check; n++) { + /* build the new principal name */ + /* we can't pick random names because we need to generate all the names + again given a prefix and count to test the db lib and kdb */ + ctmp[0] = '\0'; + for (i = 1; i <= depth; i++) { + ctmp2[0] = '\0'; + (void) sprintf(ctmp2, "%s%s%d-DEPTH-%d", (i != 1) ? "/" : "", + prefix, n, i); + strcat(ctmp, ctmp2); + client = ctmp; + + if ((counter != 0) && (n != 1)) krb5_free_principal(client_princ); + if (get_tgt (client, &client_princ, ccache)) { + errors++; + n_tried++; + continue; + } + n_tried++; + + stmp[0] = '\0'; + for (j = 1; j <= depth; j++) { + stmp2[0] = '\0'; + (void) sprintf(stmp2, "%s%s%d-DEPTH-%d", (j != 1) ? "/" : "", + prefix, n, j); + strcat(stmp, stmp2); + server = stmp; + if (verify_cs_pair(client, client_princ, server, n, i, j, ccache)) + errors++; + n_tried++; + } + } + } + } + fprintf (stderr, "\n%Tried %d. Got %d errors.\n", n_tried, errors); + } + + +krb5_error_code get_server_key(keyprocarg, princ, vno, key) + krb5_pointer keyprocarg; + krb5_principal princ; + krb5_kvno vno; + krb5_keyblock **key; +{ + krb5_data pwd, salt; + char *princ_str, *at; + krb5_error_code code; + /* Does this belong here or in libos or something? */ + + code = krb5_unparse_name(princ, &princ_str); + if (code) { + com_err (prog, code, "while unparsing server name"); + return(code); + } + + /* The kdb5_create does not include realm names in the password ... + this is ugly */ + at = index(princ_str, '@'); + if (at) *at = NULL; + + pwd.data = princ_str; + pwd.length = strlen(princ_str); + + if (code = krb5_principal2salt(princ, &salt)) { + com_err(prog, code, "while converting principal to salt for '%s'", princ_str); + goto errout; + } + + *key = (krb5_keyblock *)malloc(sizeof(**key)); + if (!*key) { + code = ENOMEM; + com_err(prog, code, "while allocating key for server %s", princ_str); + goto errout; + } + if (code = (*krb5_keytype_array[keytype]->system-> + string_to_key)(keytype, + *key, + &pwd, + &salt)) + goto errout; + +out: + if (princ_str) free(princ_str); + if (salt.data) free(salt.data); + return(code); + + errout: + if (*key) xfree(*key); + goto out; + +} + +int verify_cs_pair(p_client_str, p_client, p_server_str, p_num, + c_depth, s_depth, ccache) + char *p_client_str; + krb5_principal p_client; + char *p_server_str; + int p_num, c_depth, s_depth; + krb5_ccache ccache; +{ + krb5_error_code code; + krb5_principal server; + krb5_data request_data; + char *returned_client; + krb5_tkt_authent authdat; + + if (brief) + fprintf(stderr, "\tprinc (%d) client (%d) for server (%d)\n", + p_num, c_depth, s_depth); + else + fprintf(stderr, "\tclient %s for server %s\n", p_client_str, + p_server_str); + + if (code = krb5_parse_name (p_server_str, &server)) { + com_err (prog, code, "when parsing name %s", p_server_str); + return(-1); + } + + /* test the checksum stuff? */ + if (code = krb5_mk_req(server, 0, 0, ccache, &request_data)) { + com_err(prog, code, "while preparing AP_REQ for %s", p_server_str); + return(-1); + } + + if (code = krb5_rd_req(&request_data, server, 0, 0, get_server_key, 0, 0, + &authdat)) { + com_err(prog, code, "while decoding AP_REQ for %s", p_server_str); + return(-1); + } + + if (!krb5_principal_compare(authdat.authenticator->client, p_client)) { + code = krb5_unparse_name(authdat.authenticator->client, &returned_client); + if (code) + com_err (prog, code, + "Client not as expected, but cannot unparse client name"); + else + com_err (prog, 0, "Client not as expected (%s).", returned_client); + if (authdat.ticket) xfree(authdat.ticket); + if (authdat.authenticator) xfree(authdat.authenticator); + free(returned_client); + return(-1); + } + + if (authdat.ticket) xfree(authdat.ticket); + if (authdat.authenticator) xfree(authdat.authenticator); + krb5_free_principal(server); + if (request_data.data) xfree(request_data.data); + + return(0); +} + +int get_tgt (p_client_str, p_client, ccache) + char *p_client_str; + krb5_principal *p_client; + krb5_ccache ccache; +{ + char *cache_name = NULL; /* -f option */ + long lifetime = KRB5_DEFAULT_LIFE; /* -l option */ + int options = KRB5_DEFAULT_OPTIONS; + krb5_address **my_addresses; + krb5_error_code code; + krb5_creds my_creds; + krb5_timestamp start; + krb5_data *tgt_server[4]; + + if (!brief) + fprintf(stderr, "\tgetting TGT for %s\n", p_client_str); + + if (code = krb5_timeofday(&start)) { + com_err(prog, code, "while getting time of day"); + return(-1); + } + + memset((char *)&my_creds, 0, sizeof(my_creds)); + + if (code = krb5_parse_name (p_client_str, p_client)) { + com_err (prog, code, "when parsing name %s", p_client_str); + return(-1); + } + + my_creds.server = tgt_server; + + tgt_server[0] = *p_client[0]; /* realm name */ + tgt_server[1] = &tgtname; + tgt_server[2] = *p_client[0]; + tgt_server[3] = 0; + + code = krb5_os_localaddr(&my_addresses); + if (code != 0) { + com_err (prog, code, "when getting my address"); + exit(1); + } + + my_creds.client = *p_client; + my_creds.server = tgt_server; + + krb5_cc_destroy(ccache); /* ugh, I'd much rather just delete the credential */ + + code = krb5_cc_initialize (ccache, *p_client); + if (code != 0) { + com_err (prog, code, "when initializing cache %s", + cache_name?cache_name:""); + return(-1); + } + + my_creds.times.starttime = 0; /* start timer when request + gets to KDC */ + my_creds.times.endtime = start + lifetime; + my_creds.times.renew_till = 0; + + code = krb5_get_in_tkt_with_password(options, my_addresses, + etype, + keytype, + p_client_str, + ccache, + &my_creds); + if (code != 0) { + com_err (prog, code, "while getting initial credentials"); + return(-1); + } + + return(0); +} diff --git a/src/tests/verify/Imakefile b/src/tests/verify/Imakefile new file mode 100644 index 000000000..1e80bb19d --- /dev/null +++ b/src/tests/verify/Imakefile @@ -0,0 +1,13 @@ +# $Source$ +# $Author$ +# $Id$ +# +# Copyright 1990 by the Massachusetts Institute of Technology. +# +# For copying and distribution information, please see the file +# . +# +DEPLIBS = $(DEPKDBLIB) $(DEPKLIB) +LOCAL_LIBRARIES = $(KDBLIB) $(KLIB) + +SimpleProgramTarget(kdb5_verify) diff --git a/src/tests/verify/kdb5_verify.c b/src/tests/verify/kdb5_verify.c new file mode 100644 index 000000000..c89594f63 --- /dev/null +++ b/src/tests/verify/kdb5_verify.c @@ -0,0 +1,449 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990,1991 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * For copying and distribution information, please see the file + * . + * + * Edit a KDC database. + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_kdb_edit_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include +#include +#include +#include +#include +#include +#include /* for MAXPATHLEN */ +#include + +#include +#include +#include + + +#define REALM_SEP '@' +#define REALM_SEP_STR "@" + +struct mblock { + krb5_deltat max_life; + krb5_deltat max_rlife; + krb5_timestamp expiration; + krb5_flags flags; + krb5_kvno mkvno; +} mblock = { /* XXX */ + KRB5_KDB_MAX_LIFE, + KRB5_KDB_MAX_RLIFE, + KRB5_KDB_EXPIRATION, + KRB5_KDB_DEF_FLAGS, + 0 +}; + +int set_dbname_help PROTOTYPE((char *, char *)); + +static void +usage(who, status) +char *who; +int status; +{ + fprintf(stderr, + "usage: %s -p prefix -n num_to_check [-d dbpathname] [-r realmname]\n", + who); + fprintf(stderr, "\t [-D depth] [-k keytype] [-e etype] [-M mkeyname]\n"); + + exit(status); +} + +krb5_keyblock master_keyblock; +krb5_principal master_princ; +krb5_db_entry master_entry; +krb5_encrypt_block master_encblock; +krb5_pointer master_random; +char *str_master_princ; + +static char *progname; +static char *cur_realm = 0; +static char *mkey_name = 0; +static krb5_boolean manual_mkey = FALSE; +static krb5_boolean dbactive = FALSE; + +void +quit() +{ + krb5_error_code retval = krb5_db_fini(); + memset((char *)master_keyblock.contents, 0, master_keyblock.length); + if (retval) { + com_err(progname, retval, "while closing database"); + exit(1); + } + exit(0); +} + +int check_princ PROTOTYPE((char *)); + +void +main(argc, argv) +int argc; +char *argv[]; +{ + extern char *optarg; + int optchar, i, n; + char tmp[4096], tmp2[BUFSIZ], *str_princ; + + krb5_error_code retval; + char *dbname = 0; + char defrealm[BUFSIZ]; + int keytypedone = 0; + krb5_enctype etype = 0xffff; + register krb5_cryptosystem_entry *csentry; + int num_to_check; + char principal_string[BUFSIZ]; + char *suffix; + int depth, errors; + + krb5_init_ets(); + + if (strrchr(argv[0], '/')) + argv[0] = strrchr(argv[0], '/')+1; + + progname = argv[0]; + + memset(principal_string, 0, sizeof(principal_string)); + num_to_check = 0; + depth = 1; + + while ((optchar = getopt(argc, argv, "D:p:n:d:r:R:k:M:e:m")) != EOF) { + switch(optchar) { + case 'D': + depth = atoi(optarg); /* how deep to go */ + break; + case 'p': /* prefix name to check */ + strcpy(principal_string, optarg); + suffix = principal_string + strlen(principal_string); + break; + case 'n': /* how many to check */ + num_to_check = atoi(optarg); + break; + case 'd': /* set db name */ + dbname = optarg; + break; + case 'r': + cur_realm = optarg; + break; + case 'k': + master_keyblock.keytype = atoi(optarg); + keytypedone++; + break; + case 'M': /* master key name in DB */ + mkey_name = optarg; + break; + case 'e': + etype = atoi(optarg); + break; + case 'm': + manual_mkey = TRUE; + break; + case '?': + default: + usage(progname, 1); + /*NOTREACHED*/ + } + } + + if (!(num_to_check && principal_string[0])) usage(progname, 1); + + if (!keytypedone) + master_keyblock.keytype = DEFAULT_KDC_KEYTYPE; + + if (!valid_keytype(master_keyblock.keytype)) { + com_err(progname, KRB5_PROG_KEYTYPE_NOSUPP, + "while setting up keytype %d", master_keyblock.keytype); + exit(1); + } + + if (etype == 0xffff) + etype = krb5_keytype_array[master_keyblock.keytype]->system->proto_enctype; + + if (!valid_etype(etype)) { + com_err(progname, KRB5_PROG_ETYPE_NOSUPP, + "while setting up etype %d", etype); + exit(1); + } + master_encblock.crypto_entry = krb5_csarray[etype]->system; + csentry = master_encblock.crypto_entry; + + if (!dbname) + dbname = DEFAULT_DBM_FILE; /* XXX? */ + + if (!cur_realm) { + if (retval = krb5_get_default_realm(sizeof(defrealm), defrealm)) { + com_err(progname, retval, "while retrieving default realm name"); + exit(1); + } + cur_realm = defrealm; + } + if (retval = set_dbname_help(progname, dbname)) + exit(retval); + + errors = 0; + + fprintf(stdout, "\nChecking "); + + for (n = 1; n <= num_to_check; n++) { + /* build the new principal name */ + /* we can't pick random names because we need to generate all the names + again given a prefix and count to test the db lib and kdb */ + (void) sprintf(suffix, "%d", n); + (void) sprintf(tmp, "%s-DEPTH-1", principal_string); + str_princ = tmp; + if (check_princ(str_princ)) errors++; + + for (i = 2; i <= depth; i++) { + tmp2[0] = '\0'; + (void) sprintf(tmp2, "/%s-DEPTH-%d", principal_string, i); + strcat(tmp, tmp2); + str_princ = tmp; + if (check_princ(str_princ)) errors++; + } + } + + if (errors) + fprintf(stdout, "\n%d errors principals failed.\n", errors); + else + fprintf(stdout, "\nNo errors.\n"); + + (void) (*csentry->finish_key)(&master_encblock); + (void) (*csentry->finish_random_key)(&master_random); + retval = krb5_db_fini(); + memset((char *)master_keyblock.contents, 0, master_keyblock.length); + if (retval && retval != KRB5_KDB_DBNOTINITED) { + com_err(progname, retval, "while closing database"); + exit(1); + } + exit(0); +} + +int +check_princ(DECLARG(char *, str_princ)) +OLDDECLARG(char *, str_princ) +{ + krb5_error_code retval; + krb5_db_entry kdbe; + krb5_keyblock pwd_key, db_key; + krb5_data pwd, salt; + krb5_principal princ; + krb5_boolean more; + int nprincs = 1; + char *str_mod_name; + + fprintf(stderr, "\t%s ...\n", str_princ); + + if (retval = krb5_parse_name(str_princ, &princ)) { + com_err(progname, retval, "while parsing '%s'", str_princ); + goto out; + } + + pwd.data = str_princ; /* must be able to regenerate */ + pwd.length = strlen(str_princ); + + if (retval = krb5_principal2salt(princ, &salt)) { + com_err(progname, retval, "while converting principal to salt for '%s'", str_princ); + goto out; + } + + retval = krb5_string_to_key(&master_encblock, master_keyblock.keytype, + &pwd_key, + &pwd, + &salt); + if (retval) { + com_err(progname, retval, "while converting password to key for '%s'", str_princ); + goto out; + } + + if (retval = krb5_db_get_principal(princ, &kdbe, &nprincs, &more)) { + com_err(progname, retval, "while attempting to verify principal's existence"); + goto out; + } + + if (nprincs != 1) { + com_err(progname, 0, "Found more than one db entry for %s.\n", str_princ); + goto out; + } + + retval = krb5_kdb_decrypt_key(&master_encblock, + &kdbe.key, + &db_key); + if (retval) { + com_err(progname, retval, "while decrypting key for '%s'", str_princ); + goto out; + } + + if ((pwd_key.keytype != db_key.keytype) | + (pwd_key.length != db_key.length)) { + fprintf (stderr, "\tKey types do not agree (%d expected, %d from db)\n", + pwd_key.keytype, db_key.keytype); +errout: + krb5_db_free_principal(&kdbe, nprincs); + return(-1); + } + else { + if (memcmp((char *)pwd_key.contents, (char *) db_key.contents, pwd_key.length)) { + fprintf(stderr, "\t key did not match stored value for %s\n", + str_princ); + goto errout; + } + } + + free((char *)pwd_key.contents); + free((char *)db_key.contents); + + if (kdbe.kvno != 0) { + fprintf(stderr, "\tkvno did not match stored value for %s.\n", str_princ); + goto errout; + } + + if (kdbe.max_life != mblock.max_life) { + fprintf(stderr, "\tmax life did not match stored value for %s.\n", + str_princ); + goto errout; + } + + if (kdbe.max_renewable_life != mblock.max_rlife) { + fprintf(stderr, + "\tmax renewable life did not match stored value for %s.\n", + str_princ); + goto errout; + } + + if (kdbe.mkvno != mblock.mkvno) { + fprintf(stderr, "\tmaster keyvno did not match stored value for %s.\n", + str_princ); + goto errout; + } + + if (kdbe.expiration != mblock.expiration) { + fprintf(stderr, "\texpiration time did not match stored value for %s.\n", + str_princ); + goto errout; + } + + if (retval = krb5_unparse_name(kdbe.mod_name, &str_mod_name)) + com_err(progname, retval, "while unparsing mode name"); + else { + if (strcmp(str_mod_name, str_master_princ) != 0) { + fprintf(stderr, "\tmod name isn't the master princ (%s not %s).\n", + str_mod_name, str_master_princ); + free(str_mod_name); + goto errout; + } + else free(str_mod_name); + } + + if (kdbe.attributes != mblock.flags) { + fprintf(stderr, "\tAttributes did not match stored value for %s.\n", + str_princ); + goto errout; + } + + out: + krb5_db_free_principal(&kdbe, nprincs); + + return(0); +} + +int +set_dbname_help(pname, dbname) +char *pname; +char *dbname; +{ + krb5_error_code retval; + int nentries; + krb5_boolean more; + register krb5_cryptosystem_entry *csentry; + + csentry = master_encblock.crypto_entry; + + if (retval = krb5_db_set_name(dbname)) { + com_err(pname, retval, "while setting active database to '%s'", + dbname); + return(1); + } + /* assemble & parse the master key name */ + + if (retval = krb5_db_setup_mkey_name(mkey_name, cur_realm, 0, + &master_princ)) { + com_err(pname, retval, "while setting up master key name"); + return(1); + } + if (retval = krb5_db_fetch_mkey(master_princ, &master_encblock, + manual_mkey, + FALSE, &master_keyblock)) { + com_err(pname, retval, "while reading master key"); + return(1); + } + if (retval = krb5_db_init()) { + com_err(pname, retval, "while initializing database"); + return(1); + } + if (retval = krb5_db_verify_master_key(master_princ, &master_keyblock, + &master_encblock)) { + com_err(pname, retval, "while verifying master key"); + (void) krb5_db_fini(); + return(1); + } + nentries = 1; + if (retval = krb5_db_get_principal(master_princ, &master_entry, &nentries, + &more)) { + com_err(pname, retval, "while retrieving master entry"); + (void) krb5_db_fini(); + return(1); + } else if (more) { + com_err(pname, KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, + "while retrieving master entry"); + (void) krb5_db_fini(); + return(1); + } else if (!nentries) { + com_err(pname, KRB5_KDB_NOENTRY, "while retrieving master entry"); + (void) krb5_db_fini(); + return(1); + } + + if (retval = krb5_unparse_name(master_princ, &str_master_princ)) { + com_err(pname, retval, "while unparsing master principal"); + krb5_db_fini(); + return(1); + } + + if (retval = (*csentry->process_key)(&master_encblock, + &master_keyblock)) { + com_err(pname, retval, "while processing master key"); + (void) krb5_db_fini(); + return(1); + } + if (retval = (*csentry->init_random_key)(&master_keyblock, + &master_random)) { + com_err(pname, retval, "while initializing random key generator"); + (void) (*csentry->finish_key)(&master_encblock); + (void) krb5_db_fini(); + return(1); + } + mblock.max_life = master_entry.max_life; + mblock.max_rlife = master_entry.max_renewable_life; + mblock.expiration = master_entry.expiration; + /* don't set flags, master has some extra restrictions */ + mblock.mkvno = master_entry.kvno; + + krb5_db_free_principal(&master_entry, nentries); + dbactive = TRUE; + return 0; +} +