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