17c478bd9Sstevel@tonic-gate /*
2dd9ccd46S  * 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.
34*55fea89dSDan Cross  *
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.
48*55fea89dSDan Cross  *
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 
7656a424ccSmp 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 
102*55fea89dSDan Cross static krb5_error_code add_principal
10356a424ccSmp 	(krb5_context,
10456a424ccSmp 	 krb5_principal,
10556a424ccSmp 	 enum ap_op,
10656a424ccSmp 	 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 
13256a424ccSmp /* XXX knows about contents of krb5_principal, and that tgt names
13356a424ccSmp  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 
kdb5_create(argc,argv)15756a424ccSmp 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;
171b89e8170SToomas Soome     krb5_data master_salt = { 0 };
172*55fea89dSDan Cross 
173dd9ccd46S     /* Solaris Kerberos */
174dd9ccd46S     (void) memset(&mkey, 0, sizeof (mkey));
175dd9ccd46S 
176*55fea89dSDan Cross /* Solaris Kerberos */
177*55fea89dSDan Cross #if 0
1787c478bd9Sstevel@tonic-gate     if (strrchr(argv[0], '/'))
1797c478bd9Sstevel@tonic-gate 	argv[0] = strrchr(argv[0], '/')+1;
180dd9ccd46S #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 
20856a424ccSmp /* SUNW14resync XXX */
20956a424ccSmp #if 0
21056a424ccSmp     printf ("Loading random data\n");
21156a424ccSmp     retval = krb5_c_random_os_entropy (util_context, 1, NULL);
21256a424ccSmp     if (retval) {
213dd9ccd46S       /* Solaris Kerberos */
214dd9ccd46S       com_err (progname, retval, "Loading random data");
21556a424ccSmp       exit_status++; return;
21656a424ccSmp     }
217*55fea89dSDan Cross #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,
222*55fea89dSDan Cross 					  global_params.realm,
2237c478bd9Sstevel@tonic-gate 					  &mkey_fullname, &master_princ))) {
224dd9ccd46S 	/* Solaris Kerberos */
225dd9ccd46S 	com_err(progname, retval,
2267c478bd9Sstevel@tonic-gate 			gettext("while setting up master key name"));
22756a424ccSmp 	exit_status++; return;
2287c478bd9Sstevel@tonic-gate     }
22956a424ccSmp 
23056a424ccSmp     krb5_princ_set_realm_data(util_context, &db_create_princ, global_params.realm);
23156a424ccSmp     krb5_princ_set_realm_length(util_context, &db_create_princ, strlen(global_params.realm));
23256a424ccSmp     krb5_princ_set_realm_data(util_context, &tgt_princ, global_params.realm);
23356a424ccSmp     krb5_princ_set_realm_length(util_context, &tgt_princ, strlen(global_params.realm));
23456a424ccSmp     krb5_princ_component(util_context, &tgt_princ,1)->data = global_params.realm;
23556a424ccSmp     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);
249*55fea89dSDan Cross 
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) {
256dd9ccd46S 	    /* Solaris Kerberos */
257dd9ccd46S 	    com_err(progname, retval,
2587c478bd9Sstevel@tonic-gate 		    gettext("while reading master key from keyboard"));
25956a424ccSmp 	    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) {
268dd9ccd46S 	/* Solaris Kerberos */
269dd9ccd46S 	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 
27556a424ccSmp     retval = krb5_c_string_to_key(util_context, global_params.enctype,
27656a424ccSmp 				  &pwd, &master_salt, &mkey);
27756a424ccSmp     if (retval) {
278dd9ccd46S 	/* Solaris Kerberos */
279dd9ccd46S 	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) {
287dd9ccd46S 	/* Solaris Kerberos */
288dd9ccd46S 	com_err(progname, retval, gettext("while copying master key"));
289*55fea89dSDan Cross 	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))) {
297dd9ccd46S 	/* Solaris Kerberos */
298*55fea89dSDan Cross 	com_err(progname, retval,
2997c478bd9Sstevel@tonic-gate 		gettext("while initializing random key generator"));
300*55fea89dSDan Cross 	exit_status++;
3017c478bd9Sstevel@tonic-gate 	goto cleanup;
3027c478bd9Sstevel@tonic-gate     }
30354925bf6Swillf     if ((retval = krb5_db_create(util_context, db5util_db_args))) {
304dd9ccd46S 	/* Solaris Kerberos */
305*55fea89dSDan Cross 	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)) {
313dd9ccd46S 	/* Solaris Kerberos */
314dd9ccd46S 	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))) {
320dd9ccd46S 	/* Solaris Kerberos */
321dd9ccd46S 	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))) {
328dd9ccd46S 	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     }
334*55fea89dSDan Cross #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)) {
339dd9ccd46S 		/* Solaris Kerberos */
340dd9ccd46S 		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 
352*55fea89dSDan Cross 	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);
368dd9ccd46S 	/* Solaris Kerberos */
369dd9ccd46S 	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,
37954925bf6Swillf 				      global_params.stash_file,
38054925bf6Swillf 				      master_princ,
38154925bf6Swillf 				      &mkey,
38254925bf6Swillf 				      mkey_password);
38354925bf6Swillf 
38456a424ccSmp     if (retval) {
385dd9ccd46S 	/* Solaris Kerberos */
386dd9ccd46S 	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)) {
39456a424ccSmp 	 if (!do_stash) unlink(global_params.stash_file);
39556a424ccSmp 	 exit_status++;
39656a424ccSmp 	 goto cleanup;
3977c478bd9Sstevel@tonic-gate     }
39856a424ccSmp     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
tgt_keysalt_iterate(ksent,ptr)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);
43956a424ccSmp     kret = krb5_c_random_seed(context, &pwd);
44056a424ccSmp     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,
449*55fea89dSDan Cross 					       &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
add_principal(context,princ,op,pblock,mkey)46156a424ccSmp add_principal(context, princ, op, pblock, mkey)
46256a424ccSmp     krb5_context context;
46356a424ccSmp     krb5_principal princ;
46456a424ccSmp     enum ap_op op;
46556a424ccSmp     struct realm_info *pblock;
46656a424ccSmp     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:
49656a424ccSmp 	if ((entry.key_data=(krb5_key_data*)malloc(sizeof(krb5_key_data)))
49756a424ccSmp 	    == 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,
50456a424ccSmp 						  mkey, NULL,
50556a424ccSmp 						  1, entry.key_data)))
50656a424ccSmp 	    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)))
52056a424ccSmp 	    return retval;
5217c478bd9Sstevel@tonic-gate 	break;
5227c478bd9Sstevel@tonic-gate     case NULL_KEY:
52356a424ccSmp 	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);
53656a424ccSmp     return retval;
5377c478bd9Sstevel@tonic-gate }
538