17c478bd9Sstevel@tonic-gate /* 2*dd9ccd46S * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate /* 77c478bd9Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * Openvision retains the copyright to derivative works of 107c478bd9Sstevel@tonic-gate * this source code. Do *NOT* create a derivative of this 117c478bd9Sstevel@tonic-gate * source code before consulting with your legal department. 127c478bd9Sstevel@tonic-gate * Do *NOT* integrate *ANY* of this source code into another 137c478bd9Sstevel@tonic-gate * product before consulting with your legal department. 147c478bd9Sstevel@tonic-gate * 157c478bd9Sstevel@tonic-gate * For further information, read the top-level Openvision 167c478bd9Sstevel@tonic-gate * copyright which is contained in the top-level MIT Kerberos 177c478bd9Sstevel@tonic-gate * copyright. 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 207c478bd9Sstevel@tonic-gate * 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate 237c478bd9Sstevel@tonic-gate 247c478bd9Sstevel@tonic-gate /* 257c478bd9Sstevel@tonic-gate * admin/create/kdb5_create.c 267c478bd9Sstevel@tonic-gate * 277c478bd9Sstevel@tonic-gate * Copyright 1990,1991 by the Massachusetts Institute of Technology. 287c478bd9Sstevel@tonic-gate * All Rights Reserved. 297c478bd9Sstevel@tonic-gate * 307c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may 317c478bd9Sstevel@tonic-gate * require a specific license from the United States Government. 327c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 337c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting. 347c478bd9Sstevel@tonic-gate * 357c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 367c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 377c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 387c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 397c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 407c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 417c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 427c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 437c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a 447c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 457c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 467c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 477c478bd9Sstevel@tonic-gate * or implied warranty. 487c478bd9Sstevel@tonic-gate * 497c478bd9Sstevel@tonic-gate * 507c478bd9Sstevel@tonic-gate * Generate (from scratch) a Kerberos KDC database. 517c478bd9Sstevel@tonic-gate */ 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate /* 547c478bd9Sstevel@tonic-gate * Yes, I know this is a hack, but we need admin.h without including the 557c478bd9Sstevel@tonic-gate * rpc.h header. Additionally, our rpc.h header brings in 567c478bd9Sstevel@tonic-gate * a des.h header which causes other problems. 577c478bd9Sstevel@tonic-gate */ 587c478bd9Sstevel@tonic-gate #define _RPC_RPC_H 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate #include <stdio.h> 617c478bd9Sstevel@tonic-gate #include <k5-int.h> 6254925bf6Swillf #include <krb5/kdb.h> 6354925bf6Swillf #include <kadm5/server_internal.h> 647c478bd9Sstevel@tonic-gate #include <kadm5/admin.h> 657c478bd9Sstevel@tonic-gate #include <rpc/types.h> 667c478bd9Sstevel@tonic-gate #include <rpc/xdr.h> 677c478bd9Sstevel@tonic-gate #include <libintl.h> 687c478bd9Sstevel@tonic-gate #include "kdb5_util.h" 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate enum ap_op { 717c478bd9Sstevel@tonic-gate NULL_KEY, /* setup null keys */ 727c478bd9Sstevel@tonic-gate MASTER_KEY, /* use master key as new key */ 737c478bd9Sstevel@tonic-gate TGT_KEY /* special handling for tgt key */ 747c478bd9Sstevel@tonic-gate }; 757c478bd9Sstevel@tonic-gate 7656a424ccSmp153739 krb5_key_salt_tuple def_kslist = { ENCTYPE_DES_CBC_CRC, KRB5_KDB_SALTTYPE_NORMAL }; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate struct realm_info { 797c478bd9Sstevel@tonic-gate krb5_deltat max_life; 807c478bd9Sstevel@tonic-gate krb5_deltat max_rlife; 817c478bd9Sstevel@tonic-gate krb5_timestamp expiration; 827c478bd9Sstevel@tonic-gate krb5_flags flags; 837c478bd9Sstevel@tonic-gate krb5_keyblock *key; 847c478bd9Sstevel@tonic-gate krb5_int32 nkslist; 857c478bd9Sstevel@tonic-gate krb5_key_salt_tuple *kslist; 867c478bd9Sstevel@tonic-gate } rblock = { /* XXX */ 877c478bd9Sstevel@tonic-gate KRB5_KDB_MAX_LIFE, 887c478bd9Sstevel@tonic-gate KRB5_KDB_MAX_RLIFE, 897c478bd9Sstevel@tonic-gate KRB5_KDB_EXPIRATION, 907c478bd9Sstevel@tonic-gate KRB5_KDB_DEF_FLAGS, 917c478bd9Sstevel@tonic-gate (krb5_keyblock *) NULL, 927c478bd9Sstevel@tonic-gate 1, 937c478bd9Sstevel@tonic-gate &def_kslist 947c478bd9Sstevel@tonic-gate }; 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate struct iterate_args { 977c478bd9Sstevel@tonic-gate krb5_context ctx; 987c478bd9Sstevel@tonic-gate struct realm_info *rblock; 997c478bd9Sstevel@tonic-gate krb5_db_entry *dbentp; 1007c478bd9Sstevel@tonic-gate }; 1017c478bd9Sstevel@tonic-gate 10256a424ccSmp153739 static krb5_error_code add_principal 10356a424ccSmp153739 (krb5_context, 1047c478bd9Sstevel@tonic-gate krb5_principal, 1057c478bd9Sstevel@tonic-gate enum ap_op, 1067c478bd9Sstevel@tonic-gate struct realm_info *, 1077c478bd9Sstevel@tonic-gate krb5_keyblock *); 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate /* 1107c478bd9Sstevel@tonic-gate * Steps in creating a database: 1117c478bd9Sstevel@tonic-gate * 1127c478bd9Sstevel@tonic-gate * 1) use the db calls to open/create a new database 1137c478bd9Sstevel@tonic-gate * 1147c478bd9Sstevel@tonic-gate * 2) get a realm name for the new db 1157c478bd9Sstevel@tonic-gate * 1167c478bd9Sstevel@tonic-gate * 3) get a master password for the new db; convert to an encryption key. 1177c478bd9Sstevel@tonic-gate * 1187c478bd9Sstevel@tonic-gate * 4) create various required entries in the database 1197c478bd9Sstevel@tonic-gate * 1207c478bd9Sstevel@tonic-gate * 5) close & exit 1217c478bd9Sstevel@tonic-gate */ 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate extern krb5_principal master_princ; 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate krb5_data tgt_princ_entries[] = { 1267c478bd9Sstevel@tonic-gate {0, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME}, 1277c478bd9Sstevel@tonic-gate {0, 0, 0} }; 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate krb5_data db_creator_entries[] = { 1307c478bd9Sstevel@tonic-gate {0, sizeof("db_creation")-1, "db_creation"} }; 1317c478bd9Sstevel@tonic-gate 13256a424ccSmp153739 /* XXX knows about contents of krb5_principal, and that tgt names 13356a424ccSmp153739 are of form TGT/REALM@REALM */ 1347c478bd9Sstevel@tonic-gate krb5_principal_data tgt_princ = { 1357c478bd9Sstevel@tonic-gate 0, /* magic number */ 1367c478bd9Sstevel@tonic-gate {0, 0, 0}, /* krb5_data realm */ 1377c478bd9Sstevel@tonic-gate tgt_princ_entries, /* krb5_data *data */ 1387c478bd9Sstevel@tonic-gate 2, /* int length */ 1397c478bd9Sstevel@tonic-gate KRB5_NT_SRV_INST /* int type */ 1407c478bd9Sstevel@tonic-gate }; 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate krb5_principal_data db_create_princ = { 1437c478bd9Sstevel@tonic-gate 0, /* magic number */ 1447c478bd9Sstevel@tonic-gate {0, 0, 0}, /* krb5_data realm */ 1457c478bd9Sstevel@tonic-gate db_creator_entries, /* krb5_data *data */ 1467c478bd9Sstevel@tonic-gate 1, /* int length */ 1477c478bd9Sstevel@tonic-gate KRB5_NT_SRV_INST /* int type */ 1487c478bd9Sstevel@tonic-gate }; 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate extern char *mkey_password; 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate extern char *progname; 1537c478bd9Sstevel@tonic-gate extern int exit_status; 1547c478bd9Sstevel@tonic-gate extern kadm5_config_params global_params; 1557c478bd9Sstevel@tonic-gate extern krb5_context util_context; 1567c478bd9Sstevel@tonic-gate 15756a424ccSmp153739 void kdb5_create(argc, argv) 1587c478bd9Sstevel@tonic-gate int argc; 1597c478bd9Sstevel@tonic-gate char *argv[]; 1607c478bd9Sstevel@tonic-gate { 1617c478bd9Sstevel@tonic-gate int optchar; 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate krb5_error_code retval; 1647c478bd9Sstevel@tonic-gate char *mkey_fullname; 1657c478bd9Sstevel@tonic-gate char *pw_str = 0; 1667c478bd9Sstevel@tonic-gate unsigned int pw_size = 0; 1677c478bd9Sstevel@tonic-gate int do_stash = 0; 1687c478bd9Sstevel@tonic-gate krb5_data pwd, seed; 1697c478bd9Sstevel@tonic-gate kdb_log_context *log_ctx; 1707c478bd9Sstevel@tonic-gate krb5_keyblock mkey; 1717c478bd9Sstevel@tonic-gate krb5_data master_salt = { 0, NULL }; 1727c478bd9Sstevel@tonic-gate 173*dd9ccd46S /* Solaris Kerberos */ 174*dd9ccd46S (void) memset(&mkey, 0, sizeof (mkey)); 175*dd9ccd46S 176*dd9ccd46S /* Solaris Kerberos */ 177*dd9ccd46S #if 0 1787c478bd9Sstevel@tonic-gate if (strrchr(argv[0], '/')) 1797c478bd9Sstevel@tonic-gate argv[0] = strrchr(argv[0], '/')+1; 180*dd9ccd46S #endif 1817c478bd9Sstevel@tonic-gate while ((optchar = getopt(argc, argv, "s")) != -1) { 1827c478bd9Sstevel@tonic-gate switch(optchar) { 1837c478bd9Sstevel@tonic-gate case 's': 1847c478bd9Sstevel@tonic-gate do_stash++; 1857c478bd9Sstevel@tonic-gate break; 1867c478bd9Sstevel@tonic-gate case 'h': 18754925bf6Swillf if (!add_db_arg("hash=true")) { 18854925bf6Swillf com_err(progname, ENOMEM, "while parsing command arguments\n"); 18954925bf6Swillf exit(1); 19054925bf6Swillf } 19154925bf6Swillf break; 1927c478bd9Sstevel@tonic-gate case '?': 1937c478bd9Sstevel@tonic-gate default: 1947c478bd9Sstevel@tonic-gate usage(); 1957c478bd9Sstevel@tonic-gate return; 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate rblock.max_life = global_params.max_life; 2007c478bd9Sstevel@tonic-gate rblock.max_rlife = global_params.max_rlife; 2017c478bd9Sstevel@tonic-gate rblock.expiration = global_params.expiration; 2027c478bd9Sstevel@tonic-gate rblock.flags = global_params.flags; 2037c478bd9Sstevel@tonic-gate rblock.nkslist = global_params.num_keysalts; 2047c478bd9Sstevel@tonic-gate rblock.kslist = global_params.keysalts; 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate log_ctx = util_context->kdblog_context; 2077c478bd9Sstevel@tonic-gate 20856a424ccSmp153739 /* SUNW14resync XXX */ 20956a424ccSmp153739 #if 0 21056a424ccSmp153739 printf ("Loading random data\n"); 21156a424ccSmp153739 retval = krb5_c_random_os_entropy (util_context, 1, NULL); 21256a424ccSmp153739 if (retval) { 213*dd9ccd46S /* Solaris Kerberos */ 214*dd9ccd46S com_err (progname, retval, "Loading random data"); 21556a424ccSmp153739 exit_status++; return; 21656a424ccSmp153739 } 21756a424ccSmp153739 #endif 2187c478bd9Sstevel@tonic-gate /* assemble & parse the master key name */ 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate if ((retval = krb5_db_setup_mkey_name(util_context, 2217c478bd9Sstevel@tonic-gate global_params.mkey_name, 2227c478bd9Sstevel@tonic-gate global_params.realm, 2237c478bd9Sstevel@tonic-gate &mkey_fullname, &master_princ))) { 224*dd9ccd46S /* Solaris Kerberos */ 225*dd9ccd46S com_err(progname, retval, 2267c478bd9Sstevel@tonic-gate gettext("while setting up master key name")); 22756a424ccSmp153739 exit_status++; return; 2287c478bd9Sstevel@tonic-gate } 22956a424ccSmp153739 23056a424ccSmp153739 krb5_princ_set_realm_data(util_context, &db_create_princ, global_params.realm); 23156a424ccSmp153739 krb5_princ_set_realm_length(util_context, &db_create_princ, strlen(global_params.realm)); 23256a424ccSmp153739 krb5_princ_set_realm_data(util_context, &tgt_princ, global_params.realm); 23356a424ccSmp153739 krb5_princ_set_realm_length(util_context, &tgt_princ, strlen(global_params.realm)); 23456a424ccSmp153739 krb5_princ_component(util_context, &tgt_princ,1)->data = global_params.realm; 23556a424ccSmp153739 krb5_princ_component(util_context, &tgt_princ,1)->length = strlen(global_params.realm); 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate printf(gettext("Initializing database '%s' for realm '%s',\n" 2387c478bd9Sstevel@tonic-gate "master key name '%s'\n"), 2397c478bd9Sstevel@tonic-gate global_params.dbname, global_params.realm, mkey_fullname); 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate if (!mkey_password) { 2427c478bd9Sstevel@tonic-gate printf(gettext("You will be prompted for the " 2437c478bd9Sstevel@tonic-gate "database Master Password.\n")); 2447c478bd9Sstevel@tonic-gate printf(gettext("It is important that you NOT FORGET this password.\n")); 2457c478bd9Sstevel@tonic-gate fflush(stdout); 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate pw_size = 1024; 2487c478bd9Sstevel@tonic-gate pw_str = malloc(pw_size); 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate retval = krb5_read_password(util_context, 251e49962a0Ssemery gettext("Enter KDC database master key"), 2527c478bd9Sstevel@tonic-gate gettext("Re-enter KDC database " 253e49962a0Ssemery "master key to verify"), 2547c478bd9Sstevel@tonic-gate pw_str, &pw_size); 2557c478bd9Sstevel@tonic-gate if (retval) { 256*dd9ccd46S /* Solaris Kerberos */ 257*dd9ccd46S com_err(progname, retval, 2587c478bd9Sstevel@tonic-gate gettext("while reading master key from keyboard")); 25956a424ccSmp153739 exit_status++; return; 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate mkey_password = pw_str; 2627c478bd9Sstevel@tonic-gate } 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate pwd.data = mkey_password; 2657c478bd9Sstevel@tonic-gate pwd.length = strlen(mkey_password); 2667c478bd9Sstevel@tonic-gate retval = krb5_principal2salt(util_context, master_princ, &master_salt); 2677c478bd9Sstevel@tonic-gate if (retval) { 268*dd9ccd46S /* Solaris Kerberos */ 269*dd9ccd46S com_err(progname, retval, 2707c478bd9Sstevel@tonic-gate gettext("while calculated master key salt")); 2717c478bd9Sstevel@tonic-gate exit_status++; 2727c478bd9Sstevel@tonic-gate goto cleanup; 2737c478bd9Sstevel@tonic-gate } 2747c478bd9Sstevel@tonic-gate 27556a424ccSmp153739 retval = krb5_c_string_to_key(util_context, global_params.enctype, 27656a424ccSmp153739 &pwd, &master_salt, &mkey); 27756a424ccSmp153739 if (retval) { 278*dd9ccd46S /* Solaris Kerberos */ 279*dd9ccd46S com_err(progname, retval, 2807c478bd9Sstevel@tonic-gate gettext("while transforming master key from password")); 2817c478bd9Sstevel@tonic-gate exit_status++; 2827c478bd9Sstevel@tonic-gate goto cleanup; 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate retval = krb5_copy_keyblock(util_context, &mkey, &rblock.key); 2867c478bd9Sstevel@tonic-gate if (retval) { 287*dd9ccd46S /* Solaris Kerberos */ 288*dd9ccd46S com_err(progname, retval, gettext("while copying master key")); 2897c478bd9Sstevel@tonic-gate exit_status++; 2907c478bd9Sstevel@tonic-gate goto cleanup; 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate seed.length = mkey.length; 2947c478bd9Sstevel@tonic-gate seed.data = (char *)mkey.contents; 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate if ((retval = krb5_c_random_seed(util_context, &seed))) { 297*dd9ccd46S /* Solaris Kerberos */ 298*dd9ccd46S com_err(progname, retval, 2997c478bd9Sstevel@tonic-gate gettext("while initializing random key generator")); 3007c478bd9Sstevel@tonic-gate exit_status++; 3017c478bd9Sstevel@tonic-gate goto cleanup; 3027c478bd9Sstevel@tonic-gate } 30354925bf6Swillf if ((retval = krb5_db_create(util_context, db5util_db_args))) { 304*dd9ccd46S /* Solaris Kerberos */ 305*dd9ccd46S com_err(progname, retval, 3067c478bd9Sstevel@tonic-gate gettext("while creating database '%s'"), 3077c478bd9Sstevel@tonic-gate global_params.dbname); 3087c478bd9Sstevel@tonic-gate exit_status++; 3097c478bd9Sstevel@tonic-gate goto cleanup; 3107c478bd9Sstevel@tonic-gate } 31154925bf6Swillf #if 0 /************** Begin IFDEF'ed OUT *******************************/ 3127c478bd9Sstevel@tonic-gate if (retval = krb5_db_fini(util_context)) { 313*dd9ccd46S /* Solaris Kerberos */ 314*dd9ccd46S com_err(progname, retval, 3157c478bd9Sstevel@tonic-gate gettext("while closing current database")); 3167c478bd9Sstevel@tonic-gate exit_status++; 3177c478bd9Sstevel@tonic-gate goto cleanup; 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate if ((retval = krb5_db_set_name(util_context, global_params.dbname))) { 320*dd9ccd46S /* Solaris Kerberos */ 321*dd9ccd46S com_err(progname, retval, 3227c478bd9Sstevel@tonic-gate gettext("while setting active database to '%s'"), 3237c478bd9Sstevel@tonic-gate global_params.dbname); 3247c478bd9Sstevel@tonic-gate exit_status++; 3257c478bd9Sstevel@tonic-gate goto cleanup; 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate if ((retval = krb5_db_init(util_context))) { 328*dd9ccd46S com_err(progname, retval, 3297c478bd9Sstevel@tonic-gate gettext("while initializing the database '%s'"), 3307c478bd9Sstevel@tonic-gate global_params.dbname); 3317c478bd9Sstevel@tonic-gate exit_status++; 3327c478bd9Sstevel@tonic-gate goto cleanup; 3337c478bd9Sstevel@tonic-gate } 33454925bf6Swillf #endif /**************** END IFDEF'ed OUT *******************************/ 3357c478bd9Sstevel@tonic-gate 33654925bf6Swillf /* Solaris Kerberos: for iprop */ 3377c478bd9Sstevel@tonic-gate if (log_ctx && log_ctx->iproprole) { 3387c478bd9Sstevel@tonic-gate if (retval = ulog_map(util_context, &global_params, FKCOMMAND)) { 339*dd9ccd46S /* Solaris Kerberos */ 340*dd9ccd46S com_err(progname, retval, 3417c478bd9Sstevel@tonic-gate gettext("while creating update log")); 3427c478bd9Sstevel@tonic-gate exit_status++; 3437c478bd9Sstevel@tonic-gate goto cleanup; 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate /* 3477c478bd9Sstevel@tonic-gate * We're reinitializing the update log in case one already 3487c478bd9Sstevel@tonic-gate * existed, but this should never happen. 3497c478bd9Sstevel@tonic-gate */ 3507c478bd9Sstevel@tonic-gate (void) memset(log_ctx->ulog, 0, sizeof (kdb_hlog_t)); 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate log_ctx->ulog->kdb_hmagic = KDB_HMAGIC; 3537c478bd9Sstevel@tonic-gate log_ctx->ulog->db_version_num = KDB_VERSION; 3547c478bd9Sstevel@tonic-gate log_ctx->ulog->kdb_state = KDB_STABLE; 3557c478bd9Sstevel@tonic-gate log_ctx->ulog->kdb_block = ULOG_BLOCK; 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate /* 3587c478bd9Sstevel@tonic-gate * Since we're creating a new db we shouldn't worry about 3597c478bd9Sstevel@tonic-gate * adding the initial principals since any slave might as well 3607c478bd9Sstevel@tonic-gate * do full resyncs from this newly created db. 3617c478bd9Sstevel@tonic-gate */ 3627c478bd9Sstevel@tonic-gate log_ctx->iproprole = IPROP_NULL; 3637c478bd9Sstevel@tonic-gate } 3647c478bd9Sstevel@tonic-gate 36554925bf6Swillf if ((retval = add_principal(util_context, master_princ, MASTER_KEY, &rblock, &mkey)) || 36654925bf6Swillf (retval = add_principal(util_context, &tgt_princ, TGT_KEY, &rblock, &mkey))) { 3677c478bd9Sstevel@tonic-gate (void) krb5_db_fini(util_context); 368*dd9ccd46S /* Solaris Kerberos */ 369*dd9ccd46S com_err(progname, retval, gettext("while adding entries to the database")); 3707c478bd9Sstevel@tonic-gate exit_status++; 3717c478bd9Sstevel@tonic-gate goto cleanup; 3727c478bd9Sstevel@tonic-gate } 3737c478bd9Sstevel@tonic-gate /* 3747c478bd9Sstevel@tonic-gate * Always stash the master key so kadm5_create does not prompt for 3757c478bd9Sstevel@tonic-gate * it; delete the file below if it was not requested. DO NOT EXIT 3767c478bd9Sstevel@tonic-gate * BEFORE DELETING THE KEYFILE if do_stash is not set. 3777c478bd9Sstevel@tonic-gate */ 37854925bf6Swillf retval = krb5_db_store_master_key(util_context, 3797c478bd9Sstevel@tonic-gate global_params.stash_file, 3807c478bd9Sstevel@tonic-gate master_princ, 38154925bf6Swillf &mkey, 38254925bf6Swillf mkey_password); 38354925bf6Swillf 38456a424ccSmp153739 if (retval) { 385*dd9ccd46S /* Solaris Kerberos */ 386*dd9ccd46S com_err(progname, errno, gettext("while storing key")); 3877c478bd9Sstevel@tonic-gate printf(gettext("Warning: couldn't stash master key.\n")); 3887c478bd9Sstevel@tonic-gate } 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate if (pw_str) 3917c478bd9Sstevel@tonic-gate memset(pw_str, 0, pw_size); 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate if (kadm5_create(&global_params)) { 39456a424ccSmp153739 if (!do_stash) unlink(global_params.stash_file); 3957c478bd9Sstevel@tonic-gate exit_status++; 3967c478bd9Sstevel@tonic-gate goto cleanup; 3977c478bd9Sstevel@tonic-gate } 39856a424ccSmp153739 if (!do_stash) unlink(global_params.stash_file); 3997c478bd9Sstevel@tonic-gate 40054925bf6Swillf /* Solaris Kerberos: deal with master_keyblock in better way */ 4017c478bd9Sstevel@tonic-gate cleanup: 4027c478bd9Sstevel@tonic-gate if (pw_str) { 4037c478bd9Sstevel@tonic-gate if (mkey_password == pw_str) 4047c478bd9Sstevel@tonic-gate mkey_password = NULL; 4057c478bd9Sstevel@tonic-gate free(pw_str); 4067c478bd9Sstevel@tonic-gate } 4077c478bd9Sstevel@tonic-gate if (master_salt.data) 4087c478bd9Sstevel@tonic-gate free(master_salt.data); 4093441f6a1Ssemery krb5_free_keyblock(util_context, rblock.key); 4107c478bd9Sstevel@tonic-gate krb5_free_keyblock_contents(util_context, &mkey); 4117c478bd9Sstevel@tonic-gate (void) krb5_db_fini(util_context); 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate return; 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate static krb5_error_code 4177c478bd9Sstevel@tonic-gate tgt_keysalt_iterate(ksent, ptr) 4187c478bd9Sstevel@tonic-gate krb5_key_salt_tuple *ksent; 4197c478bd9Sstevel@tonic-gate krb5_pointer ptr; 4207c478bd9Sstevel@tonic-gate { 4217c478bd9Sstevel@tonic-gate krb5_context context; 4227c478bd9Sstevel@tonic-gate krb5_error_code kret; 4237c478bd9Sstevel@tonic-gate struct iterate_args *iargs; 4247c478bd9Sstevel@tonic-gate krb5_keyblock key; 4257c478bd9Sstevel@tonic-gate krb5_int32 ind; 4267c478bd9Sstevel@tonic-gate krb5_data pwd; 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate iargs = (struct iterate_args *) ptr; 4297c478bd9Sstevel@tonic-gate kret = 0; 4307c478bd9Sstevel@tonic-gate 4317c478bd9Sstevel@tonic-gate context = iargs->ctx; 4327c478bd9Sstevel@tonic-gate 4337c478bd9Sstevel@tonic-gate /* 4347c478bd9Sstevel@tonic-gate * Convert the master key password into a key for this particular 4357c478bd9Sstevel@tonic-gate * encryption system. 4367c478bd9Sstevel@tonic-gate */ 4377c478bd9Sstevel@tonic-gate pwd.data = mkey_password; 4387c478bd9Sstevel@tonic-gate pwd.length = strlen(mkey_password); 43956a424ccSmp153739 kret = krb5_c_random_seed(context, &pwd); 44056a424ccSmp153739 if (kret) 4417c478bd9Sstevel@tonic-gate return kret; 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate if (!(kret = krb5_dbe_create_key_data(iargs->ctx, iargs->dbentp))) { 4447c478bd9Sstevel@tonic-gate ind = iargs->dbentp->n_key_data-1; 4457c478bd9Sstevel@tonic-gate if (!(kret = krb5_c_make_random_key(context, ksent->ks_enctype, 4467c478bd9Sstevel@tonic-gate &key))) { 4477c478bd9Sstevel@tonic-gate kret = krb5_dbekd_encrypt_key_data(context, 4487c478bd9Sstevel@tonic-gate iargs->rblock->key, 4497c478bd9Sstevel@tonic-gate &key, 4507c478bd9Sstevel@tonic-gate NULL, 4517c478bd9Sstevel@tonic-gate 1, 4527c478bd9Sstevel@tonic-gate &iargs->dbentp->key_data[ind]); 4537c478bd9Sstevel@tonic-gate krb5_free_keyblock_contents(context, &key); 4547c478bd9Sstevel@tonic-gate } 4557c478bd9Sstevel@tonic-gate } 4567c478bd9Sstevel@tonic-gate 4577c478bd9Sstevel@tonic-gate return(kret); 4587c478bd9Sstevel@tonic-gate } 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate static krb5_error_code 46156a424ccSmp153739 add_principal(context, princ, op, pblock, mkey) 46256a424ccSmp153739 krb5_context context; 46356a424ccSmp153739 krb5_principal princ; 46456a424ccSmp153739 enum ap_op op; 46556a424ccSmp153739 struct realm_info *pblock; 46656a424ccSmp153739 krb5_keyblock *mkey; 4677c478bd9Sstevel@tonic-gate { 4687c478bd9Sstevel@tonic-gate krb5_error_code retval; 4697c478bd9Sstevel@tonic-gate krb5_db_entry entry; 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate krb5_timestamp now; 4727c478bd9Sstevel@tonic-gate struct iterate_args iargs; 4737c478bd9Sstevel@tonic-gate 4747c478bd9Sstevel@tonic-gate int nentries = 1; 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate memset((char *) &entry, 0, sizeof(entry)); 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate entry.len = KRB5_KDB_V1_BASE_LENGTH; 4797c478bd9Sstevel@tonic-gate entry.attributes = pblock->flags; 4807c478bd9Sstevel@tonic-gate entry.max_life = pblock->max_life; 4817c478bd9Sstevel@tonic-gate entry.max_renewable_life = pblock->max_rlife; 4827c478bd9Sstevel@tonic-gate entry.expiration = pblock->expiration; 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate if ((retval = krb5_copy_principal(context, princ, &entry.princ))) 4857c478bd9Sstevel@tonic-gate goto error_out; 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate if ((retval = krb5_timeofday(context, &now))) 4887c478bd9Sstevel@tonic-gate goto error_out; 4897c478bd9Sstevel@tonic-gate 4907c478bd9Sstevel@tonic-gate if ((retval = krb5_dbe_update_mod_princ_data(context, &entry, 4917c478bd9Sstevel@tonic-gate now, &db_create_princ))) 4927c478bd9Sstevel@tonic-gate goto error_out; 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate switch (op) { 4957c478bd9Sstevel@tonic-gate case MASTER_KEY: 49656a424ccSmp153739 if ((entry.key_data=(krb5_key_data*)malloc(sizeof(krb5_key_data))) 49756a424ccSmp153739 == NULL) 4987c478bd9Sstevel@tonic-gate goto error_out; 4997c478bd9Sstevel@tonic-gate memset((char *) entry.key_data, 0, sizeof(krb5_key_data)); 5007c478bd9Sstevel@tonic-gate entry.n_key_data = 1; 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate entry.attributes |= KRB5_KDB_DISALLOW_ALL_TIX; 5037c478bd9Sstevel@tonic-gate if ((retval = krb5_dbekd_encrypt_key_data(context, pblock->key, 50456a424ccSmp153739 mkey, NULL, 50556a424ccSmp153739 1, entry.key_data))) 5067c478bd9Sstevel@tonic-gate goto error_out; 5077c478bd9Sstevel@tonic-gate break; 5087c478bd9Sstevel@tonic-gate case TGT_KEY: 5097c478bd9Sstevel@tonic-gate iargs.ctx = context; 5107c478bd9Sstevel@tonic-gate iargs.rblock = pblock; 5117c478bd9Sstevel@tonic-gate iargs.dbentp = &entry; 5127c478bd9Sstevel@tonic-gate /* 5137c478bd9Sstevel@tonic-gate * Iterate through the key/salt list, ignoring salt types. 5147c478bd9Sstevel@tonic-gate */ 5157c478bd9Sstevel@tonic-gate if ((retval = krb5_keysalt_iterate(pblock->kslist, 5167c478bd9Sstevel@tonic-gate pblock->nkslist, 5177c478bd9Sstevel@tonic-gate 1, 5187c478bd9Sstevel@tonic-gate tgt_keysalt_iterate, 5197c478bd9Sstevel@tonic-gate (krb5_pointer) &iargs))) 52056a424ccSmp153739 return retval; 5217c478bd9Sstevel@tonic-gate break; 5227c478bd9Sstevel@tonic-gate case NULL_KEY: 52356a424ccSmp153739 return EOPNOTSUPP; 5247c478bd9Sstevel@tonic-gate default: 5257c478bd9Sstevel@tonic-gate break; 5267c478bd9Sstevel@tonic-gate } 5277c478bd9Sstevel@tonic-gate 52854925bf6Swillf entry.mask = (KADM5_KEY_DATA | KADM5_PRINCIPAL | KADM5_ATTRIBUTES | 52954925bf6Swillf KADM5_MAX_LIFE | KADM5_MAX_RLIFE | KADM5_TL_DATA | 53054925bf6Swillf KADM5_PRINC_EXPIRE_TIME); 53154925bf6Swillf 5327c478bd9Sstevel@tonic-gate retval = krb5_db_put_principal(context, &entry, &nentries); 5337c478bd9Sstevel@tonic-gate 5347c478bd9Sstevel@tonic-gate error_out:; 53554925bf6Swillf krb5_db_free_principal(context, &entry, 1); 53656a424ccSmp153739 return retval; 5377c478bd9Sstevel@tonic-gate } 538