xref: /onnv-gate/usr/src/cmd/krb5/kadmin/dbutil/dump.c (revision 7934:6aeeafc994de)
10Sstevel@tonic-gate /*
25916Swillf  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate 
70Sstevel@tonic-gate /*
80Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
90Sstevel@tonic-gate  *
100Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
110Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
120Sstevel@tonic-gate  *	source code before consulting with your legal department.
130Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
140Sstevel@tonic-gate  *	product before consulting with your legal department.
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  *	For further information, read the top-level Openvision
170Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
180Sstevel@tonic-gate  *	copyright.
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
210Sstevel@tonic-gate  *
220Sstevel@tonic-gate  */
230Sstevel@tonic-gate 
240Sstevel@tonic-gate 
250Sstevel@tonic-gate /*
260Sstevel@tonic-gate  * admin/edit/dump.c
270Sstevel@tonic-gate  *
280Sstevel@tonic-gate  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
290Sstevel@tonic-gate  * All Rights Reserved.
300Sstevel@tonic-gate  *
310Sstevel@tonic-gate  * Export of this software from the United States of America may
320Sstevel@tonic-gate  *   require a specific license from the United States Government.
330Sstevel@tonic-gate  *   It is the responsibility of any person or organization contemplating
340Sstevel@tonic-gate  *   export to obtain such a license before exporting.
350Sstevel@tonic-gate  *
360Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
370Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
380Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
390Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
400Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
410Sstevel@tonic-gate  * the name of M.I.T. not be used in advertising or publicity pertaining
420Sstevel@tonic-gate  * to distribution of the software without specific, written prior
430Sstevel@tonic-gate  * permission.  Furthermore if you modify this software you must label
440Sstevel@tonic-gate  * your software as modified software and not distribute it in such a
450Sstevel@tonic-gate  * fashion that it might be confused with the original M.I.T. software.
460Sstevel@tonic-gate  * M.I.T. makes no representations about the suitability of
470Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
480Sstevel@tonic-gate  * or implied warranty.
490Sstevel@tonic-gate  *
500Sstevel@tonic-gate  *
510Sstevel@tonic-gate  * Dump a KDC database
520Sstevel@tonic-gate  */
530Sstevel@tonic-gate 
544960Swillf #include <stdio.h>
550Sstevel@tonic-gate #include <k5-int.h>
564960Swillf #include <kadm5/admin.h>
574960Swillf #include <kadm5/server_internal.h>
584960Swillf #include <kdb.h>
590Sstevel@tonic-gate #include <com_err.h>
600Sstevel@tonic-gate #include <libintl.h>
610Sstevel@tonic-gate #include "kdb5_util.h"
622881Smp153739 #if defined(HAVE_REGEX_H) && defined(HAVE_REGCOMP)
630Sstevel@tonic-gate #include <regex.h>
640Sstevel@tonic-gate #endif	/* HAVE_REGEX_H */
650Sstevel@tonic-gate 
660Sstevel@tonic-gate /*
670Sstevel@tonic-gate  * Needed for master key conversion.
680Sstevel@tonic-gate  */
690Sstevel@tonic-gate extern krb5_keyblock master_key;
700Sstevel@tonic-gate extern krb5_principal master_princ;
710Sstevel@tonic-gate static int			mkey_convert;
720Sstevel@tonic-gate static krb5_keyblock		new_master_key;
730Sstevel@tonic-gate 
742881Smp153739 static int	backwards;
752881Smp153739 static int	recursive;
762881Smp153739 
770Sstevel@tonic-gate /*
780Sstevel@tonic-gate  * Use compile(3) if no regcomp present.
790Sstevel@tonic-gate  */
800Sstevel@tonic-gate #if	!defined(HAVE_REGCOMP) && defined(HAVE_REGEXP_H)
810Sstevel@tonic-gate #define	INIT		char *sp = instring;
820Sstevel@tonic-gate #define	GETC()		(*sp++)
830Sstevel@tonic-gate #define	PEEKC()		(*sp)
840Sstevel@tonic-gate #define	UNGETC(c)	(--sp)
850Sstevel@tonic-gate #define	RETURN(c)	return(c)
860Sstevel@tonic-gate #define	ERROR(c)
870Sstevel@tonic-gate #define	RE_BUF_SIZE	1024
880Sstevel@tonic-gate #include <regexp.h>
890Sstevel@tonic-gate #endif	/* !HAVE_REGCOMP && HAVE_REGEXP_H */
900Sstevel@tonic-gate 
910Sstevel@tonic-gate struct dump_args {
920Sstevel@tonic-gate     char		*programname;
930Sstevel@tonic-gate     FILE		*ofile;
940Sstevel@tonic-gate     krb5_context	kcontext;
950Sstevel@tonic-gate     char		**names;
960Sstevel@tonic-gate     int			nnames;
970Sstevel@tonic-gate     int			verbose;
980Sstevel@tonic-gate };
990Sstevel@tonic-gate 
1002881Smp153739 static krb5_error_code dump_k5beta_iterator (krb5_pointer,
1012881Smp153739 					     krb5_db_entry *);
1022881Smp153739 static krb5_error_code dump_k5beta6_iterator (krb5_pointer,
1032881Smp153739 					      krb5_db_entry *);
1042881Smp153739 static krb5_error_code dump_k5beta6_iterator_ext (krb5_pointer,
1052881Smp153739 						  krb5_db_entry *,
1062881Smp153739 						  int);
1072881Smp153739 static krb5_error_code dump_iprop_iterator (krb5_pointer,
1082881Smp153739 						  krb5_db_entry *);
1092881Smp153739 static krb5_error_code dump_k5beta7_princ (krb5_pointer,
1102881Smp153739 					   krb5_db_entry *);
1112881Smp153739 static krb5_error_code dump_k5beta7_princ_ext (krb5_pointer,
1122881Smp153739 					       krb5_db_entry *,
1132881Smp153739 					       int);
1142881Smp153739 static krb5_error_code dump_k5beta7_princ_withpolicy
1152881Smp153739 			(krb5_pointer, krb5_db_entry *);
1162881Smp153739 static krb5_error_code dump_iprop_princ (krb5_pointer,
1172881Smp153739 					       krb5_db_entry *);
1182881Smp153739 static krb5_error_code dump_ov_princ (krb5_pointer,
1192881Smp153739 				      krb5_db_entry *);
120781Sgtb static void dump_k5beta7_policy (void *, osa_policy_ent_t);
1210Sstevel@tonic-gate 
1222881Smp153739 typedef krb5_error_code (*dump_func)(krb5_pointer,
1232881Smp153739 				     krb5_db_entry *);
1240Sstevel@tonic-gate 
1252881Smp153739 static int process_k5beta_record (char *, krb5_context,
1264960Swillf 				  FILE *, int, int *);
1272881Smp153739 static int process_k5beta6_record (char *, krb5_context,
1284960Swillf 				   FILE *, int, int *);
1292881Smp153739 static int process_k5beta7_record (char *, krb5_context,
1304960Swillf 				   FILE *, int, int *);
1312881Smp153739 static int process_ov_record (char *, krb5_context,
1324960Swillf 			      FILE *, int, int *);
1332881Smp153739 typedef krb5_error_code (*load_func)(char *, krb5_context,
1344960Swillf 				     FILE *, int, int *);
1350Sstevel@tonic-gate 
1360Sstevel@tonic-gate typedef struct _dump_version {
1370Sstevel@tonic-gate      char *name;
1380Sstevel@tonic-gate      char *header;
1390Sstevel@tonic-gate      int updateonly;
1400Sstevel@tonic-gate      int create_kadm5;
1410Sstevel@tonic-gate      dump_func dump_princ;
1420Sstevel@tonic-gate      osa_adb_iter_policy_func dump_policy;
1430Sstevel@tonic-gate      load_func load_record;
1440Sstevel@tonic-gate } dump_version;
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate dump_version old_version = {
1470Sstevel@tonic-gate      "Kerberos version 5 old format",
1480Sstevel@tonic-gate      "kdb5_edit load_dump version 2.0\n",
1490Sstevel@tonic-gate      0,
1500Sstevel@tonic-gate      1,
1510Sstevel@tonic-gate      dump_k5beta_iterator,
1520Sstevel@tonic-gate      NULL,
1534960Swillf      process_k5beta_record
1540Sstevel@tonic-gate };
1550Sstevel@tonic-gate dump_version beta6_version = {
1560Sstevel@tonic-gate      "Kerberos version 5 beta 6 format",
1570Sstevel@tonic-gate      "kdb5_edit load_dump version 3.0\n",
1580Sstevel@tonic-gate      0,
1590Sstevel@tonic-gate      1,
1600Sstevel@tonic-gate      dump_k5beta6_iterator,
1610Sstevel@tonic-gate      NULL,
1624960Swillf      process_k5beta6_record
1630Sstevel@tonic-gate };
1640Sstevel@tonic-gate dump_version beta7_version = {
1650Sstevel@tonic-gate      "Kerberos version 5",
1660Sstevel@tonic-gate      "kdb5_util load_dump version 4\n",
1670Sstevel@tonic-gate      0,
1680Sstevel@tonic-gate      0,
1690Sstevel@tonic-gate      dump_k5beta7_princ,
1700Sstevel@tonic-gate      dump_k5beta7_policy,
1714960Swillf      process_k5beta7_record
1720Sstevel@tonic-gate };
1730Sstevel@tonic-gate dump_version iprop_version = {
1740Sstevel@tonic-gate      "Kerberos iprop version",
1750Sstevel@tonic-gate      "iprop",
1760Sstevel@tonic-gate      0,
1770Sstevel@tonic-gate      0,
1780Sstevel@tonic-gate      dump_iprop_princ,
1790Sstevel@tonic-gate      dump_k5beta7_policy,
1804960Swillf      process_k5beta7_record
1810Sstevel@tonic-gate };
1820Sstevel@tonic-gate dump_version ov_version = {
1830Sstevel@tonic-gate      "OpenV*Secure V1.0",
1840Sstevel@tonic-gate      "OpenV*Secure V1.0\t",
1850Sstevel@tonic-gate      1,
1860Sstevel@tonic-gate      1,
1870Sstevel@tonic-gate      dump_ov_princ,
1880Sstevel@tonic-gate      dump_k5beta7_policy,
1894960Swillf      process_ov_record
1900Sstevel@tonic-gate };
1910Sstevel@tonic-gate 
1922881Smp153739 dump_version r1_3_version = {
1932881Smp153739      "Kerberos version 5 release 1.3",
1942881Smp153739      "kdb5_util load_dump version 5\n",
1952881Smp153739      0,
1962881Smp153739      0,
1972881Smp153739      dump_k5beta7_princ_withpolicy,
1982881Smp153739      dump_k5beta7_policy,
1992881Smp153739      process_k5beta7_record,
2002881Smp153739 };
2012881Smp153739 
2020Sstevel@tonic-gate /* External data */
2030Sstevel@tonic-gate extern char		*current_dbname;
2040Sstevel@tonic-gate extern krb5_boolean	dbactive;
2050Sstevel@tonic-gate extern int		exit_status;
2060Sstevel@tonic-gate extern krb5_context	util_context;
2070Sstevel@tonic-gate extern kadm5_config_params global_params;
2080Sstevel@tonic-gate 
2090Sstevel@tonic-gate /* Strings */
2100Sstevel@tonic-gate 
2112881Smp153739 #define k5beta_dump_header	"kdb5_edit load_dump version 2.0\n"
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate static const char null_mprinc_name[] = "kdb5_dump@MISSING";
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate /*
2160Sstevel@tonic-gate  * We define gettext(s) to be s here, so that xgettext will extract the
2170Sstevel@tonic-gate  * strings to the .po file. At the end of the message section we will
2180Sstevel@tonic-gate  * undef gettext so that we can use it as a funtion.
2190Sstevel@tonic-gate  */
2200Sstevel@tonic-gate 
2210Sstevel@tonic-gate #define	gettext(s) s
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate /* Message strings */
2240Sstevel@tonic-gate static const char regex_err[] =
2250Sstevel@tonic-gate 	gettext("%s: regular expression error - %s\n");
2260Sstevel@tonic-gate static const char regex_merr[] =
2270Sstevel@tonic-gate 	gettext("%s: regular expression match error - %s\n");
2280Sstevel@tonic-gate static const char pname_unp_err[] =
2290Sstevel@tonic-gate 	gettext("%s: cannot unparse principal name (%s)\n");
2300Sstevel@tonic-gate static const char mname_unp_err[] =
2310Sstevel@tonic-gate 	gettext("%s: cannot unparse modifier name (%s)\n");
2320Sstevel@tonic-gate static const char nokeys_err[] =
2330Sstevel@tonic-gate 	gettext("%s: cannot find any standard key for %s\n");
2340Sstevel@tonic-gate static const char sdump_tl_inc_err[] =
2350Sstevel@tonic-gate 	gettext("%s: tagged data list inconsistency for %s "
2360Sstevel@tonic-gate 		"(counted %d, stored %d)\n");
2370Sstevel@tonic-gate static const char stand_fmt_name[] =
2380Sstevel@tonic-gate 	gettext("Kerberos version 5");
2390Sstevel@tonic-gate static const char old_fmt_name[] =
2400Sstevel@tonic-gate 	gettext("Kerberos version 5 old format");
2410Sstevel@tonic-gate static const char b6_fmt_name[] =
2420Sstevel@tonic-gate 	gettext("Kerberos version 5 beta 6 format");
2430Sstevel@tonic-gate static const char ofopen_error[] =
2440Sstevel@tonic-gate 	gettext("%s: cannot open %s for writing (%s)\n");
2450Sstevel@tonic-gate static const char oflock_error[] =
2460Sstevel@tonic-gate 	gettext("%s: cannot lock %s (%s)\n");
2470Sstevel@tonic-gate static const char dumprec_err[] =
2480Sstevel@tonic-gate 	gettext("%s: error performing %s dump (%s)\n");
2490Sstevel@tonic-gate static const char dumphdr_err[] =
2500Sstevel@tonic-gate 	gettext("%s: error dumping %s header (%s)\n");
2510Sstevel@tonic-gate static const char trash_end_fmt[] =
2520Sstevel@tonic-gate 	gettext("%s(%d): ignoring trash at end of line: ");
2530Sstevel@tonic-gate static const char read_name_string[] =
2540Sstevel@tonic-gate 	gettext("name string");
2550Sstevel@tonic-gate static const char read_key_type[] =
2560Sstevel@tonic-gate 	gettext("key type");
2570Sstevel@tonic-gate static const char read_key_data[] =
2580Sstevel@tonic-gate 	gettext("key data");
2590Sstevel@tonic-gate static const char read_pr_data1[] =
2600Sstevel@tonic-gate 	gettext("first set of principal attributes");
2610Sstevel@tonic-gate static const char read_mod_name[] =
2620Sstevel@tonic-gate 	gettext("modifier name");
2630Sstevel@tonic-gate static const char read_pr_data2[] =
2640Sstevel@tonic-gate 	gettext("second set of principal attributes");
2650Sstevel@tonic-gate static const char read_salt_data[] =
2660Sstevel@tonic-gate 	gettext("salt data");
2670Sstevel@tonic-gate static const char read_akey_type[] =
2680Sstevel@tonic-gate 	gettext("alternate key type");
2690Sstevel@tonic-gate static const char read_akey_data[] =
2700Sstevel@tonic-gate 	gettext("alternate key data");
2710Sstevel@tonic-gate static const char read_asalt_type[] =
2720Sstevel@tonic-gate 	gettext("alternate salt type");
2730Sstevel@tonic-gate static const char read_asalt_data[] =
2740Sstevel@tonic-gate 	gettext("alternate salt data");
2750Sstevel@tonic-gate static const char read_exp_data[] =
2760Sstevel@tonic-gate 	gettext("expansion data");
2770Sstevel@tonic-gate static const char store_err_fmt[] =
2780Sstevel@tonic-gate 	gettext("%s(%d): cannot store %s(%s)\n");
2790Sstevel@tonic-gate static const char add_princ_fmt[] =
2800Sstevel@tonic-gate 	gettext("%s\n");
2810Sstevel@tonic-gate static const char parse_err_fmt[] =
2820Sstevel@tonic-gate 	gettext("%s(%d): cannot parse %s (%s)\n");
2830Sstevel@tonic-gate static const char read_err_fmt[] =
2840Sstevel@tonic-gate 	gettext("%s(%d): cannot read %s\n");
2850Sstevel@tonic-gate static const char no_mem_fmt[] =
2860Sstevel@tonic-gate 	gettext("%s(%d): no memory for buffers\n");
2870Sstevel@tonic-gate static const char rhead_err_fmt[] =
2880Sstevel@tonic-gate 	gettext("%s(%d): cannot match size tokens\n");
2890Sstevel@tonic-gate static const char err_line_fmt[] =
2900Sstevel@tonic-gate 	gettext("%s: error processing line %d of %s\n");
2910Sstevel@tonic-gate static const char head_bad_fmt[] =
2920Sstevel@tonic-gate 	gettext("%s: dump header bad in %s\n");
2930Sstevel@tonic-gate static const char read_bytecnt[] =
2940Sstevel@tonic-gate 	gettext("record byte count");
2950Sstevel@tonic-gate static const char read_encdata[] =
2960Sstevel@tonic-gate 	gettext("encoded data");
2970Sstevel@tonic-gate static const char n_name_unp_fmt[] =
2980Sstevel@tonic-gate 	gettext("%s(%s): cannot unparse name\n");
2990Sstevel@tonic-gate static const char n_dec_cont_fmt[] =
3000Sstevel@tonic-gate 	gettext("%s(%s): cannot decode contents\n");
3010Sstevel@tonic-gate static const char read_nint_data[] =
3020Sstevel@tonic-gate 	gettext("principal static attributes");
3030Sstevel@tonic-gate static const char read_tcontents[] =
3040Sstevel@tonic-gate 	gettext("tagged data contents");
3050Sstevel@tonic-gate static const char read_ttypelen[] =
3060Sstevel@tonic-gate 	gettext("tagged data type and length");
3070Sstevel@tonic-gate static const char read_kcontents[] =
3080Sstevel@tonic-gate 	gettext("key data contents");
3090Sstevel@tonic-gate static const char read_ktypelen[] =
3100Sstevel@tonic-gate 	gettext("key data type and length");
3110Sstevel@tonic-gate static const char read_econtents[] =
3120Sstevel@tonic-gate 	gettext("extra data contents");
3130Sstevel@tonic-gate static const char k5beta_fmt_name[] =
3140Sstevel@tonic-gate 	gettext("Kerberos version 5 old format");
3150Sstevel@tonic-gate static const char standard_fmt_name[] =
3160Sstevel@tonic-gate 	gettext("Kerberos version 5 format");
3170Sstevel@tonic-gate static const char no_name_mem_fmt[] =
3180Sstevel@tonic-gate 	gettext("%s: cannot get memory for temporary name\n");
3190Sstevel@tonic-gate static const char ctx_err_fmt[] =
3200Sstevel@tonic-gate 	gettext("%s: cannot initialize Kerberos context\n");
3210Sstevel@tonic-gate static const char stdin_name[] =
3220Sstevel@tonic-gate 	gettext("standard input");
3230Sstevel@tonic-gate static const char remaster_err_fmt[] =
3240Sstevel@tonic-gate 	gettext("while re-encoding keys for principal %s with new master key");
3250Sstevel@tonic-gate static const char restfail_fmt[] =
3260Sstevel@tonic-gate 	gettext("%s: %s restore failed\n");
3270Sstevel@tonic-gate static const char close_err_fmt[] =
3280Sstevel@tonic-gate 	gettext("%s: cannot close database (%s)\n");
3290Sstevel@tonic-gate static const char dbinit_err_fmt[] =
3300Sstevel@tonic-gate 	gettext("%s: cannot initialize database (%s)\n");
3310Sstevel@tonic-gate static const char dblock_err_fmt[] =
3320Sstevel@tonic-gate 	gettext("%s: cannot initialize database lock (%s)\n");
3330Sstevel@tonic-gate static const char dbname_err_fmt[] =
3340Sstevel@tonic-gate 	gettext("%s: cannot set database name to %s (%s)\n");
3350Sstevel@tonic-gate static const char dbdelerr_fmt[] =
3360Sstevel@tonic-gate 	gettext("%s: cannot delete bad database %s (%s)\n");
3370Sstevel@tonic-gate static const char dbunlockerr_fmt[] =
3380Sstevel@tonic-gate 	gettext("%s: cannot unlock database %s (%s)\n");
3390Sstevel@tonic-gate static const char dbrenerr_fmt[] =
3400Sstevel@tonic-gate 	gettext("%s: cannot rename database %s to %s (%s)\n");
3410Sstevel@tonic-gate static const char dbcreaterr_fmt[] =
3420Sstevel@tonic-gate 	gettext("%s: cannot create database %s (%s)\n");
3430Sstevel@tonic-gate static const char dfile_err_fmt[] =
3440Sstevel@tonic-gate 	gettext("%s: cannot open %s (%s)\n");
3450Sstevel@tonic-gate 
3460Sstevel@tonic-gate /*
3470Sstevel@tonic-gate  * We now return you to your regularly scheduled program.
3480Sstevel@tonic-gate  */
3490Sstevel@tonic-gate #undef gettext
3500Sstevel@tonic-gate 
3510Sstevel@tonic-gate static const char oldoption[] = "-old";
3520Sstevel@tonic-gate static const char b6option[] = "-b6";
3532881Smp153739 static const char b7option[] = "-b7";
3540Sstevel@tonic-gate static const char ipropoption[] = "-i";
3550Sstevel@tonic-gate static const char verboseoption[] = "-verbose";
3560Sstevel@tonic-gate static const char updateoption[] = "-update";
3570Sstevel@tonic-gate static const char hashoption[] = "-hash";
3580Sstevel@tonic-gate static const char ovoption[] = "-ov";
3590Sstevel@tonic-gate static const char dump_tmptrail[] = "~";
3600Sstevel@tonic-gate 
3610Sstevel@tonic-gate /*
3620Sstevel@tonic-gate  * Re-encrypt the key_data with the new master key...
3630Sstevel@tonic-gate  */
3642881Smp153739 static krb5_error_code master_key_convert(context, db_entry)
3650Sstevel@tonic-gate     krb5_context	  context;
3660Sstevel@tonic-gate     krb5_db_entry	* db_entry;
3670Sstevel@tonic-gate {
3680Sstevel@tonic-gate     krb5_error_code	retval;
3690Sstevel@tonic-gate     krb5_keyblock 	v5plainkey, *key_ptr;
3700Sstevel@tonic-gate     krb5_keysalt 	keysalt;
3712881Smp153739     int	      i, j;
3720Sstevel@tonic-gate     krb5_key_data	new_key_data, *key_data;
3730Sstevel@tonic-gate     krb5_boolean	is_mkey;
3740Sstevel@tonic-gate 
3750Sstevel@tonic-gate     is_mkey = krb5_principal_compare(context, master_princ, db_entry->princ);
3760Sstevel@tonic-gate 
3770Sstevel@tonic-gate     if (is_mkey && db_entry->n_key_data != 1)
3780Sstevel@tonic-gate 	    fprintf(stderr,
3790Sstevel@tonic-gate 		    gettext(
3800Sstevel@tonic-gate 		      "Master key db entry has %d keys, expecting only 1!\n"),
3810Sstevel@tonic-gate 		    db_entry->n_key_data);
3820Sstevel@tonic-gate     for (i=0; i < db_entry->n_key_data; i++) {
3830Sstevel@tonic-gate 	key_data = &db_entry->key_data[i];
3840Sstevel@tonic-gate 	if (key_data->key_data_length == 0)
3850Sstevel@tonic-gate 	    continue;
3860Sstevel@tonic-gate 	retval = krb5_dbekd_decrypt_key_data(context, &master_key,
3870Sstevel@tonic-gate 					     key_data, &v5plainkey,
3880Sstevel@tonic-gate 					     &keysalt);
3890Sstevel@tonic-gate 	if (retval)
3900Sstevel@tonic-gate 		return retval;
3910Sstevel@tonic-gate 
3920Sstevel@tonic-gate 	memset(&new_key_data, 0, sizeof(new_key_data));
3930Sstevel@tonic-gate 	key_ptr = is_mkey ? &new_master_key : &v5plainkey;
3940Sstevel@tonic-gate 	retval = krb5_dbekd_encrypt_key_data(context, &new_master_key,
3950Sstevel@tonic-gate 					     key_ptr, &keysalt,
3960Sstevel@tonic-gate 					     key_data->key_data_kvno,
3970Sstevel@tonic-gate 					     &new_key_data);
3980Sstevel@tonic-gate 	if (retval)
3990Sstevel@tonic-gate 		return retval;
4000Sstevel@tonic-gate 	krb5_free_keyblock_contents(context, &v5plainkey);
4012881Smp153739 	for (j = 0; j < key_data->key_data_ver; j++) {
4022881Smp153739 	    if (key_data->key_data_length[j]) {
4032881Smp153739 		free(key_data->key_data_contents[j]);
4042881Smp153739 	    }
4052881Smp153739 	}
4060Sstevel@tonic-gate 	*key_data = new_key_data;
4070Sstevel@tonic-gate     }
4080Sstevel@tonic-gate     return 0;
4090Sstevel@tonic-gate }
4100Sstevel@tonic-gate 
4110Sstevel@tonic-gate /*
4120Sstevel@tonic-gate  * Update the "ok" file.
4130Sstevel@tonic-gate  */
4142881Smp153739 void update_ok_file (file_name)
4150Sstevel@tonic-gate      char *file_name;
4160Sstevel@tonic-gate {
4170Sstevel@tonic-gate 	/* handle slave locking/failure stuff */
4180Sstevel@tonic-gate 	char *file_ok;
4190Sstevel@tonic-gate 	int fd;
4200Sstevel@tonic-gate 	static char ok[]=".dump_ok";
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate 	if ((file_ok = (char *)malloc(strlen(file_name) + strlen(ok) + 1))
4230Sstevel@tonic-gate 	    == NULL) {
4240Sstevel@tonic-gate 		com_err(progname, ENOMEM,
4250Sstevel@tonic-gate 		    gettext("while allocating filename "
4260Sstevel@tonic-gate 			"for update_ok_file"));
4270Sstevel@tonic-gate 		exit_status++;
4280Sstevel@tonic-gate 		return;
4290Sstevel@tonic-gate 	}
4300Sstevel@tonic-gate 	strcpy(file_ok, file_name);
4310Sstevel@tonic-gate 	strcat(file_ok, ok);
4320Sstevel@tonic-gate 	if ((fd = open(file_ok, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) {
4330Sstevel@tonic-gate 		com_err(progname, errno,
4340Sstevel@tonic-gate 		    gettext("while creating 'ok' file, '%s'"),
4350Sstevel@tonic-gate 			file_ok);
4360Sstevel@tonic-gate 		exit_status++;
4370Sstevel@tonic-gate 		free(file_ok);
4380Sstevel@tonic-gate 		return;
4390Sstevel@tonic-gate 	}
4400Sstevel@tonic-gate 	if (write(fd, "", 1) != 1) {
4410Sstevel@tonic-gate 		com_err(progname, errno,
4420Sstevel@tonic-gate 		    gettext("while writing to 'ok' file, '%s'"),
4430Sstevel@tonic-gate 		    file_ok);
4440Sstevel@tonic-gate 	     exit_status++;
4450Sstevel@tonic-gate 	     free(file_ok);
4460Sstevel@tonic-gate 	     return;
4470Sstevel@tonic-gate 	}
4482881Smp153739 
4490Sstevel@tonic-gate 	free(file_ok);
4500Sstevel@tonic-gate 	close(fd);
4512881Smp153739 	return;
4520Sstevel@tonic-gate }
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate /*
4550Sstevel@tonic-gate  * name_matches()	- See if a principal name matches a regular expression
4560Sstevel@tonic-gate  *			  or string.
4570Sstevel@tonic-gate  */
4580Sstevel@tonic-gate static int
4590Sstevel@tonic-gate name_matches(name, arglist)
4600Sstevel@tonic-gate     char		*name;
4610Sstevel@tonic-gate     struct dump_args	*arglist;
4620Sstevel@tonic-gate {
4630Sstevel@tonic-gate #if	HAVE_REGCOMP
4640Sstevel@tonic-gate     regex_t	match_exp;
4650Sstevel@tonic-gate     regmatch_t	match_match;
4660Sstevel@tonic-gate     int		match_error;
4670Sstevel@tonic-gate     char	match_errmsg[BUFSIZ];
4680Sstevel@tonic-gate     size_t	errmsg_size;
4690Sstevel@tonic-gate #elif	HAVE_REGEXP_H
4700Sstevel@tonic-gate     char	regexp_buffer[RE_BUF_SIZE];
4710Sstevel@tonic-gate #elif	HAVE_RE_COMP
4720Sstevel@tonic-gate     extern char	*re_comp();
4730Sstevel@tonic-gate     char	*re_result;
4740Sstevel@tonic-gate #endif	/* HAVE_RE_COMP */
4750Sstevel@tonic-gate     int		i, match;
4760Sstevel@tonic-gate 
4770Sstevel@tonic-gate     /*
4782881Smp153739      * Plow, brute force, through the list of names/regular expressions.
4790Sstevel@tonic-gate      */
4800Sstevel@tonic-gate     match = (arglist->nnames) ? 0 : 1;
4810Sstevel@tonic-gate     for (i=0; i<arglist->nnames; i++) {
4820Sstevel@tonic-gate #if	HAVE_REGCOMP
4830Sstevel@tonic-gate 	/*
4840Sstevel@tonic-gate 	 * Compile the regular expression.
4850Sstevel@tonic-gate 	 */
4862881Smp153739 	match_error = regcomp(&match_exp, arglist->names[i], REG_EXTENDED);
4872881Smp153739 	if (match_error) {
4880Sstevel@tonic-gate 	    errmsg_size = regerror(match_error,
4890Sstevel@tonic-gate 				   &match_exp,
4900Sstevel@tonic-gate 				   match_errmsg,
4910Sstevel@tonic-gate 				   sizeof(match_errmsg));
4920Sstevel@tonic-gate 			fprintf(stderr, gettext(regex_err),
4930Sstevel@tonic-gate 			    arglist->programname, match_errmsg);
4940Sstevel@tonic-gate 	    break;
4950Sstevel@tonic-gate 	}
4960Sstevel@tonic-gate 	/*
4970Sstevel@tonic-gate 	 * See if we have a match.
4980Sstevel@tonic-gate 	 */
4992881Smp153739 	match_error = regexec(&match_exp, name, 1, &match_match, 0);
5002881Smp153739 	if (match_error) {
5010Sstevel@tonic-gate 	    if (match_error != REG_NOMATCH) {
5020Sstevel@tonic-gate 		errmsg_size = regerror(match_error,
5030Sstevel@tonic-gate 				       &match_exp,
5040Sstevel@tonic-gate 				       match_errmsg,
5050Sstevel@tonic-gate 				       sizeof(match_errmsg));
5060Sstevel@tonic-gate 				fprintf(stderr, gettext(regex_merr),
5070Sstevel@tonic-gate 			arglist->programname, match_errmsg);
5080Sstevel@tonic-gate 		break;
5090Sstevel@tonic-gate 	    }
5102881Smp153739 	}
5112881Smp153739 	else {
5120Sstevel@tonic-gate 	    /*
5130Sstevel@tonic-gate 	     * We have a match.  See if it matches the whole
5140Sstevel@tonic-gate 	     * name.
5150Sstevel@tonic-gate 	     */
5160Sstevel@tonic-gate 	    if ((match_match.rm_so == 0) &&
5170Sstevel@tonic-gate 		(match_match.rm_eo == strlen(name)))
5180Sstevel@tonic-gate 		match = 1;
5190Sstevel@tonic-gate 	}
5200Sstevel@tonic-gate 	regfree(&match_exp);
5210Sstevel@tonic-gate #elif	HAVE_REGEXP_H
5220Sstevel@tonic-gate 	/*
5230Sstevel@tonic-gate 	 * Compile the regular expression.
5240Sstevel@tonic-gate 	 */
5250Sstevel@tonic-gate 	compile(arglist->names[i],
5260Sstevel@tonic-gate 		regexp_buffer,
5270Sstevel@tonic-gate 		&regexp_buffer[RE_BUF_SIZE],
5280Sstevel@tonic-gate 		'\0');
5290Sstevel@tonic-gate 	if (step(name, regexp_buffer)) {
5300Sstevel@tonic-gate 	    if ((loc1 == name) &&
5310Sstevel@tonic-gate 		(loc2 == &name[strlen(name)]))
5320Sstevel@tonic-gate 		match = 1;
5330Sstevel@tonic-gate 	}
5340Sstevel@tonic-gate #elif	HAVE_RE_COMP
5350Sstevel@tonic-gate 	/*
5360Sstevel@tonic-gate 	 * Compile the regular expression.
5370Sstevel@tonic-gate 	 */
5380Sstevel@tonic-gate 	if (re_result = re_comp(arglist->names[i])) {
5392881Smp153739 	    fprintf(stderr, gettext(regex_err), arglist->programname, re_result);
5400Sstevel@tonic-gate 	    break;
5410Sstevel@tonic-gate 	}
5420Sstevel@tonic-gate 	if (re_exec(name))
5430Sstevel@tonic-gate 	    match = 1;
5440Sstevel@tonic-gate #else	/* HAVE_RE_COMP */
5450Sstevel@tonic-gate 	/*
5462881Smp153739 	 * If no regular expression support, then just compare the strings.
5470Sstevel@tonic-gate 	 */
5482881Smp153739 	if (!strcmp(arglist->names[i], name))
5490Sstevel@tonic-gate 	    match = 1;
5500Sstevel@tonic-gate #endif	/* HAVE_REGCOMP */
5510Sstevel@tonic-gate 	if (match)
5520Sstevel@tonic-gate 	    break;
5530Sstevel@tonic-gate     }
5540Sstevel@tonic-gate     return(match);
5550Sstevel@tonic-gate }
5560Sstevel@tonic-gate 
5570Sstevel@tonic-gate static krb5_error_code
5580Sstevel@tonic-gate find_enctype(dbentp, enctype, salttype, kentp)
5590Sstevel@tonic-gate     krb5_db_entry	*dbentp;
5600Sstevel@tonic-gate     krb5_enctype	enctype;
5610Sstevel@tonic-gate     krb5_int32		salttype;
5620Sstevel@tonic-gate     krb5_key_data	**kentp;
5630Sstevel@tonic-gate {
5640Sstevel@tonic-gate     int			i;
5650Sstevel@tonic-gate     int			maxkvno;
5660Sstevel@tonic-gate     krb5_key_data	*datap;
5670Sstevel@tonic-gate 
5680Sstevel@tonic-gate     maxkvno = -1;
5690Sstevel@tonic-gate     datap = (krb5_key_data *) NULL;
5700Sstevel@tonic-gate     for (i=0; i<dbentp->n_key_data; i++) {
5710Sstevel@tonic-gate 	if (( (krb5_enctype)dbentp->key_data[i].key_data_type[0] == enctype) &&
5720Sstevel@tonic-gate 	    ((dbentp->key_data[i].key_data_type[1] == salttype) ||
5730Sstevel@tonic-gate 	     (salttype < 0))) {
5740Sstevel@tonic-gate 	    maxkvno = dbentp->key_data[i].key_data_kvno;
5750Sstevel@tonic-gate 	    datap = &dbentp->key_data[i];
5760Sstevel@tonic-gate 	}
5770Sstevel@tonic-gate     }
5780Sstevel@tonic-gate     if (maxkvno >= 0) {
5790Sstevel@tonic-gate 	*kentp = datap;
5800Sstevel@tonic-gate 	return(0);
5810Sstevel@tonic-gate     }
5820Sstevel@tonic-gate     return(ENOENT);
5830Sstevel@tonic-gate }
5840Sstevel@tonic-gate 
5852881Smp153739 #if 0
5860Sstevel@tonic-gate /*
5870Sstevel@tonic-gate  * dump_k5beta_header()	- Make a dump header that is recognizable by Kerberos
5880Sstevel@tonic-gate  *			  Version 5 Beta 5 and previous releases.
5890Sstevel@tonic-gate  */
5900Sstevel@tonic-gate static krb5_error_code
5910Sstevel@tonic-gate dump_k5beta_header(arglist)
5920Sstevel@tonic-gate     struct dump_args *arglist;
5930Sstevel@tonic-gate {
5940Sstevel@tonic-gate     /* The old header consists of the leading string */
5950Sstevel@tonic-gate     fprintf(arglist->ofile, k5beta_dump_header);
5960Sstevel@tonic-gate     return(0);
5970Sstevel@tonic-gate }
5982881Smp153739 #endif
5990Sstevel@tonic-gate 
6000Sstevel@tonic-gate /*
6010Sstevel@tonic-gate  * dump_k5beta_iterator()	- Dump an entry in a format that is usable
6020Sstevel@tonic-gate  *				  by Kerberos Version 5 Beta 5 and previous
6030Sstevel@tonic-gate  *				  releases.
6040Sstevel@tonic-gate  */
6050Sstevel@tonic-gate static krb5_error_code
6060Sstevel@tonic-gate dump_k5beta_iterator(ptr, entry)
6070Sstevel@tonic-gate     krb5_pointer	ptr;
6080Sstevel@tonic-gate     krb5_db_entry	*entry;
6090Sstevel@tonic-gate {
6100Sstevel@tonic-gate     krb5_error_code	retval;
6110Sstevel@tonic-gate     struct dump_args	*arg;
6120Sstevel@tonic-gate     char		*name, *mod_name;
6130Sstevel@tonic-gate     krb5_principal	mod_princ;
6140Sstevel@tonic-gate     krb5_key_data	*pkey, *akey, nullkey;
6150Sstevel@tonic-gate     krb5_timestamp	mod_date, last_pwd_change;
6160Sstevel@tonic-gate     int			i;
6170Sstevel@tonic-gate 
6180Sstevel@tonic-gate     /* Initialize */
6190Sstevel@tonic-gate     arg = (struct dump_args *) ptr;
6200Sstevel@tonic-gate     name = (char *) NULL;
6210Sstevel@tonic-gate     mod_name = (char *) NULL;
6220Sstevel@tonic-gate     memset(&nullkey, 0, sizeof(nullkey));
6230Sstevel@tonic-gate 
6240Sstevel@tonic-gate     /*
6250Sstevel@tonic-gate      * Flatten the principal name.
6260Sstevel@tonic-gate      */
6270Sstevel@tonic-gate     if ((retval = krb5_unparse_name(arg->kcontext,
6280Sstevel@tonic-gate 				    entry->princ,
6290Sstevel@tonic-gate 				    &name))) {
6300Sstevel@tonic-gate 		fprintf(stderr, gettext(pname_unp_err),
6310Sstevel@tonic-gate 		arg->programname, error_message(retval));
6320Sstevel@tonic-gate 	return(retval);
6330Sstevel@tonic-gate     }
6340Sstevel@tonic-gate 
6350Sstevel@tonic-gate     /*
6360Sstevel@tonic-gate      * Re-encode the keys in the new master key, if necessary.
6370Sstevel@tonic-gate      */
6380Sstevel@tonic-gate     if (mkey_convert) {
6390Sstevel@tonic-gate 	retval = master_key_convert(arg->kcontext, entry);
6400Sstevel@tonic-gate 	if (retval) {
6410Sstevel@tonic-gate 	    com_err(arg->programname, retval, remaster_err_fmt, name);
6420Sstevel@tonic-gate 	    return retval;
6430Sstevel@tonic-gate 	}
6440Sstevel@tonic-gate     }
6450Sstevel@tonic-gate 
6460Sstevel@tonic-gate     /*
6470Sstevel@tonic-gate      * If we don't have any match strings, or if our name matches, then
6480Sstevel@tonic-gate      * proceed with the dump, otherwise, just forget about it.
6490Sstevel@tonic-gate      */
6500Sstevel@tonic-gate     if (!arg->nnames || name_matches(name, arg)) {
6510Sstevel@tonic-gate 	/*
6520Sstevel@tonic-gate 	 * Deserialize the modifier record.
6530Sstevel@tonic-gate 	 */
6540Sstevel@tonic-gate 	mod_name = (char *) NULL;
6550Sstevel@tonic-gate 	mod_princ = NULL;
6560Sstevel@tonic-gate 	last_pwd_change = mod_date = 0;
6570Sstevel@tonic-gate 	pkey = akey = (krb5_key_data *) NULL;
6580Sstevel@tonic-gate 	if (!(retval = krb5_dbe_lookup_mod_princ_data(arg->kcontext,
6590Sstevel@tonic-gate 						      entry,
6600Sstevel@tonic-gate 						      &mod_date,
6610Sstevel@tonic-gate 						      &mod_princ))) {
6620Sstevel@tonic-gate 	    if (mod_princ) {
6630Sstevel@tonic-gate 		/*
6640Sstevel@tonic-gate 		 * Flatten the modifier name.
6650Sstevel@tonic-gate 		 */
6660Sstevel@tonic-gate 		if ((retval = krb5_unparse_name(arg->kcontext,
6670Sstevel@tonic-gate 						mod_princ,
6680Sstevel@tonic-gate 						&mod_name)))
6690Sstevel@tonic-gate 					fprintf(stderr, gettext(mname_unp_err),
6700Sstevel@tonic-gate 					    arg->programname,
6710Sstevel@tonic-gate 			    error_message(retval));
6720Sstevel@tonic-gate 		krb5_free_principal(arg->kcontext, mod_princ);
6730Sstevel@tonic-gate 	    }
6740Sstevel@tonic-gate 	}
6750Sstevel@tonic-gate 	if (!mod_name)
6760Sstevel@tonic-gate 	    mod_name = strdup(null_mprinc_name);
6770Sstevel@tonic-gate 
6780Sstevel@tonic-gate 	/*
6792881Smp153739 	 * Find the last password change record and set it straight.
6800Sstevel@tonic-gate 	 */
6810Sstevel@tonic-gate 	if ((retval =
6820Sstevel@tonic-gate 	     krb5_dbe_lookup_last_pwd_change(arg->kcontext, entry,
6832881Smp153739 					     &last_pwd_change))) {
6840Sstevel@tonic-gate 			fprintf(stderr, gettext(nokeys_err),
6850Sstevel@tonic-gate 			    arg->programname, name);
6860Sstevel@tonic-gate 	    krb5_xfree(mod_name);
6870Sstevel@tonic-gate 	    krb5_xfree(name);
6880Sstevel@tonic-gate 	    return(retval);
6890Sstevel@tonic-gate 	}
6900Sstevel@tonic-gate 
6910Sstevel@tonic-gate 	/*
6920Sstevel@tonic-gate 	 * Find the 'primary' key and the 'alternate' key.
6930Sstevel@tonic-gate 	 */
6940Sstevel@tonic-gate 	if ((retval = find_enctype(entry,
6950Sstevel@tonic-gate 				   ENCTYPE_DES_CBC_CRC,
6960Sstevel@tonic-gate 				   KRB5_KDB_SALTTYPE_NORMAL,
6970Sstevel@tonic-gate 				   &pkey)) &&
6980Sstevel@tonic-gate 	    (retval = find_enctype(entry,
6990Sstevel@tonic-gate 				   ENCTYPE_DES_CBC_CRC,
7000Sstevel@tonic-gate 				   KRB5_KDB_SALTTYPE_V4,
7010Sstevel@tonic-gate 				   &akey))) {
7020Sstevel@tonic-gate 			fprintf(stderr, gettext(nokeys_err),
7030Sstevel@tonic-gate 			    arg->programname, name);
7040Sstevel@tonic-gate 	    krb5_xfree(mod_name);
7050Sstevel@tonic-gate 	    krb5_xfree(name);
7060Sstevel@tonic-gate 	    return(retval);
7070Sstevel@tonic-gate 	}
7082881Smp153739 
7092881Smp153739 	/* If we only have one type, then ship it out as the primary. */
7100Sstevel@tonic-gate 	if (!pkey && akey) {
7110Sstevel@tonic-gate 	    pkey = akey;
7120Sstevel@tonic-gate 	    akey = &nullkey;
7132881Smp153739 	}
7142881Smp153739 	else {
7150Sstevel@tonic-gate 	    if (!akey)
7160Sstevel@tonic-gate 		akey = &nullkey;
7170Sstevel@tonic-gate 	}
7180Sstevel@tonic-gate 
7190Sstevel@tonic-gate 	/*
7202881Smp153739 	 * First put out strings representing the length of the variable
7212881Smp153739 	 * length data in this record, then the name and the primary key type.
7220Sstevel@tonic-gate 	 */
7232881Smp153739 	fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%d\t%s\t%d\t", strlen(name),
7240Sstevel@tonic-gate 		strlen(mod_name),
7250Sstevel@tonic-gate 		(krb5_int32) pkey->key_data_length[0],
7260Sstevel@tonic-gate 		(krb5_int32) akey->key_data_length[0],
7270Sstevel@tonic-gate 		(krb5_int32) pkey->key_data_length[1],
7280Sstevel@tonic-gate 		(krb5_int32) akey->key_data_length[1],
7290Sstevel@tonic-gate 		name,
7300Sstevel@tonic-gate 		(krb5_int32) pkey->key_data_type[0]);
7310Sstevel@tonic-gate 	for (i=0; i<pkey->key_data_length[0]; i++) {
7322881Smp153739 	    fprintf(arg->ofile, "%02x", pkey->key_data_contents[0][i]);
7330Sstevel@tonic-gate 	}
7340Sstevel@tonic-gate 	/*
7352881Smp153739 	 * Second, print out strings representing the standard integer
7362881Smp153739 	 * data in this record.
7370Sstevel@tonic-gate 	 */
7380Sstevel@tonic-gate 	fprintf(arg->ofile,
7392881Smp153739 		"\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%s\t%u\t%u\t%u\t",
7400Sstevel@tonic-gate 		(krb5_int32) pkey->key_data_kvno,
7410Sstevel@tonic-gate 		entry->max_life, entry->max_renewable_life,
7422881Smp153739 		1 /* Fake mkvno */, entry->expiration, entry->pw_expiration,
7432881Smp153739 		last_pwd_change, entry->last_success, entry->last_failed,
7440Sstevel@tonic-gate 		entry->fail_auth_count, mod_name, mod_date,
7450Sstevel@tonic-gate 		entry->attributes, pkey->key_data_type[1]);
7460Sstevel@tonic-gate 
7470Sstevel@tonic-gate 	/* Pound out the salt data, if present. */
7480Sstevel@tonic-gate 	for (i=0; i<pkey->key_data_length[1]; i++) {
7492881Smp153739 	    fprintf(arg->ofile, "%02x", pkey->key_data_contents[1][i]);
7500Sstevel@tonic-gate 	}
7510Sstevel@tonic-gate 	/* Pound out the alternate key type and contents */
7520Sstevel@tonic-gate 	fprintf(arg->ofile, "\t%u\t", akey->key_data_type[0]);
7530Sstevel@tonic-gate 	for (i=0; i<akey->key_data_length[0]; i++) {
7542881Smp153739 	    fprintf(arg->ofile, "%02x", akey->key_data_contents[0][i]);
7550Sstevel@tonic-gate 	}
7560Sstevel@tonic-gate 	/* Pound out the alternate salt type and contents */
7570Sstevel@tonic-gate 	fprintf(arg->ofile, "\t%u\t", akey->key_data_type[1]);
7580Sstevel@tonic-gate 	for (i=0; i<akey->key_data_length[1]; i++) {
7592881Smp153739 	    fprintf(arg->ofile, "%02x", akey->key_data_contents[1][i]);
7600Sstevel@tonic-gate 	}
7610Sstevel@tonic-gate 	/* Pound out the expansion data. (is null) */
7620Sstevel@tonic-gate 	for (i=0; i < 8; i++) {
7630Sstevel@tonic-gate 	    fprintf(arg->ofile, "\t%u", 0);
7640Sstevel@tonic-gate 	}
7650Sstevel@tonic-gate 	fprintf(arg->ofile, ";\n");
7660Sstevel@tonic-gate 	/* If we're blabbing, do it */
7670Sstevel@tonic-gate 	if (arg->verbose)
7680Sstevel@tonic-gate 	    fprintf(stderr, "%s\n", name);
7690Sstevel@tonic-gate 	krb5_xfree(mod_name);
7700Sstevel@tonic-gate     }
7710Sstevel@tonic-gate     krb5_xfree(name);
7720Sstevel@tonic-gate     return(0);
7730Sstevel@tonic-gate }
7740Sstevel@tonic-gate 
7750Sstevel@tonic-gate /*
7760Sstevel@tonic-gate  * dump_k5beta6_iterator()	- Output a dump record in krb5b6 format.
7770Sstevel@tonic-gate  */
7780Sstevel@tonic-gate static krb5_error_code
7790Sstevel@tonic-gate dump_k5beta6_iterator(ptr, entry)
7800Sstevel@tonic-gate     krb5_pointer	ptr;
7810Sstevel@tonic-gate     krb5_db_entry	*entry;
7820Sstevel@tonic-gate {
7832881Smp153739     return dump_k5beta6_iterator_ext(ptr, entry, 0);
7842881Smp153739 }
7852881Smp153739 
7862881Smp153739 static krb5_error_code
7872881Smp153739 dump_k5beta6_iterator_ext(ptr, entry, kadm)
7882881Smp153739     krb5_pointer	ptr;
7892881Smp153739     krb5_db_entry	*entry;
7902881Smp153739     int			kadm;
7912881Smp153739 {
7920Sstevel@tonic-gate     krb5_error_code	retval;
7930Sstevel@tonic-gate     struct dump_args	*arg;
7940Sstevel@tonic-gate     char		*name;
7950Sstevel@tonic-gate     krb5_tl_data	*tlp;
7960Sstevel@tonic-gate     krb5_key_data	*kdata;
7970Sstevel@tonic-gate     int			counter, skip, i, j;
7980Sstevel@tonic-gate 
7990Sstevel@tonic-gate     /* Initialize */
8000Sstevel@tonic-gate     arg = (struct dump_args *) ptr;
8010Sstevel@tonic-gate     name = (char *) NULL;
8020Sstevel@tonic-gate 
8030Sstevel@tonic-gate     /*
8040Sstevel@tonic-gate      * Flatten the principal name.
8050Sstevel@tonic-gate      */
8060Sstevel@tonic-gate     if ((retval = krb5_unparse_name(arg->kcontext,
8070Sstevel@tonic-gate 				    entry->princ,
8080Sstevel@tonic-gate 				    &name))) {
8090Sstevel@tonic-gate 		fprintf(stderr, gettext(pname_unp_err),
8100Sstevel@tonic-gate 		arg->programname, error_message(retval));
8110Sstevel@tonic-gate 	return(retval);
8120Sstevel@tonic-gate     }
8130Sstevel@tonic-gate 
8140Sstevel@tonic-gate     /*
8150Sstevel@tonic-gate      * Re-encode the keys in the new master key, if necessary.
8160Sstevel@tonic-gate      */
8170Sstevel@tonic-gate     if (mkey_convert) {
8180Sstevel@tonic-gate 	retval = master_key_convert(arg->kcontext, entry);
8190Sstevel@tonic-gate 	if (retval) {
8200Sstevel@tonic-gate 	    com_err(arg->programname, retval, remaster_err_fmt, name);
8210Sstevel@tonic-gate 	    return retval;
8220Sstevel@tonic-gate 	}
8230Sstevel@tonic-gate     }
8240Sstevel@tonic-gate 
8250Sstevel@tonic-gate     /*
8260Sstevel@tonic-gate      * If we don't have any match strings, or if our name matches, then
8270Sstevel@tonic-gate      * proceed with the dump, otherwise, just forget about it.
8280Sstevel@tonic-gate      */
8290Sstevel@tonic-gate     if (!arg->nnames || name_matches(name, arg)) {
8300Sstevel@tonic-gate 	/*
8312881Smp153739 	 * We'd like to just blast out the contents as they would appear in
8322881Smp153739 	 * the database so that we can just suck it back in, but it doesn't
8332881Smp153739 	 * lend itself to easy editing.
8340Sstevel@tonic-gate 	 */
8350Sstevel@tonic-gate 
8360Sstevel@tonic-gate 	/*
8372881Smp153739 	 * The dump format is as follows:
8382881Smp153739 	 *	len strlen(name) n_tl_data n_key_data e_length
8392881Smp153739 	 *	name
8402881Smp153739 	 *	attributes max_life max_renewable_life expiration
8412881Smp153739 	 *	pw_expiration last_success last_failed fail_auth_count
8422881Smp153739 	 *	n_tl_data*[type length <contents>]
8432881Smp153739 	 *	n_key_data*[ver kvno ver*(type length <contents>)]
8442881Smp153739 	 *	<e_data>
8452881Smp153739 	 * Fields which are not encapsulated by angle-brackets are to appear
8462881Smp153739 	 * verbatim.  A bracketed field's absence is indicated by a -1 in its
8472881Smp153739 	 * place
8480Sstevel@tonic-gate 	 */
8490Sstevel@tonic-gate 
8502881Smp153739 	/*
8510Sstevel@tonic-gate 	 * Make sure that the tagged list is reasonably correct.
8520Sstevel@tonic-gate 	 */
8530Sstevel@tonic-gate 	counter = skip = 0;
8540Sstevel@tonic-gate 	for (tlp = entry->tl_data; tlp; tlp = tlp->tl_data_next) {
8552881Smp153739 	     /*
8562881Smp153739 	      * don't dump tl data types we know aren't understood by
8572881Smp153739 	      * earlier revisions [krb5-admin/89]
8582881Smp153739 	      */
8592881Smp153739 	     switch (tlp->tl_data_type) {
8602881Smp153739 	     case KRB5_TL_KADM_DATA:
8612881Smp153739 		  if (kadm)
8622881Smp153739 		      counter++;
8632881Smp153739 		  else
8642881Smp153739 		      skip++;
8652881Smp153739 		  break;
8662881Smp153739 	     default:
8672881Smp153739 		  counter++;
8682881Smp153739 		  break;
8692881Smp153739 	     }
8700Sstevel@tonic-gate 	}
8710Sstevel@tonic-gate 
8720Sstevel@tonic-gate 	if (counter + skip == entry->n_tl_data) {
8730Sstevel@tonic-gate 	    /* Pound out header */
8740Sstevel@tonic-gate 	    fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%s\t",
8750Sstevel@tonic-gate 		    (int) entry->len,
8760Sstevel@tonic-gate 		    strlen(name),
8770Sstevel@tonic-gate 		    counter,
8780Sstevel@tonic-gate 		    (int) entry->n_key_data,
8790Sstevel@tonic-gate 		    (int) entry->e_length,
8800Sstevel@tonic-gate 		    name);
8810Sstevel@tonic-gate 	    fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t",
8820Sstevel@tonic-gate 		    entry->attributes,
8830Sstevel@tonic-gate 		    entry->max_life,
8840Sstevel@tonic-gate 		    entry->max_renewable_life,
8850Sstevel@tonic-gate 		    entry->expiration,
8860Sstevel@tonic-gate 		    entry->pw_expiration,
8870Sstevel@tonic-gate 		    entry->last_success,
8880Sstevel@tonic-gate 		    entry->last_failed,
8890Sstevel@tonic-gate 		    entry->fail_auth_count);
8900Sstevel@tonic-gate 	    /* Pound out tagged data. */
8912881Smp153739 	    for (tlp = entry->tl_data; tlp; tlp = tlp->tl_data_next) {
8922881Smp153739 		if (tlp->tl_data_type == KRB5_TL_KADM_DATA && !kadm)
8932881Smp153739 		     continue; /* see above, [krb5-admin/89] */
8940Sstevel@tonic-gate 
8950Sstevel@tonic-gate 		fprintf(arg->ofile, "%d\t%d\t",
8960Sstevel@tonic-gate 			(int) tlp->tl_data_type,
8970Sstevel@tonic-gate 			(int) tlp->tl_data_length);
8980Sstevel@tonic-gate 		if (tlp->tl_data_length)
8992881Smp153739 		    for (i=0; i<tlp->tl_data_length; i++)
9002881Smp153739 			fprintf(arg->ofile, "%02x", tlp->tl_data_contents[i]);
9010Sstevel@tonic-gate 		else
9020Sstevel@tonic-gate 		    fprintf(arg->ofile, "%d", -1);
9030Sstevel@tonic-gate 		fprintf(arg->ofile, "\t");
9040Sstevel@tonic-gate 	    }
9050Sstevel@tonic-gate 
9060Sstevel@tonic-gate 	    /* Pound out key data */
9072881Smp153739 	    for (counter=0; counter<entry->n_key_data; counter++) {
9080Sstevel@tonic-gate 		kdata = &entry->key_data[counter];
9090Sstevel@tonic-gate 		fprintf(arg->ofile, "%d\t%d\t",
9100Sstevel@tonic-gate 			(int) kdata->key_data_ver,
9110Sstevel@tonic-gate 			(int) kdata->key_data_kvno);
9120Sstevel@tonic-gate 		for (i=0; i<kdata->key_data_ver; i++) {
9130Sstevel@tonic-gate 		    fprintf(arg->ofile, "%d\t%d\t",
9140Sstevel@tonic-gate 			    kdata->key_data_type[i],
9150Sstevel@tonic-gate 			    kdata->key_data_length[i]);
9160Sstevel@tonic-gate 		    if (kdata->key_data_length[i])
9172881Smp153739 			for (j=0; j<kdata->key_data_length[i]; j++)
9182881Smp153739 			    fprintf(arg->ofile, "%02x",
9192881Smp153739 				    kdata->key_data_contents[i][j]);
9200Sstevel@tonic-gate 		    else
9210Sstevel@tonic-gate 			fprintf(arg->ofile, "%d", -1);
9220Sstevel@tonic-gate 		    fprintf(arg->ofile, "\t");
9230Sstevel@tonic-gate 		}
9240Sstevel@tonic-gate 	    }
9250Sstevel@tonic-gate 
9260Sstevel@tonic-gate 	    /* Pound out extra data */
9270Sstevel@tonic-gate 	    if (entry->e_length)
9280Sstevel@tonic-gate 		for (i=0; i<entry->e_length; i++)
9292881Smp153739 		    fprintf(arg->ofile, "%02x", entry->e_data[i]);
9300Sstevel@tonic-gate 	    else
9310Sstevel@tonic-gate 		fprintf(arg->ofile, "%d", -1);
9320Sstevel@tonic-gate 
9330Sstevel@tonic-gate 	    /* Print trailer */
9340Sstevel@tonic-gate 	    fprintf(arg->ofile, ";\n");
9350Sstevel@tonic-gate 
9360Sstevel@tonic-gate 	    if (arg->verbose)
9370Sstevel@tonic-gate 		fprintf(stderr, "%s\n", name);
9382881Smp153739 	}
9392881Smp153739 	else {
9400Sstevel@tonic-gate 			fprintf(stderr, gettext(sdump_tl_inc_err),
9412881Smp153739 		    arg->programname, name, counter+skip,
9420Sstevel@tonic-gate 		    (int) entry->n_tl_data);
9430Sstevel@tonic-gate 	    retval = EINVAL;
9440Sstevel@tonic-gate 	}
9450Sstevel@tonic-gate     }
9460Sstevel@tonic-gate     krb5_xfree(name);
9470Sstevel@tonic-gate     return(retval);
9480Sstevel@tonic-gate }
9492881Smp153739 
9500Sstevel@tonic-gate /*
9510Sstevel@tonic-gate  * dump_iprop_iterator()	- Output a dump record in iprop format.
9520Sstevel@tonic-gate  */
9530Sstevel@tonic-gate static krb5_error_code
9540Sstevel@tonic-gate dump_iprop_iterator(ptr, entry)
9550Sstevel@tonic-gate     krb5_pointer	ptr;
9560Sstevel@tonic-gate     krb5_db_entry	*entry;
9570Sstevel@tonic-gate {
9580Sstevel@tonic-gate     krb5_error_code	retval;
9590Sstevel@tonic-gate     struct dump_args	*arg;
9600Sstevel@tonic-gate     char		*name;
9610Sstevel@tonic-gate     krb5_tl_data	*tlp;
9620Sstevel@tonic-gate     krb5_key_data	*kdata;
9630Sstevel@tonic-gate     int			counter, i, j;
9640Sstevel@tonic-gate 
9650Sstevel@tonic-gate     /* Initialize */
9660Sstevel@tonic-gate     arg = (struct dump_args *) ptr;
9670Sstevel@tonic-gate     name = (char *) NULL;
9680Sstevel@tonic-gate 
9690Sstevel@tonic-gate     /*
9700Sstevel@tonic-gate      * Flatten the principal name.
9710Sstevel@tonic-gate      */
9720Sstevel@tonic-gate     if ((retval = krb5_unparse_name(arg->kcontext,
9730Sstevel@tonic-gate 				    entry->princ,
9740Sstevel@tonic-gate 				    &name))) {
9750Sstevel@tonic-gate 		fprintf(stderr, gettext(pname_unp_err),
9760Sstevel@tonic-gate 		arg->programname, error_message(retval));
9770Sstevel@tonic-gate 	return(retval);
9780Sstevel@tonic-gate     }
9790Sstevel@tonic-gate 
9800Sstevel@tonic-gate     /*
9810Sstevel@tonic-gate      * Re-encode the keys in the new master key, if necessary.
9820Sstevel@tonic-gate      */
9830Sstevel@tonic-gate     if (mkey_convert) {
9840Sstevel@tonic-gate 	retval = master_key_convert(arg->kcontext, entry);
9850Sstevel@tonic-gate 	if (retval) {
9860Sstevel@tonic-gate 	    com_err(arg->programname, retval, remaster_err_fmt, name);
9870Sstevel@tonic-gate 	    return retval;
9880Sstevel@tonic-gate 	}
9890Sstevel@tonic-gate     }
9900Sstevel@tonic-gate 
9910Sstevel@tonic-gate     /*
9920Sstevel@tonic-gate      * If we don't have any match strings, or if our name matches, then
9930Sstevel@tonic-gate      * proceed with the dump, otherwise, just forget about it.
9940Sstevel@tonic-gate      */
9950Sstevel@tonic-gate     if (!arg->nnames || name_matches(name, arg)) {
9960Sstevel@tonic-gate 	/*
9970Sstevel@tonic-gate 	 * We'd like to just blast out the contents as they would
9980Sstevel@tonic-gate 	 * appear in the database so that we can just suck it back
9990Sstevel@tonic-gate 	 * in, but it doesn't lend itself to easy editing.
10000Sstevel@tonic-gate 	 */
10010Sstevel@tonic-gate 
10020Sstevel@tonic-gate 	/*
10030Sstevel@tonic-gate 	 * The dump format is as follows: len strlen(name)
10040Sstevel@tonic-gate 	 * n_tl_data n_key_data e_length name attributes max_life
10050Sstevel@tonic-gate 	 * max_renewable_life expiration pw_expiration last_success
10060Sstevel@tonic-gate 	 * last_failed fail_auth_count n_tl_data*[type length
10070Sstevel@tonic-gate 	 * <contents>] n_key_data*[ver kvno ver*(type length
10080Sstevel@tonic-gate 	 * <contents>)] <e_data> Fields which are not encapsulated
10090Sstevel@tonic-gate 	 * by angle-brackets are to appear verbatim.  Bracketed
10100Sstevel@tonic-gate 	 * fields absence is indicated by a -1 in its place
10110Sstevel@tonic-gate 	 */
10120Sstevel@tonic-gate 
10130Sstevel@tonic-gate 	/*
10140Sstevel@tonic-gate 	 * Make sure that the tagged list is reasonably correct.
10150Sstevel@tonic-gate 	 */
10160Sstevel@tonic-gate 	counter = 0;
10170Sstevel@tonic-gate 	for (tlp = entry->tl_data; tlp; tlp = tlp->tl_data_next)
10180Sstevel@tonic-gate 		  counter++;
10190Sstevel@tonic-gate 
10200Sstevel@tonic-gate 	if (counter == entry->n_tl_data) {
10210Sstevel@tonic-gate 	    /* Pound out header */
10220Sstevel@tonic-gate 	    fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%s\t",
10230Sstevel@tonic-gate 		    (int) entry->len,
10240Sstevel@tonic-gate 		    strlen(name),
10250Sstevel@tonic-gate 		    (int) entry->n_tl_data,
10260Sstevel@tonic-gate 		    (int) entry->n_key_data,
10270Sstevel@tonic-gate 		    (int) entry->e_length,
10280Sstevel@tonic-gate 		    name);
10290Sstevel@tonic-gate 	    fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t",
10300Sstevel@tonic-gate 		    entry->attributes,
10310Sstevel@tonic-gate 		    entry->max_life,
10320Sstevel@tonic-gate 		    entry->max_renewable_life,
10330Sstevel@tonic-gate 		    entry->expiration,
10340Sstevel@tonic-gate 		    entry->pw_expiration,
10350Sstevel@tonic-gate 		    entry->last_success,
10360Sstevel@tonic-gate 		    entry->last_failed,
10370Sstevel@tonic-gate 		    entry->fail_auth_count);
10380Sstevel@tonic-gate 	    /* Pound out tagged data. */
10390Sstevel@tonic-gate 			for (tlp = entry->tl_data; tlp;
10400Sstevel@tonic-gate 			    tlp = tlp->tl_data_next) {
10410Sstevel@tonic-gate 		fprintf(arg->ofile, "%d\t%d\t",
10420Sstevel@tonic-gate 			(int) tlp->tl_data_type,
10430Sstevel@tonic-gate 			(int) tlp->tl_data_length);
10440Sstevel@tonic-gate 		if (tlp->tl_data_length)
10450Sstevel@tonic-gate 					for (i = 0;
10460Sstevel@tonic-gate 					    i < tlp->tl_data_length;
10470Sstevel@tonic-gate 					    i++)
10480Sstevel@tonic-gate 						fprintf(arg->ofile, "%02x",
10490Sstevel@tonic-gate 							tlp->
10500Sstevel@tonic-gate 							tl_data_contents[i]);
10510Sstevel@tonic-gate 		else
10520Sstevel@tonic-gate 		    fprintf(arg->ofile, "%d", -1);
10530Sstevel@tonic-gate 		fprintf(arg->ofile, "\t");
10540Sstevel@tonic-gate 	    }
10550Sstevel@tonic-gate 
10560Sstevel@tonic-gate 	    /* Pound out key data */
10570Sstevel@tonic-gate 			for (counter = 0;
10580Sstevel@tonic-gate 			    counter < entry->n_key_data; counter++) {
10590Sstevel@tonic-gate 		kdata = &entry->key_data[counter];
10600Sstevel@tonic-gate 		fprintf(arg->ofile, "%d\t%d\t",
10610Sstevel@tonic-gate 			(int) kdata->key_data_ver,
10620Sstevel@tonic-gate 			(int) kdata->key_data_kvno);
10630Sstevel@tonic-gate 		for (i=0; i<kdata->key_data_ver; i++) {
10640Sstevel@tonic-gate 		    fprintf(arg->ofile, "%d\t%d\t",
10650Sstevel@tonic-gate 			    kdata->key_data_type[i],
10660Sstevel@tonic-gate 			    kdata->key_data_length[i]);
10670Sstevel@tonic-gate 		    if (kdata->key_data_length[i])
10680Sstevel@tonic-gate 						for (j = 0;
10690Sstevel@tonic-gate 						    j < kdata->
10700Sstevel@tonic-gate 							key_data_length[i];
10710Sstevel@tonic-gate 						    j++)
10720Sstevel@tonic-gate 							fprintf(arg->ofile,
10730Sstevel@tonic-gate 							    "%02x",
10740Sstevel@tonic-gate 							    kdata->
10750Sstevel@tonic-gate 							    key_data_contents
10760Sstevel@tonic-gate 								[i][j]);
10770Sstevel@tonic-gate 		    else
10780Sstevel@tonic-gate 			fprintf(arg->ofile, "%d", -1);
10790Sstevel@tonic-gate 		    fprintf(arg->ofile, "\t");
10800Sstevel@tonic-gate 		}
10810Sstevel@tonic-gate 	    }
10820Sstevel@tonic-gate 
10830Sstevel@tonic-gate 	    /* Pound out extra data */
10840Sstevel@tonic-gate 	    if (entry->e_length)
10850Sstevel@tonic-gate 		for (i=0; i<entry->e_length; i++)
10860Sstevel@tonic-gate 					fprintf(arg->ofile, "%02x",
10870Sstevel@tonic-gate 						entry->e_data[i]);
10880Sstevel@tonic-gate 	    else
10890Sstevel@tonic-gate 		fprintf(arg->ofile, "%d", -1);
10900Sstevel@tonic-gate 
10910Sstevel@tonic-gate 	    /* Print trailer */
10920Sstevel@tonic-gate 	    fprintf(arg->ofile, ";\n");
10930Sstevel@tonic-gate 
10940Sstevel@tonic-gate 	    if (arg->verbose)
10950Sstevel@tonic-gate 		fprintf(stderr, "%s\n", name);
10960Sstevel@tonic-gate 		} else {
10970Sstevel@tonic-gate 			fprintf(stderr, gettext(sdump_tl_inc_err),
10980Sstevel@tonic-gate 		    arg->programname, name, counter,
10990Sstevel@tonic-gate 		    (int) entry->n_tl_data);
11000Sstevel@tonic-gate 	    retval = EINVAL;
11010Sstevel@tonic-gate 	}
11020Sstevel@tonic-gate     }
11030Sstevel@tonic-gate     krb5_xfree(name);
11040Sstevel@tonic-gate     return(retval);
11050Sstevel@tonic-gate }
11060Sstevel@tonic-gate 
11070Sstevel@tonic-gate /*
11080Sstevel@tonic-gate  * dump_k5beta7_iterator()	- Output a dump record in krb5b7 format.
11090Sstevel@tonic-gate  */
11100Sstevel@tonic-gate static krb5_error_code
11110Sstevel@tonic-gate dump_k5beta7_princ(ptr, entry)
11120Sstevel@tonic-gate     krb5_pointer	ptr;
11130Sstevel@tonic-gate     krb5_db_entry	*entry;
11140Sstevel@tonic-gate {
11152881Smp153739     return dump_k5beta7_princ_ext(ptr, entry, 0);
11162881Smp153739 }
11172881Smp153739 
11182881Smp153739 static krb5_error_code
11192881Smp153739 dump_k5beta7_princ_ext(ptr, entry, kadm)
11202881Smp153739     krb5_pointer	ptr;
11212881Smp153739     krb5_db_entry	*entry;
11222881Smp153739     int			kadm;
11232881Smp153739 {
11240Sstevel@tonic-gate      krb5_error_code retval;
11250Sstevel@tonic-gate      struct dump_args *arg;
11260Sstevel@tonic-gate      char *name;
11270Sstevel@tonic-gate      int tmp_nnames;
11280Sstevel@tonic-gate 
11290Sstevel@tonic-gate      /* Initialize */
11300Sstevel@tonic-gate      arg = (struct dump_args *) ptr;
11310Sstevel@tonic-gate      name = (char *) NULL;
11320Sstevel@tonic-gate 
11330Sstevel@tonic-gate      /*
11340Sstevel@tonic-gate       * Flatten the principal name.
11350Sstevel@tonic-gate       */
11360Sstevel@tonic-gate      if ((retval = krb5_unparse_name(arg->kcontext,
11370Sstevel@tonic-gate 				     entry->princ,
11380Sstevel@tonic-gate 				     &name))) {
11390Sstevel@tonic-gate 		fprintf(stderr, gettext(pname_unp_err),
11400Sstevel@tonic-gate 		  arg->programname, error_message(retval));
11410Sstevel@tonic-gate 	  return(retval);
11420Sstevel@tonic-gate      }
11430Sstevel@tonic-gate      /*
11440Sstevel@tonic-gate       * If we don't have any match strings, or if our name matches, then
11450Sstevel@tonic-gate       * proceed with the dump, otherwise, just forget about it.
11460Sstevel@tonic-gate       */
11470Sstevel@tonic-gate      if (!arg->nnames || name_matches(name, arg)) {
11480Sstevel@tonic-gate 	  fprintf(arg->ofile, "princ\t");
11490Sstevel@tonic-gate 
11500Sstevel@tonic-gate 	  /* save the callee from matching the name again */
11510Sstevel@tonic-gate 	  tmp_nnames = arg->nnames;
11520Sstevel@tonic-gate 	  arg->nnames = 0;
11532881Smp153739 	  retval = dump_k5beta6_iterator_ext(ptr, entry, kadm);
11540Sstevel@tonic-gate 	  arg->nnames = tmp_nnames;
11550Sstevel@tonic-gate      }
11562881Smp153739 
11570Sstevel@tonic-gate      free(name);
11582881Smp153739      return retval;
11590Sstevel@tonic-gate }
11600Sstevel@tonic-gate 
11610Sstevel@tonic-gate /*
11620Sstevel@tonic-gate  * dump_iprop_princ()	- Output a dump record in iprop format.
11630Sstevel@tonic-gate  * This was created in order to dump more data, such as kadm5 tl
11640Sstevel@tonic-gate  */
11650Sstevel@tonic-gate static krb5_error_code
11660Sstevel@tonic-gate dump_iprop_princ(ptr, entry)
11670Sstevel@tonic-gate     krb5_pointer	ptr;
11680Sstevel@tonic-gate     krb5_db_entry	*entry;
11690Sstevel@tonic-gate {
11700Sstevel@tonic-gate      krb5_error_code retval;
11710Sstevel@tonic-gate      struct dump_args *arg;
11720Sstevel@tonic-gate      char *name;
11730Sstevel@tonic-gate      int tmp_nnames;
11740Sstevel@tonic-gate 
11750Sstevel@tonic-gate      /* Initialize */
11760Sstevel@tonic-gate      arg = (struct dump_args *) ptr;
11770Sstevel@tonic-gate      name = (char *) NULL;
11780Sstevel@tonic-gate 
11790Sstevel@tonic-gate      /*
11800Sstevel@tonic-gate       * Flatten the principal name.
11810Sstevel@tonic-gate       */
11820Sstevel@tonic-gate      if ((retval = krb5_unparse_name(arg->kcontext,
11830Sstevel@tonic-gate 				     entry->princ,
11840Sstevel@tonic-gate 				     &name))) {
11850Sstevel@tonic-gate 		fprintf(stderr, gettext(pname_unp_err),
11860Sstevel@tonic-gate 		  arg->programname, error_message(retval));
11870Sstevel@tonic-gate 	  return(retval);
11880Sstevel@tonic-gate      }
11890Sstevel@tonic-gate      /*
11900Sstevel@tonic-gate       * If we don't have any match strings, or if our name matches, then
11910Sstevel@tonic-gate       * proceed with the dump, otherwise, just forget about it.
11920Sstevel@tonic-gate       */
11930Sstevel@tonic-gate      if (!arg->nnames || name_matches(name, arg)) {
11940Sstevel@tonic-gate 	  fprintf(arg->ofile, "princ\t");
11950Sstevel@tonic-gate 
11960Sstevel@tonic-gate 	  /* save the callee from matching the name again */
11970Sstevel@tonic-gate 	  tmp_nnames = arg->nnames;
11980Sstevel@tonic-gate 	  arg->nnames = 0;
11990Sstevel@tonic-gate 	  retval = dump_iprop_iterator(ptr, entry);
12000Sstevel@tonic-gate 	  arg->nnames = tmp_nnames;
12010Sstevel@tonic-gate      }
12020Sstevel@tonic-gate      free(name);
12030Sstevel@tonic-gate 	return (retval);
12040Sstevel@tonic-gate }
12052881Smp153739 
12062881Smp153739 static krb5_error_code
12072881Smp153739 dump_k5beta7_princ_withpolicy(ptr, entry)
12082881Smp153739     krb5_pointer	ptr;
12092881Smp153739     krb5_db_entry	*entry;
12102881Smp153739 {
12112881Smp153739     return dump_k5beta7_princ_ext(ptr, entry, 1);
12122881Smp153739 }
12132881Smp153739 
12142881Smp153739 void dump_k5beta7_policy(void *data, osa_policy_ent_t entry)
12150Sstevel@tonic-gate {
12160Sstevel@tonic-gate      struct dump_args *arg;
12170Sstevel@tonic-gate 
12180Sstevel@tonic-gate      arg = (struct dump_args *) data;
12190Sstevel@tonic-gate      fprintf(arg->ofile, "policy\t%s\t%d\t%d\t%d\t%d\t%d\t%d\n", entry->name,
12200Sstevel@tonic-gate 	     entry->pw_min_life, entry->pw_max_life, entry->pw_min_length,
12210Sstevel@tonic-gate 	     entry->pw_min_classes, entry->pw_history_num,
12220Sstevel@tonic-gate 	     entry->policy_refcnt);
12230Sstevel@tonic-gate }
12240Sstevel@tonic-gate 
12252881Smp153739 static void print_key_data(FILE *f, krb5_key_data *key_data)
12260Sstevel@tonic-gate {
12270Sstevel@tonic-gate      int c;
12280Sstevel@tonic-gate 
12290Sstevel@tonic-gate      fprintf(f, "%d\t%d\t", key_data->key_data_type[0],
12300Sstevel@tonic-gate 	     key_data->key_data_length[0]);
12310Sstevel@tonic-gate      for(c = 0; c < key_data->key_data_length[0]; c++)
12320Sstevel@tonic-gate 	  fprintf(f, "%02x ",
12330Sstevel@tonic-gate 		  key_data->key_data_contents[0][c]);
12340Sstevel@tonic-gate }
12350Sstevel@tonic-gate 
12360Sstevel@tonic-gate /*
12370Sstevel@tonic-gate  * Function: print_princ
12380Sstevel@tonic-gate  *
12390Sstevel@tonic-gate  * Purpose: output osa_adb_princ_ent data in a human
12400Sstevel@tonic-gate  *	    readable format (which is a format suitable for
12410Sstevel@tonic-gate  *	    ovsec_adm_import consumption)
12420Sstevel@tonic-gate  *
12430Sstevel@tonic-gate  * Arguments:
12440Sstevel@tonic-gate  *	data		(input) pointer to a structure containing a FILE *
12450Sstevel@tonic-gate  *			        and a record counter.
12460Sstevel@tonic-gate  *	entry		(input) entry to get dumped.
12470Sstevel@tonic-gate  * 	<return value>	void
12480Sstevel@tonic-gate  *
12490Sstevel@tonic-gate  * Requires:
12500Sstevel@tonic-gate  *	nuttin
12510Sstevel@tonic-gate  *
12520Sstevel@tonic-gate  * Effects:
12530Sstevel@tonic-gate  *	writes data to the specified file pointerp.
12540Sstevel@tonic-gate  *
12550Sstevel@tonic-gate  * Modifies:
12560Sstevel@tonic-gate  *	nuttin
12570Sstevel@tonic-gate  *
12580Sstevel@tonic-gate  */
12592881Smp153739 static krb5_error_code dump_ov_princ(krb5_pointer ptr, krb5_db_entry *kdb)
12600Sstevel@tonic-gate {
12610Sstevel@tonic-gate     char *princstr;
12622881Smp153739     int	x, y, foundcrc;
12630Sstevel@tonic-gate     struct dump_args *arg;
12640Sstevel@tonic-gate     krb5_tl_data tl_data;
12650Sstevel@tonic-gate     osa_princ_ent_rec adb;
12660Sstevel@tonic-gate     XDR xdrs;
12670Sstevel@tonic-gate 
12680Sstevel@tonic-gate     arg = (struct dump_args *) ptr;
12690Sstevel@tonic-gate     /*
12700Sstevel@tonic-gate      * XXX Currently, lookup_tl_data always returns zero; it sets
12712881Smp153739      * tl_data->tl_data_length to zero if the type isn't found.
12722881Smp153739      * This should be fixed...
12730Sstevel@tonic-gate      */
12740Sstevel@tonic-gate     /*
12750Sstevel@tonic-gate      * XXX Should this function do nothing for a principal with no
12762881Smp153739      * admin data, or print a record of "default" values?   See
12772881Smp153739      * comment in server_kdb.c to help decide.
12780Sstevel@tonic-gate      */
12790Sstevel@tonic-gate     tl_data.tl_data_type = KRB5_TL_KADM_DATA;
12802881Smp153739     if (krb5_dbe_lookup_tl_data(arg->kcontext, kdb, &tl_data)
12812881Smp153739 	|| (tl_data.tl_data_length == 0))
12822881Smp153739 	 return 0;
12830Sstevel@tonic-gate 
12840Sstevel@tonic-gate     memset(&adb, 0, sizeof(adb));
12852881Smp153739     xdrmem_create(&xdrs, (const caddr_t) tl_data.tl_data_contents,
12860Sstevel@tonic-gate 		  tl_data.tl_data_length, XDR_DECODE);
12870Sstevel@tonic-gate     if (! xdr_osa_princ_ent_rec(&xdrs, &adb)) {
12880Sstevel@tonic-gate 	 xdr_destroy(&xdrs);
12894960Swillf 	 return(KADM5_XDR_FAILURE);
12900Sstevel@tonic-gate     }
12910Sstevel@tonic-gate     xdr_destroy(&xdrs);
12920Sstevel@tonic-gate 
12930Sstevel@tonic-gate     krb5_unparse_name(arg->kcontext, kdb->princ, &princstr);
12940Sstevel@tonic-gate     fprintf(arg->ofile, "princ\t%s\t", princstr);
12950Sstevel@tonic-gate     if(adb.policy == NULL)
12960Sstevel@tonic-gate 	fputc('\t', arg->ofile);
12970Sstevel@tonic-gate     else
12980Sstevel@tonic-gate 	fprintf(arg->ofile, "%s\t", adb.policy);
12992881Smp153739     fprintf(arg->ofile, "%lx\t%d\t%d\t%d", adb.aux_attributes,
13000Sstevel@tonic-gate 	    adb.old_key_len,adb.old_key_next, adb.admin_history_kvno);
13010Sstevel@tonic-gate 
13020Sstevel@tonic-gate     for (x = 0; x < adb.old_key_len; x++) {
13030Sstevel@tonic-gate 	 foundcrc = 0;
13040Sstevel@tonic-gate 	 for (y = 0; y < adb.old_keys[x].n_key_data; y++) {
13050Sstevel@tonic-gate 	      krb5_key_data *key_data = &adb.old_keys[x].key_data[y];
13060Sstevel@tonic-gate 
13070Sstevel@tonic-gate 	      if (key_data->key_data_type[0] != ENCTYPE_DES_CBC_CRC)
13080Sstevel@tonic-gate 		   continue;
13090Sstevel@tonic-gate 	      if (foundcrc) {
13100Sstevel@tonic-gate 				fprintf(stderr,
13110Sstevel@tonic-gate 				    gettext("Warning!  Multiple DES-CBC-CRC "
13120Sstevel@tonic-gate 					"keys for principal %s; skipping "
13130Sstevel@tonic-gate 					"duplicates.\n"),
13140Sstevel@tonic-gate 			   princstr);
13150Sstevel@tonic-gate 		   continue;
13160Sstevel@tonic-gate 	      }
13170Sstevel@tonic-gate 	      foundcrc++;
13180Sstevel@tonic-gate 
13190Sstevel@tonic-gate 	      fputc('\t', arg->ofile);
13200Sstevel@tonic-gate 	      print_key_data(arg->ofile, key_data);
13210Sstevel@tonic-gate 	 }
13220Sstevel@tonic-gate 	 if (!foundcrc)
13230Sstevel@tonic-gate 			fprintf(stderr,
13240Sstevel@tonic-gate 			    gettext("Warning!  No DES-CBC-CRC key "
13250Sstevel@tonic-gate 				"for principal %s, cannot generate "
13260Sstevel@tonic-gate 				"OV-compatible record; skipping\n"),
13270Sstevel@tonic-gate 		      princstr);
13280Sstevel@tonic-gate     }
13290Sstevel@tonic-gate 
13300Sstevel@tonic-gate     fputc('\n', arg->ofile);
13310Sstevel@tonic-gate     free(princstr);
13322881Smp153739     return 0;
13330Sstevel@tonic-gate }
13340Sstevel@tonic-gate 
13350Sstevel@tonic-gate /*
13360Sstevel@tonic-gate  * usage is:
13372881Smp153739  *	dump_db [-i] [-old] [-b6] [-b7] [-ov] [-verbose] [-mkey_convert]
13382881Smp153739  *		[-new_mkey_file mkey_file] [-rev] [-recurse]
13392881Smp153739  *		[filename [principals...]]
13400Sstevel@tonic-gate  */
13410Sstevel@tonic-gate void
13420Sstevel@tonic-gate dump_db(argc, argv)
13430Sstevel@tonic-gate     int		argc;
13440Sstevel@tonic-gate     char	**argv;
13450Sstevel@tonic-gate {
13460Sstevel@tonic-gate     FILE		*f;
13470Sstevel@tonic-gate     struct dump_args	arglist;
13480Sstevel@tonic-gate     char		*programname;
13490Sstevel@tonic-gate     char		*ofile;
13500Sstevel@tonic-gate     krb5_error_code	kret, retval;
13510Sstevel@tonic-gate     dump_version	*dump;
13520Sstevel@tonic-gate     int			aindex;
13530Sstevel@tonic-gate     krb5_boolean	locked;
13540Sstevel@tonic-gate     char		*new_mkey_file = 0;
13550Sstevel@tonic-gate     bool_t		dump_sno = FALSE;
13560Sstevel@tonic-gate     kdb_log_context	*log_ctx;
13575916Swillf     /* Solaris Kerberos: adding support for -rev/recurse flags */
13585916Swillf     int			db_arg_index = 0;
13595916Swillf     char		*db_args[3] = {NULL, NULL, NULL};
13600Sstevel@tonic-gate 
13610Sstevel@tonic-gate     /*
13620Sstevel@tonic-gate      * Parse the arguments.
13630Sstevel@tonic-gate      */
13640Sstevel@tonic-gate     programname = argv[0];
13650Sstevel@tonic-gate     if (strrchr(programname, (int) '/'))
13660Sstevel@tonic-gate 	programname = strrchr(argv[0], (int) '/') + 1;
13670Sstevel@tonic-gate     ofile = (char *) NULL;
13682881Smp153739     dump = &r1_3_version;
13690Sstevel@tonic-gate     arglist.verbose = 0;
13700Sstevel@tonic-gate     new_mkey_file = 0;
13710Sstevel@tonic-gate     mkey_convert = 0;
13722881Smp153739     backwards = 0;
13732881Smp153739     recursive = 0;
13740Sstevel@tonic-gate     log_ctx = util_context->kdblog_context;
13750Sstevel@tonic-gate 
13760Sstevel@tonic-gate     /*
13770Sstevel@tonic-gate      * Parse the qualifiers.
13780Sstevel@tonic-gate      */
13790Sstevel@tonic-gate     for (aindex = 1; aindex < argc; aindex++) {
13802881Smp153739 	if (!strcmp(argv[aindex], oldoption))
13810Sstevel@tonic-gate 	     dump = &old_version;
13822881Smp153739 	else if (!strcmp(argv[aindex], b6option))
13830Sstevel@tonic-gate 	     dump = &beta6_version;
13842881Smp153739 	else if (!strcmp(argv[aindex], b7option))
13852881Smp153739 	     dump = &beta7_version;
13862881Smp153739 	else if (!strcmp(argv[aindex], ovoption))
13870Sstevel@tonic-gate 	     dump = &ov_version;
13882881Smp153739 	else if (!strcmp(argv[aindex], ipropoption)) {
13890Sstevel@tonic-gate 			if (log_ctx && log_ctx->iproprole) {
13900Sstevel@tonic-gate 				dump = &iprop_version;
13910Sstevel@tonic-gate 				/*
13920Sstevel@tonic-gate 				 * dump_sno is used to indicate if the serial
13930Sstevel@tonic-gate 				 * # should be populated in the output
13940Sstevel@tonic-gate 				 * file to be used later by iprop for updating
13950Sstevel@tonic-gate 				 * the slave's update log when loading
13960Sstevel@tonic-gate 				 */
13970Sstevel@tonic-gate 				dump_sno = TRUE;
13980Sstevel@tonic-gate 			} else {
13990Sstevel@tonic-gate 				fprintf(stderr, gettext("Iprop not enabled\n"));
14000Sstevel@tonic-gate 				exit_status++;
14010Sstevel@tonic-gate 				return;
14020Sstevel@tonic-gate 			}
14030Sstevel@tonic-gate 		}
14042881Smp153739 	else if (!strcmp(argv[aindex], verboseoption))
14050Sstevel@tonic-gate 	    arglist.verbose++;
14060Sstevel@tonic-gate 	else if (!strcmp(argv[aindex], "-mkey_convert"))
14070Sstevel@tonic-gate 	    mkey_convert = 1;
14080Sstevel@tonic-gate 	else if (!strcmp(argv[aindex], "-new_mkey_file")) {
14090Sstevel@tonic-gate 	    new_mkey_file = argv[++aindex];
14100Sstevel@tonic-gate 	    mkey_convert = 1;
14115916Swillf         } else if (!strcmp(argv[aindex], "-rev")) {
14125916Swillf 	    /* Solaris Kerberos: adding support for -rev/recurse flags */
14135916Swillf 	    /* hack to pass args to db specific plugin */
14145916Swillf 	    db_args[db_arg_index++] = "rev";
14155916Swillf 	} else if (!strcmp(argv[aindex], "-recurse")) {
14165916Swillf 	    /* hack to pass args to db specific plugin */
14175916Swillf 	    db_args[db_arg_index++] = "recurse";
14185916Swillf 	} else
14190Sstevel@tonic-gate 	    break;
14200Sstevel@tonic-gate     }
14210Sstevel@tonic-gate 
14220Sstevel@tonic-gate     arglist.names = (char **) NULL;
14230Sstevel@tonic-gate     arglist.nnames = 0;
14240Sstevel@tonic-gate     if (aindex < argc) {
14250Sstevel@tonic-gate 	ofile = argv[aindex];
14260Sstevel@tonic-gate 	aindex++;
14270Sstevel@tonic-gate 	if (aindex < argc) {
14280Sstevel@tonic-gate 	    arglist.names = &argv[aindex];
14290Sstevel@tonic-gate 	    arglist.nnames = argc - aindex;
14300Sstevel@tonic-gate 	}
14310Sstevel@tonic-gate     }
14320Sstevel@tonic-gate 
14330Sstevel@tonic-gate     /*
14340Sstevel@tonic-gate      * Make sure the database is open.  The policy database only has
14350Sstevel@tonic-gate      * to be opened if we try a dump that uses it.
14360Sstevel@tonic-gate      */
14374960Swillf     if (!dbactive) {
14380Sstevel@tonic-gate 	com_err(argv[0], 0, Err_no_database);
14390Sstevel@tonic-gate 	exit_status++;
14400Sstevel@tonic-gate 	return;
14410Sstevel@tonic-gate     }
14420Sstevel@tonic-gate 
14430Sstevel@tonic-gate     /*
14440Sstevel@tonic-gate      * If we're doing a master key conversion, set up for it.
14450Sstevel@tonic-gate      */
14460Sstevel@tonic-gate     if (mkey_convert) {
14470Sstevel@tonic-gate 	    if (!valid_master_key) {
14480Sstevel@tonic-gate 		    /* TRUE here means read the keyboard, but only once */
14490Sstevel@tonic-gate 		    retval = krb5_db_fetch_mkey(util_context,
14500Sstevel@tonic-gate 						master_princ,
14510Sstevel@tonic-gate 						global_params.enctype,
14520Sstevel@tonic-gate 						TRUE, FALSE,
14530Sstevel@tonic-gate 						(char *) NULL, 0,
14540Sstevel@tonic-gate 						&master_key);
14550Sstevel@tonic-gate 		    if (retval) {
14560Sstevel@tonic-gate 			    com_err(argv[0], retval,
14570Sstevel@tonic-gate 				    gettext("while reading master key"));
14580Sstevel@tonic-gate 			    exit(1);
14590Sstevel@tonic-gate 		    }
14600Sstevel@tonic-gate 		    retval = krb5_db_verify_master_key(util_context,
14610Sstevel@tonic-gate 						       master_princ,
14620Sstevel@tonic-gate 						       &master_key);
14630Sstevel@tonic-gate 		    if (retval) {
14640Sstevel@tonic-gate 			    com_err(argv[0], retval,
14650Sstevel@tonic-gate 				    gettext("while verifying master key"));
14660Sstevel@tonic-gate 			    exit(1);
14670Sstevel@tonic-gate 		    }
14680Sstevel@tonic-gate 	    }
14690Sstevel@tonic-gate 	    if (!new_mkey_file)
14700Sstevel@tonic-gate 		    printf(gettext("Please enter new master key....\n"));
14710Sstevel@tonic-gate 	    if ((retval = krb5_db_fetch_mkey(util_context, master_princ,
14720Sstevel@tonic-gate 					     global_params.enctype,
14732881Smp153739 					     (new_mkey_file == 0) ?
14742881Smp153739 					        (krb5_boolean) 1 : 0,
14752881Smp153739 					     TRUE,
14760Sstevel@tonic-gate 					     new_mkey_file, 0,
14770Sstevel@tonic-gate 					     &new_master_key))) {
14780Sstevel@tonic-gate 		    com_err(argv[0], retval,
14790Sstevel@tonic-gate 			    gettext("while reading new master key"));
14800Sstevel@tonic-gate 		    exit(1);
14810Sstevel@tonic-gate 	    }
14820Sstevel@tonic-gate     }
14830Sstevel@tonic-gate 
14840Sstevel@tonic-gate     kret = 0;
14850Sstevel@tonic-gate     locked = 0;
14860Sstevel@tonic-gate     if (ofile && strcmp(ofile, "-")) {
14870Sstevel@tonic-gate 	/*
14882881Smp153739 	 * Discourage accidental dumping to filenames beginning with '-'.
14892881Smp153739 	 */
14902881Smp153739 	if (ofile[0] == '-')
14912881Smp153739 	    usage();
14922881Smp153739 	/*
14930Sstevel@tonic-gate 	 * Make sure that we don't open and truncate on the fopen,
14940Sstevel@tonic-gate 	 * since that may hose an on-going kprop process.
14950Sstevel@tonic-gate 	 *
14962881Smp153739 	 * We could also control this by opening for read and
14972881Smp153739 	 * write, doing an flock with LOCK_EX, and then
14982881Smp153739 	 * truncating the file once we have gotten the lock,
14992881Smp153739 	 * but that would involve more OS dependencies than I
15002881Smp153739 	 * want to get into.
15010Sstevel@tonic-gate 	 */
15020Sstevel@tonic-gate 	unlink(ofile);
15030Sstevel@tonic-gate 	if (!(f = fopen(ofile, "w"))) {
15040Sstevel@tonic-gate 			fprintf(stderr, gettext(ofopen_error),
15050Sstevel@tonic-gate 		    programname, ofile, error_message(errno));
15060Sstevel@tonic-gate 	    exit_status++;
15070Sstevel@tonic-gate 	    return;
15080Sstevel@tonic-gate        }
15090Sstevel@tonic-gate 	if ((kret = krb5_lock_file(util_context,
15100Sstevel@tonic-gate 				   fileno(f),
15110Sstevel@tonic-gate 				   KRB5_LOCKMODE_EXCLUSIVE))) {
15120Sstevel@tonic-gate 			fprintf(stderr, gettext(oflock_error),
15130Sstevel@tonic-gate 		    programname, ofile, error_message(kret));
15140Sstevel@tonic-gate 	    exit_status++;
15152881Smp153739 	}
15162881Smp153739 	else
15170Sstevel@tonic-gate 	    locked = 1;
15180Sstevel@tonic-gate     } else {
15190Sstevel@tonic-gate 	f = stdout;
15200Sstevel@tonic-gate     }
15210Sstevel@tonic-gate     if (f && !(kret)) {
15220Sstevel@tonic-gate 	arglist.programname = programname;
15230Sstevel@tonic-gate 	arglist.ofile = f;
15240Sstevel@tonic-gate 	arglist.kcontext = util_context;
15250Sstevel@tonic-gate 	fprintf(arglist.ofile, "%s", dump->header);
15260Sstevel@tonic-gate 
15270Sstevel@tonic-gate 	if (dump_sno) {
15280Sstevel@tonic-gate 		if (ulog_map(util_context, &global_params, FKCOMMAND)) {
15290Sstevel@tonic-gate 			fprintf(stderr,
15300Sstevel@tonic-gate 			    gettext("%s: Could not map log\n"), programname);
15310Sstevel@tonic-gate 			exit_status++;
15320Sstevel@tonic-gate 			goto error;
15330Sstevel@tonic-gate 		}
15340Sstevel@tonic-gate 
15350Sstevel@tonic-gate 		/*
15360Sstevel@tonic-gate 		 * We grab the lock twice (once again in the iterator call),
15370Sstevel@tonic-gate 		 * but that's ok since the lock func handles incr locks held.
15380Sstevel@tonic-gate 		 */
15390Sstevel@tonic-gate 		if (krb5_db_lock(util_context, KRB5_LOCKMODE_SHARED)) {
15400Sstevel@tonic-gate 			fprintf(stderr,
15410Sstevel@tonic-gate 			    gettext("%s: Couldn't grab lock\n"), programname);
15420Sstevel@tonic-gate 			exit_status++;
15430Sstevel@tonic-gate 			goto error;
15440Sstevel@tonic-gate 		}
15450Sstevel@tonic-gate 
15460Sstevel@tonic-gate 		fprintf(f, " %u", log_ctx->ulog->kdb_last_sno);
15470Sstevel@tonic-gate 		fprintf(f, " %u", log_ctx->ulog->kdb_last_time.seconds);
15480Sstevel@tonic-gate 		fprintf(f, " %u", log_ctx->ulog->kdb_last_time.useconds);
15490Sstevel@tonic-gate 	}
15500Sstevel@tonic-gate 
15510Sstevel@tonic-gate 	if (dump->header[strlen(dump->header)-1] != '\n')
15520Sstevel@tonic-gate 	     fputc('\n', arglist.ofile);
15530Sstevel@tonic-gate 
15545916Swillf 	/* Solaris Kerberos: adding support for -rev/recurse flags */
15555916Swillf 	/* don't pass in db_args if there aren't any */
15564960Swillf 	if ((kret = krb5_db_iterate(util_context,
15574960Swillf 				    NULL,
15584960Swillf 				    dump->dump_princ,
15595916Swillf 				    (krb5_pointer) &arglist,
15605916Swillf 				    db_arg_index > 0 ? (char **)&db_args : NULL))) {
15614960Swillf 	     fprintf(stderr, dumprec_err,
15620Sstevel@tonic-gate 		     programname, dump->name, error_message(kret));
15630Sstevel@tonic-gate 	     exit_status++;
15640Sstevel@tonic-gate 		if (dump_sno)
15650Sstevel@tonic-gate 			(void) krb5_db_unlock(util_context);
15660Sstevel@tonic-gate 	}
15670Sstevel@tonic-gate 	if (dump->dump_policy &&
15684960Swillf 	    (kret = krb5_db_iter_policy( util_context, "*", dump->dump_policy,
15694960Swillf 					 &arglist))) {
15704960Swillf 	     fprintf(stderr, gettext(dumprec_err),
15714960Swillf 		programname, dump->name,
15720Sstevel@tonic-gate 		     error_message(kret));
15730Sstevel@tonic-gate 	     exit_status++;
15740Sstevel@tonic-gate 	}
15750Sstevel@tonic-gate 
15760Sstevel@tonic-gate error:
15770Sstevel@tonic-gate 	if (ofile && f != stdout && !exit_status) {
15784960Swillf 	    if (locked) {
15794960Swillf 		(void) krb5_lock_file(util_context, fileno(f), KRB5_LOCKMODE_UNLOCK);
15804960Swillf 		locked = 0;
15814960Swillf 	    }
15824960Swillf 	    fclose(f);
15834960Swillf 	    update_ok_file(ofile);
15840Sstevel@tonic-gate 	}
15850Sstevel@tonic-gate     }
15860Sstevel@tonic-gate     if (locked)
15872881Smp153739 	(void) krb5_lock_file(util_context, fileno(f), KRB5_LOCKMODE_UNLOCK);
15880Sstevel@tonic-gate }
15890Sstevel@tonic-gate 
15900Sstevel@tonic-gate /*
15910Sstevel@tonic-gate  * Read a string of bytes while counting the number of lines passed.
15920Sstevel@tonic-gate  */
15930Sstevel@tonic-gate static int
15940Sstevel@tonic-gate read_string(f, buf, len, lp)
15950Sstevel@tonic-gate     FILE	*f;
15960Sstevel@tonic-gate     char	*buf;
15970Sstevel@tonic-gate     int		len;
15980Sstevel@tonic-gate     int		*lp;
15990Sstevel@tonic-gate {
16000Sstevel@tonic-gate     int c;
16010Sstevel@tonic-gate     int i, retval;
16020Sstevel@tonic-gate 
16030Sstevel@tonic-gate     retval = 0;
16040Sstevel@tonic-gate     for (i=0; i<len; i++) {
16050Sstevel@tonic-gate 	c = fgetc(f);
16060Sstevel@tonic-gate 	if (c < 0) {
16070Sstevel@tonic-gate 	    retval = 1;
16080Sstevel@tonic-gate 	    break;
16090Sstevel@tonic-gate 	}
16100Sstevel@tonic-gate 	if (c == '\n')
16110Sstevel@tonic-gate 	    (*lp)++;
16120Sstevel@tonic-gate 	buf[i] = (char) c;
16130Sstevel@tonic-gate     }
16140Sstevel@tonic-gate     buf[len] = '\0';
16150Sstevel@tonic-gate     return(retval);
16160Sstevel@tonic-gate }
16170Sstevel@tonic-gate 
16180Sstevel@tonic-gate /*
16190Sstevel@tonic-gate  * Read a string of two character representations of bytes.
16200Sstevel@tonic-gate  */
16210Sstevel@tonic-gate static int
16220Sstevel@tonic-gate read_octet_string(f, buf, len)
16230Sstevel@tonic-gate     FILE	*f;
16240Sstevel@tonic-gate     krb5_octet	*buf;
16250Sstevel@tonic-gate     int		len;
16260Sstevel@tonic-gate {
16270Sstevel@tonic-gate     int c;
16280Sstevel@tonic-gate     int i, retval;
16290Sstevel@tonic-gate 
16300Sstevel@tonic-gate     retval = 0;
16310Sstevel@tonic-gate     for (i=0; i<len; i++) {
16320Sstevel@tonic-gate 	if (fscanf(f, "%02x", &c) != 1) {
16330Sstevel@tonic-gate 	    retval = 1;
16340Sstevel@tonic-gate 	    break;
16350Sstevel@tonic-gate 	}
16360Sstevel@tonic-gate 	buf[i] = (krb5_octet) c;
16370Sstevel@tonic-gate     }
16380Sstevel@tonic-gate     return(retval);
16390Sstevel@tonic-gate }
16400Sstevel@tonic-gate 
16410Sstevel@tonic-gate /*
16420Sstevel@tonic-gate  * Find the end of an old format record.
16430Sstevel@tonic-gate  */
16440Sstevel@tonic-gate static void
16450Sstevel@tonic-gate find_record_end(f, fn, lineno)
16460Sstevel@tonic-gate     FILE	*f;
16470Sstevel@tonic-gate     char	*fn;
16480Sstevel@tonic-gate     int		lineno;
16490Sstevel@tonic-gate {
16500Sstevel@tonic-gate     int	ch;
16510Sstevel@tonic-gate 
16520Sstevel@tonic-gate     if (((ch = fgetc(f)) != ';') || ((ch = fgetc(f)) != '\n')) {
16530Sstevel@tonic-gate 		fprintf(stderr, gettext(trash_end_fmt), fn, lineno);
16540Sstevel@tonic-gate 	while (ch != '\n') {
16550Sstevel@tonic-gate 	    putc(ch, stderr);
16560Sstevel@tonic-gate 	    ch = fgetc(f);
16570Sstevel@tonic-gate 	}
16580Sstevel@tonic-gate 	putc(ch, stderr);
16590Sstevel@tonic-gate     }
16600Sstevel@tonic-gate }
16610Sstevel@tonic-gate 
16620Sstevel@tonic-gate #if 0
16630Sstevel@tonic-gate /*
16640Sstevel@tonic-gate  * update_tl_data()	- Generate the tl_data entries.
16650Sstevel@tonic-gate  */
16660Sstevel@tonic-gate static krb5_error_code
16670Sstevel@tonic-gate update_tl_data(kcontext, dbentp, mod_name, mod_date, last_pwd_change)
16680Sstevel@tonic-gate     krb5_context	kcontext;
16690Sstevel@tonic-gate     krb5_db_entry	*dbentp;
16700Sstevel@tonic-gate     krb5_principal	mod_name;
16710Sstevel@tonic-gate     krb5_timestamp	mod_date;
16720Sstevel@tonic-gate     krb5_timestamp	last_pwd_change;
16730Sstevel@tonic-gate {
16740Sstevel@tonic-gate     krb5_error_code	kret;
16750Sstevel@tonic-gate 
16760Sstevel@tonic-gate     kret = 0 ;
16770Sstevel@tonic-gate 
16780Sstevel@tonic-gate     /*
16790Sstevel@tonic-gate      * Handle modification principal.
16800Sstevel@tonic-gate      */
16810Sstevel@tonic-gate     if (mod_name) {
16820Sstevel@tonic-gate 	krb5_tl_mod_princ	mprinc;
16830Sstevel@tonic-gate 
16840Sstevel@tonic-gate 	memset(&mprinc, 0, sizeof(mprinc));
16850Sstevel@tonic-gate 	if (!(kret = krb5_copy_principal(kcontext,
16860Sstevel@tonic-gate 					 mod_name,
16870Sstevel@tonic-gate 					 &mprinc.mod_princ))) {
16880Sstevel@tonic-gate 	    mprinc.mod_date = mod_date;
16890Sstevel@tonic-gate 	    kret = krb5_dbe_encode_mod_princ_data(kcontext,
16900Sstevel@tonic-gate 						  &mprinc,
16910Sstevel@tonic-gate 						  dbentp);
16920Sstevel@tonic-gate 	}
16930Sstevel@tonic-gate 	if (mprinc.mod_princ)
16940Sstevel@tonic-gate 	    krb5_free_principal(kcontext, mprinc.mod_princ);
16950Sstevel@tonic-gate     }
16962881Smp153739 
16970Sstevel@tonic-gate     /*
16980Sstevel@tonic-gate      * Handle last password change.
16990Sstevel@tonic-gate      */
17000Sstevel@tonic-gate     if (!kret) {
17010Sstevel@tonic-gate 	krb5_tl_data	*pwchg;
17020Sstevel@tonic-gate 	krb5_boolean	linked;
17030Sstevel@tonic-gate 
17040Sstevel@tonic-gate 	/* Find a previously existing entry */
17050Sstevel@tonic-gate 	for (pwchg = dbentp->tl_data;
17060Sstevel@tonic-gate 	     (pwchg) && (pwchg->tl_data_type != KRB5_TL_LAST_PWD_CHANGE);
17070Sstevel@tonic-gate 	     pwchg = pwchg->tl_data_next);
17080Sstevel@tonic-gate 
17090Sstevel@tonic-gate 	/* Check to see if we found one. */
17100Sstevel@tonic-gate 	linked = 0;
17110Sstevel@tonic-gate 	if (!pwchg) {
17120Sstevel@tonic-gate 	    /* No, allocate a new one */
17132881Smp153739 	    if ((pwchg = (krb5_tl_data *) malloc(sizeof(krb5_tl_data)))) {
17142881Smp153739 		memset(pwchg, 0, sizeof(krb5_tl_data));
17152881Smp153739 		if (!(pwchg->tl_data_contents =
17162881Smp153739 		      (krb5_octet *) malloc(sizeof(krb5_timestamp)))) {
17172881Smp153739 		    free(pwchg);
17182881Smp153739 		    pwchg = (krb5_tl_data *) NULL;
17192881Smp153739 		}
17202881Smp153739 		else {
17212881Smp153739 		    pwchg->tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
17222881Smp153739 		    pwchg->tl_data_length =
17232881Smp153739 			(krb5_int16) sizeof(krb5_timestamp);
17242881Smp153739 		}
17250Sstevel@tonic-gate 	    }
17262881Smp153739 	}
17272881Smp153739 	else
17282881Smp153739 	    linked = 1;
17290Sstevel@tonic-gate 
17300Sstevel@tonic-gate 	/* Do we have an entry? */
17310Sstevel@tonic-gate 	if (pwchg && pwchg->tl_data_contents) {
17320Sstevel@tonic-gate 	    /* Encode it */
17332881Smp153739 	    krb5_kdb_encode_int32(last_pwd_change, pwchg->tl_data_contents);
17340Sstevel@tonic-gate 	    /* Link it in if necessary */
17350Sstevel@tonic-gate 	    if (!linked) {
17360Sstevel@tonic-gate 		pwchg->tl_data_next = dbentp->tl_data;
17370Sstevel@tonic-gate 		dbentp->tl_data = pwchg;
17380Sstevel@tonic-gate 		dbentp->n_tl_data++;
17390Sstevel@tonic-gate 	    }
17402881Smp153739 	}
17412881Smp153739 	else
17420Sstevel@tonic-gate 	    kret = ENOMEM;
17430Sstevel@tonic-gate     }
17442881Smp153739 
17450Sstevel@tonic-gate     return(kret);
17460Sstevel@tonic-gate }
17470Sstevel@tonic-gate #endif
17480Sstevel@tonic-gate 
17490Sstevel@tonic-gate /*
17500Sstevel@tonic-gate  * process_k5beta_record()	- Handle a dump record in old format.
17510Sstevel@tonic-gate  *
17520Sstevel@tonic-gate  * Returns -1 for end of file, 0 for success and 1 for failure.
17530Sstevel@tonic-gate  */
17540Sstevel@tonic-gate static int
17554960Swillf process_k5beta_record(fname, kcontext, filep, verbose, linenop)
17560Sstevel@tonic-gate     char		*fname;
17570Sstevel@tonic-gate     krb5_context	kcontext;
17580Sstevel@tonic-gate     FILE		*filep;
17590Sstevel@tonic-gate     int			verbose;
17600Sstevel@tonic-gate     int			*linenop;
17610Sstevel@tonic-gate {
17620Sstevel@tonic-gate     int			nmatched;
17630Sstevel@tonic-gate     int			retval;
17640Sstevel@tonic-gate     krb5_db_entry	dbent;
17650Sstevel@tonic-gate     int			name_len, mod_name_len, key_len;
17660Sstevel@tonic-gate     int			alt_key_len, salt_len, alt_salt_len;
17670Sstevel@tonic-gate     char		*name;
17680Sstevel@tonic-gate     char		*mod_name;
17690Sstevel@tonic-gate     int			tmpint1, tmpint2, tmpint3;
17700Sstevel@tonic-gate     int			error;
17710Sstevel@tonic-gate     const char		*try2read;
17720Sstevel@tonic-gate     int			i;
17730Sstevel@tonic-gate     krb5_key_data	*pkey, *akey;
17740Sstevel@tonic-gate     krb5_timestamp	last_pwd_change, mod_date;
17750Sstevel@tonic-gate     krb5_principal	mod_princ;
17760Sstevel@tonic-gate     krb5_error_code	kret;
17770Sstevel@tonic-gate     krb5_octet 		*shortcopy1 = NULL; /* SUNWresync121 memleak fix */
17780Sstevel@tonic-gate     krb5_octet 		*shortcopy2 = NULL;
17790Sstevel@tonic-gate 
17800Sstevel@tonic-gate     try2read = (char *) NULL;
17810Sstevel@tonic-gate     (*linenop)++;
17820Sstevel@tonic-gate     retval = 1;
17830Sstevel@tonic-gate     memset((char *)&dbent, 0, sizeof(dbent));
17840Sstevel@tonic-gate 
17850Sstevel@tonic-gate     /* Make sure we've got key_data entries */
17860Sstevel@tonic-gate     if (krb5_dbe_create_key_data(kcontext, &dbent) ||
17870Sstevel@tonic-gate 	krb5_dbe_create_key_data(kcontext, &dbent)) {
17880Sstevel@tonic-gate 	krb5_db_free_principal(kcontext, &dbent, 1);
17890Sstevel@tonic-gate 	return(1);
17900Sstevel@tonic-gate     }
17910Sstevel@tonic-gate     pkey = &dbent.key_data[0];
17920Sstevel@tonic-gate     akey = &dbent.key_data[1];
17930Sstevel@tonic-gate 
17940Sstevel@tonic-gate     /*
17950Sstevel@tonic-gate      * Match the sizes.  6 tokens to match.
17960Sstevel@tonic-gate      */
17970Sstevel@tonic-gate     nmatched = fscanf(filep, "%d\t%d\t%d\t%d\t%d\t%d\t",
17980Sstevel@tonic-gate 		      &name_len, &mod_name_len, &key_len,
17990Sstevel@tonic-gate 		      &alt_key_len, &salt_len, &alt_salt_len);
18000Sstevel@tonic-gate     if (nmatched == 6) {
18010Sstevel@tonic-gate         pkey->key_data_length[0] = key_len;
18020Sstevel@tonic-gate 	akey->key_data_length[0] = alt_key_len;
18030Sstevel@tonic-gate 	pkey->key_data_length[1] = salt_len;
18040Sstevel@tonic-gate 	akey->key_data_length[1] = alt_salt_len;
18050Sstevel@tonic-gate 	name = (char *) NULL;
18060Sstevel@tonic-gate 	mod_name = (char *) NULL;
18070Sstevel@tonic-gate 	/*
18080Sstevel@tonic-gate 	 * Get the memory for the variable length fields.
18090Sstevel@tonic-gate 	 */
18100Sstevel@tonic-gate 	if ((name = (char *) malloc((size_t) (name_len + 1))) &&
18110Sstevel@tonic-gate 	    (mod_name = (char *) malloc((size_t) (mod_name_len + 1))) &&
18120Sstevel@tonic-gate 	    (!key_len ||
18130Sstevel@tonic-gate 	     (pkey->key_data_contents[0] =
18140Sstevel@tonic-gate 	      (krb5_octet *) malloc((size_t) (key_len + 1)))) &&
18150Sstevel@tonic-gate 	    (!alt_key_len ||
18160Sstevel@tonic-gate 	     (akey->key_data_contents[0] =
18172881Smp153739 	      (krb5_octet *) malloc((size_t) (alt_key_len + 1)))) &&
18180Sstevel@tonic-gate 	    (!salt_len ||
18190Sstevel@tonic-gate 	     (pkey->key_data_contents[1] =
18200Sstevel@tonic-gate 	      (krb5_octet *) malloc((size_t) (salt_len + 1)))) &&
18210Sstevel@tonic-gate 	    (!alt_salt_len ||
18220Sstevel@tonic-gate 	     (akey->key_data_contents[1] =
18232881Smp153739 	      (krb5_octet *) malloc((size_t) (alt_salt_len + 1))))
18242881Smp153739 	    ) {
18250Sstevel@tonic-gate 	    error = 0;
18260Sstevel@tonic-gate 
18270Sstevel@tonic-gate 	    /* Read the principal name */
18280Sstevel@tonic-gate 	    if (read_string(filep, name, name_len, linenop)) {
18290Sstevel@tonic-gate 		try2read = read_name_string;
18300Sstevel@tonic-gate 		error++;
18310Sstevel@tonic-gate 	    }
18320Sstevel@tonic-gate 	    /* Read the key type */
18332881Smp153739 	    if (!error && (fscanf(filep, "\t%d\t", &tmpint1) != 1)) {
18342881Smp153739 		try2read = read_key_type;
18352881Smp153739 		error++;
18360Sstevel@tonic-gate 	    }
18370Sstevel@tonic-gate 	    pkey->key_data_type[0] = tmpint1;
18380Sstevel@tonic-gate 	    /* Read the old format key */
18390Sstevel@tonic-gate 	    if (!error && read_octet_string(filep,
18400Sstevel@tonic-gate 					    pkey->key_data_contents[0],
18410Sstevel@tonic-gate 					    pkey->key_data_length[0])) {
18420Sstevel@tonic-gate 		try2read = read_key_data;
18430Sstevel@tonic-gate 		error++;
18440Sstevel@tonic-gate 	    }
18450Sstevel@tonic-gate 	    /* convert to a new format key */
18462881Smp153739 	    /* the encrypted version is stored as the unencrypted key length
18472881Smp153739 	       (4 bytes, MSB first) followed by the encrypted key. */
18482881Smp153739 	    if ((pkey->key_data_length[0] > 4)
18492881Smp153739 		&& (pkey->key_data_contents[0][0] == 0)
18502881Smp153739 		&& (pkey->key_data_contents[0][1] == 0)) {
18512881Smp153739 	      /* this really does look like an old key, so drop and swap */
18522881Smp153739 	      /* the *new* length is 2 bytes, LSB first, sigh. */
18532881Smp153739 	      size_t shortlen = pkey->key_data_length[0]-4+2;
18542881Smp153739 	      krb5_octet *origdata = pkey->key_data_contents[0];
18550Sstevel@tonic-gate 
18560Sstevel@tonic-gate 		    shortcopy1 = (krb5_octet *) malloc(shortlen);
18570Sstevel@tonic-gate 		    if (shortcopy1) {
18580Sstevel@tonic-gate 			shortcopy1[0] = origdata[3];
18590Sstevel@tonic-gate 			shortcopy1[1] = origdata[2];
18600Sstevel@tonic-gate 			memcpy(shortcopy1 + 2, origdata + 4, shortlen - 2);
18610Sstevel@tonic-gate 			free(origdata);
18620Sstevel@tonic-gate 			pkey->key_data_length[0] = shortlen;
18630Sstevel@tonic-gate 			pkey->key_data_contents[0] = shortcopy1;
18640Sstevel@tonic-gate 		    } else {
18650Sstevel@tonic-gate 			fprintf(stderr, gettext(no_mem_fmt), fname, *linenop);
18660Sstevel@tonic-gate 			error++;
18670Sstevel@tonic-gate 		    }
18680Sstevel@tonic-gate 	    }
18692881Smp153739 
18700Sstevel@tonic-gate 	    /* Read principal attributes */
18712881Smp153739 	    if (!error && (fscanf(filep,
18722881Smp153739 				  "\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t",
18732881Smp153739 				  &tmpint1, &dbent.max_life,
18742881Smp153739 				  &dbent.max_renewable_life,
18752881Smp153739 				  &tmpint2, &dbent.expiration,
18762881Smp153739 				  &dbent.pw_expiration, &last_pwd_change,
18772881Smp153739 				  &dbent.last_success, &dbent.last_failed,
18782881Smp153739 				  &tmpint3) != 10)) {
18792881Smp153739 		try2read = read_pr_data1;
18802881Smp153739 		error++;
18810Sstevel@tonic-gate 	    }
18820Sstevel@tonic-gate 	    pkey->key_data_kvno = tmpint1;
18830Sstevel@tonic-gate 	    dbent.fail_auth_count = tmpint3;
18840Sstevel@tonic-gate 	    /* Read modifier name */
18850Sstevel@tonic-gate 	    if (!error && read_string(filep,
18860Sstevel@tonic-gate 				      mod_name,
18870Sstevel@tonic-gate 				      mod_name_len,
18880Sstevel@tonic-gate 				      linenop)) {
18890Sstevel@tonic-gate 		try2read = read_mod_name;
18900Sstevel@tonic-gate 		error++;
18910Sstevel@tonic-gate 	    }
18920Sstevel@tonic-gate 	    /* Read second set of attributes */
18930Sstevel@tonic-gate 	    if (!error && (fscanf(filep, "\t%u\t%u\t%u\t",
18940Sstevel@tonic-gate 				  &mod_date, &dbent.attributes,
18950Sstevel@tonic-gate 				  &tmpint1) != 3)) {
18960Sstevel@tonic-gate 		try2read = read_pr_data2;
18970Sstevel@tonic-gate 		error++;
18980Sstevel@tonic-gate 	    }
18990Sstevel@tonic-gate 	    pkey->key_data_type[1] = tmpint1;
19000Sstevel@tonic-gate 	    /* Read salt data */
19010Sstevel@tonic-gate 	    if (!error && read_octet_string(filep,
19020Sstevel@tonic-gate 					    pkey->key_data_contents[1],
19030Sstevel@tonic-gate 					    pkey->key_data_length[1])) {
19040Sstevel@tonic-gate 		try2read = read_salt_data;
19050Sstevel@tonic-gate 		error++;
19060Sstevel@tonic-gate 	    }
19070Sstevel@tonic-gate 	    /* Read alternate key type */
19082881Smp153739 	    if (!error && (fscanf(filep, "\t%u\t", &tmpint1) != 1)) {
19092881Smp153739 		try2read = read_akey_type;
19102881Smp153739 		error++;
19110Sstevel@tonic-gate 	    }
19120Sstevel@tonic-gate 	    akey->key_data_type[0] = tmpint1;
19130Sstevel@tonic-gate 	    /* Read alternate key */
19140Sstevel@tonic-gate 	    if (!error && read_octet_string(filep,
19150Sstevel@tonic-gate 					    akey->key_data_contents[0],
19160Sstevel@tonic-gate 					    akey->key_data_length[0])) {
19172881Smp153739 		try2read = read_akey_data;
19182881Smp153739 		error++;
19190Sstevel@tonic-gate 	    }
19202881Smp153739 
19210Sstevel@tonic-gate 	    /* convert to a new format key */
19222881Smp153739 	    /* the encrypted version is stored as the unencrypted key length
19232881Smp153739 	       (4 bytes, MSB first) followed by the encrypted key. */
19242881Smp153739 	    if ((akey->key_data_length[0] > 4)
19252881Smp153739 		&& (akey->key_data_contents[0][0] == 0)
19262881Smp153739 		&& (akey->key_data_contents[0][1] == 0)) {
19272881Smp153739 	      /* this really does look like an old key, so drop and swap */
19282881Smp153739 	      /* the *new* length is 2 bytes, LSB first, sigh. */
19292881Smp153739 	      size_t shortlen = akey->key_data_length[0]-4+2;
19300Sstevel@tonic-gate 
19310Sstevel@tonic-gate 		    krb5_octet *origdata = akey->key_data_contents[0];
19320Sstevel@tonic-gate 
19330Sstevel@tonic-gate 		    shortcopy2 = (krb5_octet *) malloc(shortlen);
19340Sstevel@tonic-gate 		    if (shortcopy2) {
19350Sstevel@tonic-gate 			shortcopy2[0] = origdata[3];
19360Sstevel@tonic-gate 			shortcopy2[1] = origdata[2];
19370Sstevel@tonic-gate 			memcpy(shortcopy2 + 2,
19380Sstevel@tonic-gate 			    origdata + 4, shortlen - 2);
19390Sstevel@tonic-gate 			free(origdata);
19400Sstevel@tonic-gate 			akey->key_data_length[0] = shortlen;
19410Sstevel@tonic-gate 			akey->key_data_contents[0] = shortcopy2;
19420Sstevel@tonic-gate 		    } else {
19430Sstevel@tonic-gate 			fprintf(stderr, gettext(no_mem_fmt), fname, *linenop);
19440Sstevel@tonic-gate 			error++;
19450Sstevel@tonic-gate 		    }
19460Sstevel@tonic-gate 	    }
19472881Smp153739 
19480Sstevel@tonic-gate 	    /* Read alternate salt type */
19492881Smp153739 	    if (!error && (fscanf(filep, "\t%u\t", &tmpint1) != 1)) {
19502881Smp153739 		try2read = read_asalt_type;
19512881Smp153739 		error++;
19520Sstevel@tonic-gate 	    }
19530Sstevel@tonic-gate 	    akey->key_data_type[1] = tmpint1;
19540Sstevel@tonic-gate 	    /* Read alternate salt data */
19550Sstevel@tonic-gate 	    if (!error && read_octet_string(filep,
19560Sstevel@tonic-gate 					    akey->key_data_contents[1],
19570Sstevel@tonic-gate 					    akey->key_data_length[1])) {
19580Sstevel@tonic-gate 		try2read = read_asalt_data;
19590Sstevel@tonic-gate 		error++;
19600Sstevel@tonic-gate 	    }
19610Sstevel@tonic-gate 	    /* Read expansion data - discard it */
19620Sstevel@tonic-gate 	    if (!error) {
19630Sstevel@tonic-gate 		for (i=0; i<8; i++) {
19642881Smp153739 		    if (fscanf(filep, "\t%u", &tmpint1) != 1) {
19650Sstevel@tonic-gate 			try2read = read_exp_data;
19660Sstevel@tonic-gate 			error++;
19670Sstevel@tonic-gate 			break;
19682881Smp153739 		    }
19690Sstevel@tonic-gate 		}
19700Sstevel@tonic-gate 		if (!error)
19710Sstevel@tonic-gate 		    find_record_end(filep, fname, *linenop);
19720Sstevel@tonic-gate 	    }
19732881Smp153739 
19740Sstevel@tonic-gate 	    /*
19752881Smp153739 	     * If no error, then we're done reading.  Now parse the names
19762881Smp153739 	     * and store the database dbent.
19770Sstevel@tonic-gate 	     */
19780Sstevel@tonic-gate 	    if (!error) {
19792881Smp153739 		if (!(kret = krb5_parse_name(kcontext,
19802881Smp153739 					     name,
19812881Smp153739 					     &dbent.princ))) {
19822881Smp153739 		    if (!(kret = krb5_parse_name(kcontext,
19832881Smp153739 						 mod_name,
19842881Smp153739 						 &mod_princ))) {
19852881Smp153739 			if (!(kret =
19862881Smp153739 			      krb5_dbe_update_mod_princ_data(kcontext,
19872881Smp153739 							     &dbent,
19882881Smp153739 							     mod_date,
19892881Smp153739 							     mod_princ)) &&
19902881Smp153739 			    !(kret =
19912881Smp153739 			      krb5_dbe_update_last_pwd_change(kcontext,
19922881Smp153739 							      &dbent,
19932881Smp153739 							      last_pwd_change))) {
19942881Smp153739 			    int one = 1;
19952881Smp153739 
19962881Smp153739 			    dbent.len = KRB5_KDB_V1_BASE_LENGTH;
19972881Smp153739 			    pkey->key_data_ver = (pkey->key_data_type[1] || pkey->key_data_length[1]) ?
19982881Smp153739 				2 : 1;
19992881Smp153739 			    akey->key_data_ver = (akey->key_data_type[1] || akey->key_data_length[1]) ?
20002881Smp153739 				2 : 1;
20012881Smp153739 			    if ((pkey->key_data_type[0] ==
20022881Smp153739 				 akey->key_data_type[0]) &&
20032881Smp153739 				(pkey->key_data_type[1] ==
20042881Smp153739 				 akey->key_data_type[1]))
20052881Smp153739 				dbent.n_key_data--;
20062881Smp153739 			    else if ((akey->key_data_type[0] == 0)
20072881Smp153739 				     && (akey->key_data_length[0] == 0)
20082881Smp153739 				     && (akey->key_data_type[1] == 0)
20092881Smp153739 				     && (akey->key_data_length[1] == 0))
20102881Smp153739 			        dbent.n_key_data--;
20114960Swillf 
20124960Swillf 			    dbent.mask = KADM5_LOAD | KADM5_PRINCIPAL | KADM5_ATTRIBUTES |
20134960Swillf 				KADM5_MAX_LIFE | KADM5_MAX_RLIFE | KADM5_KEY_DATA |
20144960Swillf 				KADM5_PRINC_EXPIRE_TIME | KADM5_LAST_SUCCESS |
20154960Swillf 				KADM5_LAST_FAILED | KADM5_FAIL_AUTH_COUNT;
20164960Swillf 
20172881Smp153739 			    if ((kret = krb5_db_put_principal(kcontext,
20182881Smp153739 							      &dbent,
20192881Smp153739 							      &one)) ||
20202881Smp153739 				(one != 1)) {
20212881Smp153739 				fprintf(stderr, gettext(store_err_fmt),
20222881Smp153739 					fname, *linenop, name,
20232881Smp153739 					error_message(kret));
20242881Smp153739 				error++;
20252881Smp153739 			    }
20262881Smp153739 			    else {
20272881Smp153739 				if (verbose)
20282881Smp153739 				    fprintf(stderr,
20292881Smp153739 							gettext(add_princ_fmt),
20302881Smp153739 							name);
20312881Smp153739 				retval = 0;
20322881Smp153739 			    }
20332881Smp153739 			    dbent.n_key_data = 2;
20342881Smp153739 			}
20352881Smp153739 			krb5_free_principal(kcontext, mod_princ);
20362881Smp153739 		    }
20372881Smp153739 		    else {
20382881Smp153739 			fprintf(stderr,
20392881Smp153739 				gettext(parse_err_fmt),
20402881Smp153739 				fname, *linenop, mod_name,
20412881Smp153739 				error_message(kret));
20422881Smp153739 			error++;
20432881Smp153739 		    }
20442881Smp153739 		}
20452881Smp153739 		else {
20462881Smp153739 		    fprintf(stderr, gettext(parse_err_fmt),
20472881Smp153739 			    fname, *linenop, name, error_message(kret));
20482881Smp153739 		    error++;
20492881Smp153739 		}
20500Sstevel@tonic-gate 	    }
20512881Smp153739 	    else {
20522881Smp153739 	    fprintf(stderr, gettext(no_mem_fmt), fname, *linenop, try2read);
20532881Smp153739 	    }
20542881Smp153739 	}
20552881Smp153739 	else {
20562881Smp153739 		fprintf(stderr, gettext(read_err_fmt), fname, *linenop);
20570Sstevel@tonic-gate 	}
20580Sstevel@tonic-gate 
20590Sstevel@tonic-gate 	krb5_db_free_principal(kcontext, &dbent, 1);
20600Sstevel@tonic-gate 	if (mod_name)
20610Sstevel@tonic-gate 	    free(mod_name);
20620Sstevel@tonic-gate 	if (name)
20630Sstevel@tonic-gate 	    free(name);
20642881Smp153739     }
20652881Smp153739     else {
20660Sstevel@tonic-gate 	if (nmatched != EOF)
20670Sstevel@tonic-gate 	   fprintf(stderr, gettext(rhead_err_fmt),
20680Sstevel@tonic-gate 		fname, *linenop);
20690Sstevel@tonic-gate 	else
20702881Smp153739 	    retval = -1;
20710Sstevel@tonic-gate     }
20720Sstevel@tonic-gate 
20730Sstevel@tonic-gate     if (shortcopy1)
20740Sstevel@tonic-gate 	free(shortcopy1);
20750Sstevel@tonic-gate     if (shortcopy2)
20760Sstevel@tonic-gate 	free(shortcopy2);
20770Sstevel@tonic-gate 
20782881Smp153739     return(retval);
20790Sstevel@tonic-gate }
20800Sstevel@tonic-gate 
20810Sstevel@tonic-gate /*
20820Sstevel@tonic-gate  * process_k5beta6_record()	- Handle a dump record in krb5b6 format.
20830Sstevel@tonic-gate  *
20840Sstevel@tonic-gate  * Returns -1 for end of file, 0 for success and 1 for failure.
20850Sstevel@tonic-gate  */
20860Sstevel@tonic-gate static int
20874960Swillf process_k5beta6_record(fname, kcontext, filep, verbose, linenop)
20880Sstevel@tonic-gate     char		*fname;
20890Sstevel@tonic-gate     krb5_context	kcontext;
20900Sstevel@tonic-gate     FILE		*filep;
20910Sstevel@tonic-gate     int			verbose;
20920Sstevel@tonic-gate     int			*linenop;
20930Sstevel@tonic-gate {
20940Sstevel@tonic-gate     int			retval;
20950Sstevel@tonic-gate     krb5_db_entry	dbentry;
20960Sstevel@tonic-gate     krb5_int32		t1, t2, t3, t4, t5, t6, t7, t8, t9;
20970Sstevel@tonic-gate     int			nread;
20980Sstevel@tonic-gate     int			error;
20990Sstevel@tonic-gate     int			i, j, one;
21000Sstevel@tonic-gate     char		*name;
21010Sstevel@tonic-gate     krb5_key_data	*kp, *kdatap;
21020Sstevel@tonic-gate     krb5_tl_data	**tlp, *tl;
21030Sstevel@tonic-gate     krb5_octet 		*op;
21040Sstevel@tonic-gate     krb5_error_code	kret;
21050Sstevel@tonic-gate     const char		*try2read;
21060Sstevel@tonic-gate 
21070Sstevel@tonic-gate     try2read = (char *) NULL;
21080Sstevel@tonic-gate     memset((char *) &dbentry, 0, sizeof(dbentry));
21090Sstevel@tonic-gate     (*linenop)++;
21100Sstevel@tonic-gate     retval = 1;
21110Sstevel@tonic-gate     name = (char *) NULL;
21120Sstevel@tonic-gate     kp = (krb5_key_data *) NULL;
21130Sstevel@tonic-gate     op = (krb5_octet *) NULL;
21140Sstevel@tonic-gate     error = 0;
21150Sstevel@tonic-gate     kret = 0;
21160Sstevel@tonic-gate     nread = fscanf(filep, "%d\t%d\t%d\t%d\t%d\t", &t1, &t2, &t3, &t4, &t5);
21170Sstevel@tonic-gate     if (nread == 5) {
21180Sstevel@tonic-gate 	/* Get memory for flattened principal name */
21190Sstevel@tonic-gate 	if (!(name = (char *) malloc((size_t) t2 + 1)))
21200Sstevel@tonic-gate 	    error++;
21210Sstevel@tonic-gate 
21220Sstevel@tonic-gate 	/* Get memory for and form tagged data linked list */
21230Sstevel@tonic-gate 	tlp = &dbentry.tl_data;
21240Sstevel@tonic-gate 	for (i=0; i<t3; i++) {
21252881Smp153739 	    if ((*tlp = (krb5_tl_data *) malloc(sizeof(krb5_tl_data)))) {
21260Sstevel@tonic-gate 		memset(*tlp, 0, sizeof(krb5_tl_data));
21270Sstevel@tonic-gate 		tlp = &((*tlp)->tl_data_next);
21280Sstevel@tonic-gate 		dbentry.n_tl_data++;
21292881Smp153739 	    }
21302881Smp153739 	    else {
21310Sstevel@tonic-gate 		error++;
21320Sstevel@tonic-gate 		break;
21330Sstevel@tonic-gate 	    }
21340Sstevel@tonic-gate 	}
21350Sstevel@tonic-gate 
21360Sstevel@tonic-gate 	/* Get memory for key list */
21370Sstevel@tonic-gate 	if (t4 && !(kp = (krb5_key_data *) malloc((size_t)
21380Sstevel@tonic-gate 						  (t4*sizeof(krb5_key_data)))))
21390Sstevel@tonic-gate 	    error++;
21400Sstevel@tonic-gate 
21410Sstevel@tonic-gate 	/* Get memory for extra data */
21420Sstevel@tonic-gate 	if (t5 && !(op = (krb5_octet *) malloc((size_t) t5)))
21430Sstevel@tonic-gate 	    error++;
21440Sstevel@tonic-gate 
21450Sstevel@tonic-gate 	if (!error) {
21460Sstevel@tonic-gate 	    dbentry.len = t1;
21470Sstevel@tonic-gate 	    dbentry.n_key_data = t4;
21480Sstevel@tonic-gate 	    dbentry.e_length = t5;
21490Sstevel@tonic-gate 	    if (kp) {
21502881Smp153739 		memset(kp, 0, (size_t) (t4*sizeof(krb5_key_data)));
21510Sstevel@tonic-gate 		dbentry.key_data = kp;
21520Sstevel@tonic-gate 		kp = (krb5_key_data *) NULL;
21530Sstevel@tonic-gate 	    }
21540Sstevel@tonic-gate 	    if (op) {
21550Sstevel@tonic-gate 		memset(op, 0, (size_t) t5);
21560Sstevel@tonic-gate 		dbentry.e_data = op;
21570Sstevel@tonic-gate 		op = (krb5_octet *) NULL;
21580Sstevel@tonic-gate 	    }
21592881Smp153739 
21600Sstevel@tonic-gate 	    /* Read in and parse the principal name */
21610Sstevel@tonic-gate 	    if (!read_string(filep, name, t2, linenop) &&
21622881Smp153739 		!(kret = krb5_parse_name(kcontext, name, &dbentry.princ))) {
21630Sstevel@tonic-gate 
21640Sstevel@tonic-gate 		/* Get the fixed principal attributes */
21652881Smp153739 		nread = fscanf(filep, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t",
21662881Smp153739 			       &t2, &t3, &t4, &t5, &t6, &t7, &t8, &t9);
21670Sstevel@tonic-gate 		if (nread == 8) {
21680Sstevel@tonic-gate 		    dbentry.attributes = (krb5_flags) t2;
21690Sstevel@tonic-gate 		    dbentry.max_life = (krb5_deltat) t3;
21702881Smp153739 		    dbentry.max_renewable_life = (krb5_deltat) t4;
21712881Smp153739 		    dbentry.expiration = (krb5_timestamp) t5;
21722881Smp153739 		    dbentry.pw_expiration = (krb5_timestamp) t6;
21732881Smp153739 		    dbentry.last_success = (krb5_timestamp) t7;
21742881Smp153739 		    dbentry.last_failed = (krb5_timestamp) t8;
21752881Smp153739 		    dbentry.fail_auth_count = (krb5_kvno) t9;
21764960Swillf 		    dbentry.mask = KADM5_LOAD | KADM5_PRINCIPAL | KADM5_ATTRIBUTES |
21774960Swillf 			KADM5_MAX_LIFE | KADM5_MAX_RLIFE |
21784960Swillf 			KADM5_PRINC_EXPIRE_TIME | KADM5_LAST_SUCCESS |
21794960Swillf 			KADM5_LAST_FAILED | KADM5_FAIL_AUTH_COUNT;
21800Sstevel@tonic-gate 		} else {
21810Sstevel@tonic-gate 		    try2read = read_nint_data;
21820Sstevel@tonic-gate 		    error++;
21830Sstevel@tonic-gate 		}
21840Sstevel@tonic-gate 
21850Sstevel@tonic-gate 		/*
21860Sstevel@tonic-gate 		 * Get the tagged data.
21870Sstevel@tonic-gate 		 *
21882881Smp153739 		 * Really, this code ought to discard tl data types
21892881Smp153739 		 * that it knows are special to the current version
21902881Smp153739 		 * and were not supported in the previous version.
21912881Smp153739 		 * But it's a pain to implement that here, and doing
21922881Smp153739 		 * it at dump time has almost as good an effect, so
21932881Smp153739 		 * that's what I did.  [krb5-admin/89]
21940Sstevel@tonic-gate 		 */
21950Sstevel@tonic-gate 		if (!error && dbentry.n_tl_data) {
21962881Smp153739 		    for (tl = dbentry.tl_data; tl; tl = tl->tl_data_next) {
21972881Smp153739 			nread = fscanf(filep, "%d\t%d\t", &t1, &t2);
21982881Smp153739 			if (nread == 2) {
21992881Smp153739 			    tl->tl_data_type = (krb5_int16) t1;
22002881Smp153739 			    tl->tl_data_length = (krb5_int16) t2;
22012881Smp153739 			    if (tl->tl_data_length) {
22022881Smp153739 				if (!(tl->tl_data_contents =
22032881Smp153739 				      (krb5_octet *) malloc((size_t) t2+1)) ||
22042881Smp153739 				    read_octet_string(filep,
22052881Smp153739 						      tl->tl_data_contents,
22062881Smp153739 						      t2)) {
22072881Smp153739 				    try2read = read_tcontents;
22082881Smp153739 				    error++;
22092881Smp153739 				    break;
22100Sstevel@tonic-gate 				}
22114960Swillf 				/* test to set mask fields */
22124960Swillf 				if (t1 == KRB5_TL_KADM_DATA) {
22134960Swillf 				    XDR xdrs;
22144960Swillf 				    osa_princ_ent_rec osa_princ_ent;
22154960Swillf 
22164960Swillf 				    /*
22174960Swillf 				     * Assuming aux_attributes will always be
22184960Swillf 				     * there
22194960Swillf 				     */
22204960Swillf 				    dbentry.mask |= KADM5_AUX_ATTRIBUTES;
22214960Swillf 
22224960Swillf 				    /* test for an actual policy reference */
22234960Swillf 				    memset(&osa_princ_ent, 0, sizeof(osa_princ_ent));
22244960Swillf 				    xdrmem_create(&xdrs, (char *)tl->tl_data_contents,
22254960Swillf 					    tl->tl_data_length, XDR_DECODE);
22264960Swillf 				    if (xdr_osa_princ_ent_rec(&xdrs, &osa_princ_ent) &&
22274960Swillf 					    (osa_princ_ent.aux_attributes & KADM5_POLICY) &&
22284960Swillf 					    osa_princ_ent.policy != NULL) {
22294960Swillf 
22304960Swillf 					dbentry.mask |= KADM5_POLICY;
22314960Swillf 					kdb_free_entry(NULL, NULL, &osa_princ_ent);
22324960Swillf 				    }
22334960Swillf 				    xdr_destroy(&xdrs);
22344960Swillf 				}
22352881Smp153739 			    }
22362881Smp153739 			    else {
22372881Smp153739 				/* Should be a null field */
22382881Smp153739 				nread = fscanf(filep, "%d", &t9);
22392881Smp153739 				if ((nread != 1) || (t9 != -1)) {
22402881Smp153739 				    error++;
22412881Smp153739 				    try2read = read_tcontents;
22422881Smp153739 				    break;
22432881Smp153739 				}
22442881Smp153739 			    }
22452881Smp153739 			}
22462881Smp153739 			else {
22472881Smp153739 			    try2read = read_ttypelen;
22482881Smp153739 			    error++;
22492881Smp153739 			    break;
22502881Smp153739 			}
22512881Smp153739 		    }
22524960Swillf 		    if (!error)
22534960Swillf 			dbentry.mask |= KADM5_TL_DATA;
22542881Smp153739 		}
22552881Smp153739 
22560Sstevel@tonic-gate 		/* Get the key data */
22570Sstevel@tonic-gate 		if (!error && dbentry.n_key_data) {
22582881Smp153739 		    for (i=0; !error && (i<dbentry.n_key_data); i++) {
22592881Smp153739 			kdatap = &dbentry.key_data[i];
22602881Smp153739 			nread = fscanf(filep, "%d\t%d\t", &t1, &t2);
22612881Smp153739 			if (nread == 2) {
22622881Smp153739 			    kdatap->key_data_ver = (krb5_int16) t1;
22632881Smp153739 			    kdatap->key_data_kvno = (krb5_int16) t2;
22642881Smp153739 
22652881Smp153739 			    for (j=0; j<t1; j++) {
22662881Smp153739 				nread = fscanf(filep, "%d\t%d\t", &t3, &t4);
22672881Smp153739 				if (nread == 2) {
22682881Smp153739 				    kdatap->key_data_type[j] = t3;
22692881Smp153739 				    kdatap->key_data_length[j] = t4;
22702881Smp153739 				    if (t4) {
22712881Smp153739 					if (!(kdatap->key_data_contents[j] =
22722881Smp153739 					      (krb5_octet *)
22732881Smp153739 					      malloc((size_t) t4+1)) ||
22742881Smp153739 					    read_octet_string(filep,
22752881Smp153739 							      kdatap->key_data_contents[j],
22762881Smp153739 							      t4)) {
22772881Smp153739 					    try2read = read_kcontents;
22782881Smp153739 					    error++;
22792881Smp153739 					    break;
22800Sstevel@tonic-gate 					}
22812881Smp153739 				    }
22822881Smp153739 				    else {
22832881Smp153739 					/* Should be a null field */
22842881Smp153739 					nread = fscanf(filep, "%d", &t9);
22852881Smp153739 					if ((nread != 1) || (t9 != -1)) {
22862881Smp153739 					    error++;
22872881Smp153739 					    try2read = read_kcontents;
22882881Smp153739 					    break;
22892881Smp153739 					}
22902881Smp153739 				    }
22912881Smp153739 				}
22922881Smp153739 				else {
22932881Smp153739 				    try2read = read_ktypelen;
22942881Smp153739 				    error++;
22952881Smp153739 				    break;
22962881Smp153739 				}
22972881Smp153739 			    }
22982881Smp153739 			}
22992881Smp153739 		    }
23004960Swillf 		    if (!error)
23014960Swillf 			dbentry.mask |= KADM5_KEY_DATA;
23022881Smp153739 		}
23032881Smp153739 
23040Sstevel@tonic-gate 		/* Get the extra data */
23050Sstevel@tonic-gate 		if (!error && dbentry.e_length) {
23060Sstevel@tonic-gate 		    if (read_octet_string(filep,
23070Sstevel@tonic-gate 					  dbentry.e_data,
23080Sstevel@tonic-gate 					  (int) dbentry.e_length)) {
23090Sstevel@tonic-gate 			try2read = read_econtents;
23100Sstevel@tonic-gate 			error++;
23110Sstevel@tonic-gate 		    }
23122881Smp153739 		}
23132881Smp153739 		else {
23140Sstevel@tonic-gate 		    nread = fscanf(filep, "%d", &t9);
23150Sstevel@tonic-gate 		    if ((nread != 1) || (t9 != -1)) {
23160Sstevel@tonic-gate 			error++;
23170Sstevel@tonic-gate 			try2read = read_econtents;
23180Sstevel@tonic-gate 		    }
23190Sstevel@tonic-gate 		}
23200Sstevel@tonic-gate 
23210Sstevel@tonic-gate 		/* Finally, find the end of the record. */
23220Sstevel@tonic-gate 		if (!error)
23230Sstevel@tonic-gate 		    find_record_end(filep, fname, *linenop);
23240Sstevel@tonic-gate 
23250Sstevel@tonic-gate 		/*
23262881Smp153739 		 * We have either read in all the data or choked.
23270Sstevel@tonic-gate 		 */
23280Sstevel@tonic-gate 		if (!error) {
23290Sstevel@tonic-gate 		    one = 1;
23302881Smp153739 		    if ((kret = krb5_db_put_principal(kcontext,
23310Sstevel@tonic-gate 						      &dbentry,
23320Sstevel@tonic-gate 						      &one))) {
23330Sstevel@tonic-gate 						fprintf(stderr,
23340Sstevel@tonic-gate 						    gettext(store_err_fmt),
23350Sstevel@tonic-gate 				fname, *linenop,
23360Sstevel@tonic-gate 				name, error_message(kret));
23372881Smp153739 		    }
23382881Smp153739 		    else {
23390Sstevel@tonic-gate 			if (verbose)
23400Sstevel@tonic-gate 							fprintf(stderr,
23410Sstevel@tonic-gate 							    gettext(
23420Sstevel@tonic-gate 								add_princ_fmt),
23430Sstevel@tonic-gate 							    name);
23440Sstevel@tonic-gate 			retval = 0;
23450Sstevel@tonic-gate 		    }
23462881Smp153739 		}
23472881Smp153739 		else {
23480Sstevel@tonic-gate 					fprintf(stderr, gettext(read_err_fmt),
23490Sstevel@tonic-gate 					    fname, *linenop, try2read);
23500Sstevel@tonic-gate 		}
23512881Smp153739 	    }
23522881Smp153739 	    else {
23530Sstevel@tonic-gate 		if (kret)
23540Sstevel@tonic-gate 					fprintf(stderr, gettext(parse_err_fmt),
23552881Smp153739 			    fname, *linenop, name, error_message(kret));
23560Sstevel@tonic-gate 		else
23572881Smp153739 		    fprintf(stderr, gettext(no_mem_fmt),
23580Sstevel@tonic-gate 						fname, *linenop);
23590Sstevel@tonic-gate 	    }
23602881Smp153739 	}
23612881Smp153739 	else {
23622881Smp153739 	    fprintf(stderr,
23630Sstevel@tonic-gate 				gettext(rhead_err_fmt), fname, *linenop);
23640Sstevel@tonic-gate 	}
23650Sstevel@tonic-gate 
23660Sstevel@tonic-gate 	if (op)
23670Sstevel@tonic-gate 	    free(op);
23680Sstevel@tonic-gate 	if (kp)
23690Sstevel@tonic-gate 	    free(kp);
23700Sstevel@tonic-gate 	if (name)
23710Sstevel@tonic-gate 	    free(name);
23720Sstevel@tonic-gate 	krb5_db_free_principal(kcontext, &dbentry, 1);
23732881Smp153739     }
23742881Smp153739     else {
23750Sstevel@tonic-gate 	if (nread == EOF)
23760Sstevel@tonic-gate 	    retval = -1;
23770Sstevel@tonic-gate     }
23780Sstevel@tonic-gate     return(retval);
23790Sstevel@tonic-gate }
23800Sstevel@tonic-gate 
23812881Smp153739 static int
23820Sstevel@tonic-gate process_k5beta7_policy(fname, kcontext, filep, verbose, linenop, pol_db)
23830Sstevel@tonic-gate     char		*fname;
23840Sstevel@tonic-gate     krb5_context	kcontext;
23850Sstevel@tonic-gate     FILE		*filep;
23860Sstevel@tonic-gate     int			verbose;
23870Sstevel@tonic-gate     int			*linenop;
23880Sstevel@tonic-gate     void *pol_db;
23890Sstevel@tonic-gate {
23900Sstevel@tonic-gate     osa_policy_ent_rec rec;
23910Sstevel@tonic-gate     char namebuf[1024];
23920Sstevel@tonic-gate     int nread, ret;
23930Sstevel@tonic-gate 
23940Sstevel@tonic-gate     (*linenop)++;
23950Sstevel@tonic-gate     rec.name = namebuf;
23960Sstevel@tonic-gate 
23970Sstevel@tonic-gate     nread = fscanf(filep, "%1024s\t%d\t%d\t%d\t%d\t%d\t%d", rec.name,
23980Sstevel@tonic-gate 		   &rec.pw_min_life, &rec.pw_max_life,
23990Sstevel@tonic-gate 		   &rec.pw_min_length, &rec.pw_min_classes,
24000Sstevel@tonic-gate 		   &rec.pw_history_num, &rec.policy_refcnt);
24010Sstevel@tonic-gate     if (nread == EOF)
24022881Smp153739 	 return -1;
24030Sstevel@tonic-gate     else if (nread != 7) {
24040Sstevel@tonic-gate 		fprintf(stderr,
24050Sstevel@tonic-gate 		    gettext("cannot parse policy on line %d (%d read)\n"),
24060Sstevel@tonic-gate 		 *linenop, nread);
24072881Smp153739 	 return 1;
24080Sstevel@tonic-gate     }
24090Sstevel@tonic-gate 
24104960Swillf     if ((ret = krb5_db_create_policy(kcontext, &rec))) {
24114960Swillf 	 if (ret &&
24124960Swillf 	     ((ret = krb5_db_put_policy(kcontext, &rec)))) {
24130Sstevel@tonic-gate 	      fprintf(stderr, gettext("cannot create policy on line %d: %s\n"),
24140Sstevel@tonic-gate 		      *linenop, error_message(ret));
24152881Smp153739 	      return 1;
24160Sstevel@tonic-gate 	 }
24170Sstevel@tonic-gate     }
24180Sstevel@tonic-gate     if (verbose)
24190Sstevel@tonic-gate 		fprintf(stderr, gettext("created policy %s\n"), rec.name);
24200Sstevel@tonic-gate 
24212881Smp153739     return 0;
24220Sstevel@tonic-gate }
24230Sstevel@tonic-gate 
24240Sstevel@tonic-gate /*
24252881Smp153739  * process_k5beta7_record()	- Handle a dump record in krb5b7 format.
24260Sstevel@tonic-gate  *
24270Sstevel@tonic-gate  * Returns -1 for end of file, 0 for success and 1 for failure.
24280Sstevel@tonic-gate  */
24290Sstevel@tonic-gate static int
24304960Swillf process_k5beta7_record(fname, kcontext, filep, verbose, linenop)
24310Sstevel@tonic-gate     char		*fname;
24320Sstevel@tonic-gate     krb5_context	kcontext;
24330Sstevel@tonic-gate     FILE		*filep;
24340Sstevel@tonic-gate     int			verbose;
24350Sstevel@tonic-gate     int			*linenop;
24360Sstevel@tonic-gate {
24370Sstevel@tonic-gate      int nread;
24380Sstevel@tonic-gate      char rectype[100];
24390Sstevel@tonic-gate 
24400Sstevel@tonic-gate      nread = fscanf(filep, "%100s\t", rectype);
24410Sstevel@tonic-gate      if (nread == EOF)
24422881Smp153739 	  return -1;
24430Sstevel@tonic-gate      else if (nread != 1)
24442881Smp153739 	  return 1;
24450Sstevel@tonic-gate      if (strcmp(rectype, "princ") == 0)
24460Sstevel@tonic-gate 	  process_k5beta6_record(fname, kcontext, filep, verbose,
24474960Swillf 				 linenop);
24480Sstevel@tonic-gate      else if (strcmp(rectype, "policy") == 0)
24490Sstevel@tonic-gate 	  process_k5beta7_policy(fname, kcontext, filep, verbose,
24504960Swillf 				 linenop);
24510Sstevel@tonic-gate      else {
24520Sstevel@tonic-gate 		fprintf(stderr,
24530Sstevel@tonic-gate 		    gettext("unknown record type \"%s\" on line %d\n"),
24540Sstevel@tonic-gate 		  rectype, *linenop);
24552881Smp153739 	  return 1;
24560Sstevel@tonic-gate      }
24570Sstevel@tonic-gate 
24582881Smp153739      return 0;
24590Sstevel@tonic-gate }
24600Sstevel@tonic-gate 
24610Sstevel@tonic-gate /*
24620Sstevel@tonic-gate  * process_ov_record()	- Handle a dump record in OpenV*Secure 1.0 format.
24630Sstevel@tonic-gate  *
24640Sstevel@tonic-gate  * Returns -1 for end of file, 0 for success and 1 for failure.
24650Sstevel@tonic-gate  */
24660Sstevel@tonic-gate static int
24674960Swillf process_ov_record(fname, kcontext, filep, verbose, linenop)
24680Sstevel@tonic-gate     char		*fname;
24690Sstevel@tonic-gate     krb5_context	kcontext;
24700Sstevel@tonic-gate     FILE		*filep;
24710Sstevel@tonic-gate     int			verbose;
24720Sstevel@tonic-gate     int			*linenop;
24730Sstevel@tonic-gate {
24740Sstevel@tonic-gate      int nread;
24750Sstevel@tonic-gate      char rectype[100];
24760Sstevel@tonic-gate 
24770Sstevel@tonic-gate      nread = fscanf(filep, "%100s\t", rectype);
24780Sstevel@tonic-gate      if (nread == EOF)
24792881Smp153739 	  return -1;
24800Sstevel@tonic-gate      else if (nread != 1)
24812881Smp153739 	  return 1;
24820Sstevel@tonic-gate      if (strcmp(rectype, "princ") == 0)
24830Sstevel@tonic-gate 	  process_ov_principal(fname, kcontext, filep, verbose,
24844960Swillf 			       linenop);
24850Sstevel@tonic-gate      else if (strcmp(rectype, "policy") == 0)
24860Sstevel@tonic-gate 	  process_k5beta7_policy(fname, kcontext, filep, verbose,
24874960Swillf 				 linenop);
24880Sstevel@tonic-gate      else if (strcmp(rectype, "End") == 0)
24892881Smp153739 	  return -1;
24900Sstevel@tonic-gate      else {
24910Sstevel@tonic-gate 		fprintf(stderr,
24920Sstevel@tonic-gate 		    gettext("unknown record type \"%s\" on line %d\n"),
24930Sstevel@tonic-gate 		  rectype, *linenop);
24942881Smp153739 	  return 1;
24950Sstevel@tonic-gate      }
24960Sstevel@tonic-gate 
24972881Smp153739      return 0;
24980Sstevel@tonic-gate }
24990Sstevel@tonic-gate 
25000Sstevel@tonic-gate /*
25010Sstevel@tonic-gate  * restore_dump()	- Restore the database from any version dump file.
25020Sstevel@tonic-gate  */
25030Sstevel@tonic-gate static int
25044960Swillf restore_dump(programname, kcontext, dumpfile, f, verbose, dump)
25050Sstevel@tonic-gate     char		*programname;
25060Sstevel@tonic-gate     krb5_context	kcontext;
25070Sstevel@tonic-gate     char		*dumpfile;
25080Sstevel@tonic-gate     FILE		*f;
25090Sstevel@tonic-gate     int			verbose;
25100Sstevel@tonic-gate     dump_version	*dump;
25110Sstevel@tonic-gate {
25120Sstevel@tonic-gate     int		error;
25130Sstevel@tonic-gate     int		lineno;
25140Sstevel@tonic-gate 
25150Sstevel@tonic-gate     error = 0;
25160Sstevel@tonic-gate     lineno = 1;
25170Sstevel@tonic-gate 
25180Sstevel@tonic-gate     /*
25190Sstevel@tonic-gate      * Process the records.
25200Sstevel@tonic-gate      */
25210Sstevel@tonic-gate     while (!(error = (*dump->load_record)(dumpfile,
25220Sstevel@tonic-gate 					  kcontext,
25230Sstevel@tonic-gate 					  f,
25240Sstevel@tonic-gate 					  verbose,
25254960Swillf 					  &lineno)))
25262881Smp153739 	 ;
25270Sstevel@tonic-gate     if (error != -1)
25280Sstevel@tonic-gate 		fprintf(stderr, gettext(err_line_fmt),
25290Sstevel@tonic-gate 		    programname, lineno, dumpfile);
25300Sstevel@tonic-gate     else
25310Sstevel@tonic-gate 	 error = 0;
25320Sstevel@tonic-gate 
25330Sstevel@tonic-gate     return(error);
25340Sstevel@tonic-gate }
25350Sstevel@tonic-gate 
25360Sstevel@tonic-gate /*
25372881Smp153739  * Usage: load_db [-i] [-old] [-ov] [-b6] [-b7] [-verbose] [-update] [-hash]
25382881Smp153739  *		filename
25390Sstevel@tonic-gate  */
25400Sstevel@tonic-gate void
25410Sstevel@tonic-gate load_db(argc, argv)
25420Sstevel@tonic-gate     int		argc;
25430Sstevel@tonic-gate     char	**argv;
25440Sstevel@tonic-gate {
25450Sstevel@tonic-gate     kadm5_config_params newparams;
25460Sstevel@tonic-gate     krb5_error_code	kret;
25470Sstevel@tonic-gate     krb5_context	kcontext;
25480Sstevel@tonic-gate     FILE		*f;
25490Sstevel@tonic-gate     extern char		*optarg;
25500Sstevel@tonic-gate     extern int		optind;
25510Sstevel@tonic-gate     char		*programname;
25520Sstevel@tonic-gate     char		*dumpfile;
25530Sstevel@tonic-gate     char		*dbname;
25540Sstevel@tonic-gate     char		*dbname_tmp;
25550Sstevel@tonic-gate     char		buf[BUFSIZ];
25560Sstevel@tonic-gate     dump_version	*load;
25570Sstevel@tonic-gate     int			update, verbose;
25580Sstevel@tonic-gate     krb5_int32		crflags;
25590Sstevel@tonic-gate     int			aindex;
25600Sstevel@tonic-gate     bool_t		add_update = TRUE;
25610Sstevel@tonic-gate     char		iheader[MAX_HEADER];
25620Sstevel@tonic-gate     uint32_t		caller, last_sno, last_seconds, last_useconds;
25630Sstevel@tonic-gate     kdb_log_context	*log_ctx;
25644960Swillf     int			db_locked = 0;
25650Sstevel@tonic-gate 
25660Sstevel@tonic-gate     /*
25670Sstevel@tonic-gate      * Parse the arguments.
25680Sstevel@tonic-gate      */
25690Sstevel@tonic-gate     programname = argv[0];
25700Sstevel@tonic-gate     if (strrchr(programname, (int) '/'))
25710Sstevel@tonic-gate 	programname = strrchr(argv[0], (int) '/') + 1;
25720Sstevel@tonic-gate     dumpfile = (char *) NULL;
25730Sstevel@tonic-gate     dbname = global_params.dbname;
25740Sstevel@tonic-gate     load = NULL;
25750Sstevel@tonic-gate     update = 0;
25760Sstevel@tonic-gate     verbose = 0;
25770Sstevel@tonic-gate     crflags = KRB5_KDB_CREATE_BTREE;
25780Sstevel@tonic-gate     exit_status = 0;
25790Sstevel@tonic-gate     dbname_tmp = (char *) NULL;
25800Sstevel@tonic-gate     log_ctx = util_context->kdblog_context;
25810Sstevel@tonic-gate 
25820Sstevel@tonic-gate     for (aindex = 1; aindex < argc; aindex++) {
25832881Smp153739 	if (!strcmp(argv[aindex], oldoption))
25840Sstevel@tonic-gate 	     load = &old_version;
25852881Smp153739 	else if (!strcmp(argv[aindex], b6option))
25860Sstevel@tonic-gate 	     load = &beta6_version;
25872881Smp153739 	else if (!strcmp(argv[aindex], b7option))
25882881Smp153739 	     load = &beta7_version;
25892881Smp153739 	else if (!strcmp(argv[aindex], ovoption))
25900Sstevel@tonic-gate 	     load = &ov_version;
25912881Smp153739 	else if (!strcmp(argv[aindex], ipropoption)) {
25920Sstevel@tonic-gate 			if (log_ctx && log_ctx->iproprole) {
25930Sstevel@tonic-gate 				load = &iprop_version;
25940Sstevel@tonic-gate 				add_update = FALSE;
25950Sstevel@tonic-gate 			} else {
25960Sstevel@tonic-gate 				fprintf(stderr, gettext("Iprop not enabled\n"));
25970Sstevel@tonic-gate 				exit_status++;
25980Sstevel@tonic-gate 				return;
25990Sstevel@tonic-gate 			}
26002881Smp153739 		}
26012881Smp153739 	else if (!strcmp(argv[aindex], verboseoption))
26020Sstevel@tonic-gate 	    verbose = 1;
26032881Smp153739 	else if (!strcmp(argv[aindex], updateoption))
26040Sstevel@tonic-gate 	    update = 1;
26054960Swillf 	else if (!strcmp(argv[aindex], hashoption)) {
26064960Swillf 	    if (!add_db_arg("hash=true")) {
26074960Swillf 		com_err(progname, ENOMEM, "while parsing command arguments\n");
26084960Swillf 		exit(1);
26094960Swillf 	    }
26104960Swillf 	} else
26110Sstevel@tonic-gate 	    break;
26120Sstevel@tonic-gate     }
26130Sstevel@tonic-gate     if ((argc - aindex) != 1) {
26140Sstevel@tonic-gate 	usage();
26150Sstevel@tonic-gate 	return;
26160Sstevel@tonic-gate     }
26170Sstevel@tonic-gate     dumpfile = argv[aindex];
26180Sstevel@tonic-gate 
26190Sstevel@tonic-gate     if (!(dbname_tmp = (char *) malloc(strlen(dbname)+
26200Sstevel@tonic-gate 				       strlen(dump_tmptrail)+1))) {
26210Sstevel@tonic-gate 		fprintf(stderr, gettext(no_name_mem_fmt), argv[0]);
26220Sstevel@tonic-gate 	exit_status++;
26230Sstevel@tonic-gate 	return;
26240Sstevel@tonic-gate     }
26250Sstevel@tonic-gate     strcpy(dbname_tmp, dbname);
26260Sstevel@tonic-gate     strcat(dbname_tmp, dump_tmptrail);
26270Sstevel@tonic-gate 
26280Sstevel@tonic-gate     /*
26290Sstevel@tonic-gate      * Initialize the Kerberos context and error tables.
26300Sstevel@tonic-gate      */
26314960Swillf     if ((kret = kadm5_init_krb5_context(&kcontext))) {
26324960Swillf 	fprintf(stderr, gettext(ctx_err_fmt), programname);
26330Sstevel@tonic-gate 	free(dbname_tmp);
26340Sstevel@tonic-gate 	exit_status++;
26350Sstevel@tonic-gate 	return;
26360Sstevel@tonic-gate     }
26370Sstevel@tonic-gate 
26384960Swillf     if( (kret = krb5_set_default_realm(kcontext, util_context->default_realm)) )
26394960Swillf     {
26404960Swillf 	fprintf(stderr, gettext("%s: Unable to set the default realm\n"), programname);
26414960Swillf 	free(dbname_tmp);
26424960Swillf 	exit_status++;
26434960Swillf 	return;
26444960Swillf     }
26450Sstevel@tonic-gate     if (log_ctx && log_ctx->iproprole)
26460Sstevel@tonic-gate 	kcontext->kdblog_context = (void *)log_ctx;
26470Sstevel@tonic-gate     /*
26480Sstevel@tonic-gate      * Open the dumpfile
26490Sstevel@tonic-gate      */
26500Sstevel@tonic-gate     if (dumpfile) {
26514960Swillf 	if ((f = fopen(dumpfile, "r")) == NULL) {
26520Sstevel@tonic-gate 			fprintf(stderr, gettext(dfile_err_fmt),
26530Sstevel@tonic-gate 			    programname, dumpfile,
26540Sstevel@tonic-gate 		     error_message(errno));
26550Sstevel@tonic-gate 	     exit_status++;
26560Sstevel@tonic-gate 	     return;
26570Sstevel@tonic-gate 	}
26580Sstevel@tonic-gate 	if ((kret = krb5_lock_file(kcontext, fileno(f),
26590Sstevel@tonic-gate 				   KRB5_LOCKMODE_SHARED))) {
26600Sstevel@tonic-gate 	     fprintf(stderr, gettext("%s: Cannot lock %s: %s\n"), programname,
26610Sstevel@tonic-gate 		     dumpfile, error_message(errno));
26620Sstevel@tonic-gate 	     exit_status++;
26630Sstevel@tonic-gate 	     return;
26640Sstevel@tonic-gate 	}
26650Sstevel@tonic-gate     } else
26660Sstevel@tonic-gate 	f = stdin;
26670Sstevel@tonic-gate 
26680Sstevel@tonic-gate     /*
26692881Smp153739      * Auto-detect dump version if we weren't told, verify if we
26702881Smp153739      * were told.
26710Sstevel@tonic-gate      */
26720Sstevel@tonic-gate     fgets(buf, sizeof(buf), f);
26730Sstevel@tonic-gate     if (load) {
26742881Smp153739 	 /* only check what we know; some headers only contain a prefix */
26750Sstevel@tonic-gate 	 if (strncmp(buf, load->header, strlen(load->header)) != 0) {
26762881Smp153739 			fprintf(stderr, gettext(head_bad_fmt), programname, dumpfile);
26770Sstevel@tonic-gate 	      exit_status++;
26782881Smp153739 	      if (dumpfile) fclose(f);
26790Sstevel@tonic-gate 	      return;
26800Sstevel@tonic-gate 	 }
26810Sstevel@tonic-gate     } else {
26820Sstevel@tonic-gate 	 /* perhaps this should be in an array, but so what? */
26830Sstevel@tonic-gate 	 if (strcmp(buf, old_version.header) == 0)
26840Sstevel@tonic-gate 	      load = &old_version;
26850Sstevel@tonic-gate 	 else if (strcmp(buf, beta6_version.header) == 0)
26860Sstevel@tonic-gate 	      load = &beta6_version;
26870Sstevel@tonic-gate 	 else if (strcmp(buf, beta7_version.header) == 0)
26880Sstevel@tonic-gate 	      load = &beta7_version;
26892881Smp153739 	 else if (strcmp(buf, r1_3_version.header) == 0)
26902881Smp153739 	      load = &r1_3_version;
26910Sstevel@tonic-gate 	 else if (strncmp(buf, ov_version.header,
26920Sstevel@tonic-gate 			  strlen(ov_version.header)) == 0)
26930Sstevel@tonic-gate 	      load = &ov_version;
26942881Smp153739 	 else {
26950Sstevel@tonic-gate 			fprintf(stderr, gettext(head_bad_fmt),
26960Sstevel@tonic-gate 				programname, dumpfile);
26970Sstevel@tonic-gate 	      exit_status++;
26982881Smp153739 	      if (dumpfile) fclose(f);
26990Sstevel@tonic-gate 	      return;
27000Sstevel@tonic-gate 	 }
27010Sstevel@tonic-gate     }
27020Sstevel@tonic-gate     if (load->updateonly && !update) {
27030Sstevel@tonic-gate 		fprintf(stderr,
27040Sstevel@tonic-gate 		    gettext("%s: dump version %s can only "
27050Sstevel@tonic-gate 			"be loaded with the -update flag\n"),
27060Sstevel@tonic-gate 		    programname, load->name);
27070Sstevel@tonic-gate 	 exit_status++;
27080Sstevel@tonic-gate 	 return;
27090Sstevel@tonic-gate     }
27102881Smp153739 
27110Sstevel@tonic-gate     /*
27120Sstevel@tonic-gate      * Cons up params for the new databases.  If we are not in update
27134960Swillf      * mode, we create an alternate database and then promote it to
27144960Swillf      * be the live db.
27150Sstevel@tonic-gate      */
27160Sstevel@tonic-gate     newparams = global_params;
27170Sstevel@tonic-gate     if (! update) {
27180Sstevel@tonic-gate 	 newparams.mask |= KADM5_CONFIG_DBNAME;
27190Sstevel@tonic-gate 	 newparams.dbname = dbname_tmp;
27200Sstevel@tonic-gate 
2721*7934SMark.Phalan@Sun.COM 	 if ((kret = kadm5_get_config_params(kcontext, 1,
27220Sstevel@tonic-gate 					     &newparams, &newparams))) {
27230Sstevel@tonic-gate 	      com_err(argv[0], kret,
27240Sstevel@tonic-gate 			    gettext("while retreiving new "
27250Sstevel@tonic-gate 				"configuration parameters"));
27260Sstevel@tonic-gate 	      exit_status++;
27270Sstevel@tonic-gate 	      return;
27280Sstevel@tonic-gate 	 }
27294960Swillf 
27304960Swillf 	 if (!add_db_arg("temporary")) {
27314960Swillf 	     com_err(progname, ENOMEM, "computing parameters for database");
27324960Swillf 	     exit(1);
27334960Swillf 	 }
27340Sstevel@tonic-gate     }
27352881Smp153739 
27360Sstevel@tonic-gate     /*
27374960Swillf      * If not an update restoration, create the database. otherwise open
27380Sstevel@tonic-gate      */
27394960Swillf     if (!update) {
27404960Swillf 	if((kret = krb5_db_create(kcontext, db5util_db_args))) {
27414960Swillf 	    const char *emsg = krb5_get_error_message(kcontext, kret);
27424960Swillf 	    /*
27434960Swillf 	     * See if something (like DAL KDB plugin) has set a specific error
27444960Swillf 	     * message and use that otherwise use default.
27454960Swillf 	     */
27464960Swillf 
27474960Swillf 	    if (emsg != NULL) {
27484960Swillf 		fprintf(stderr, "%s: %s\n", programname, emsg);
27494960Swillf 		krb5_free_error_message (kcontext, emsg);
27504960Swillf 	    } else {
27514960Swillf 		fprintf(stderr, dbcreaterr_fmt,
27524960Swillf 			programname, dbname, error_message(kret));
27534960Swillf 	    }
27544960Swillf 	    exit_status++;
27554960Swillf 	    kadm5_free_config_params(kcontext, &newparams);
27564960Swillf 	    if (dumpfile) fclose(f);
27574960Swillf 	    return;
27584960Swillf 	}
27590Sstevel@tonic-gate     }
27604960Swillf     else {
27614960Swillf 	    /*
27624960Swillf 	     * Initialize the database.
27634960Swillf 	     */
27644960Swillf 	    if ((kret = krb5_db_open(kcontext, db5util_db_args,
27654960Swillf 				     KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN))) {
27664960Swillf 		const char *emsg = krb5_get_error_message(kcontext, kret);
27674960Swillf 		/*
27684960Swillf 		 * See if something (like DAL KDB plugin) has set a specific
27694960Swillf 		 * error message and use that otherwise use default.
27704960Swillf 		 */
27714960Swillf 
27724960Swillf 		if (emsg != NULL) {
27734960Swillf 		    fprintf(stderr, "%s: %s\n", programname, emsg);
27744960Swillf 		    krb5_free_error_message (kcontext, emsg);
27754960Swillf 		} else {
27764960Swillf 		    fprintf(stderr, dbinit_err_fmt,
27774960Swillf 			    programname, error_message(kret));
27784960Swillf 		}
27794960Swillf 		exit_status++;
27804960Swillf 		goto error;
27814960Swillf 	    }
27820Sstevel@tonic-gate     }
27832881Smp153739 
27844960Swillf 
27850Sstevel@tonic-gate     /*
27860Sstevel@tonic-gate      * If an update restoration, make sure the db is left unusable if
27870Sstevel@tonic-gate      * the update fails.
27880Sstevel@tonic-gate      */
27894960Swillf     if ((kret = krb5_db_lock(kcontext, update?KRB5_DB_LOCKMODE_PERMANENT: KRB5_DB_LOCKMODE_EXCLUSIVE))) {
27904960Swillf 	/*
27914960Swillf 	 * Ignore a not supported error since there is nothing to do about it
27924960Swillf 	 * anyway.
27934960Swillf 	 */
27944960Swillf 	if (kret != KRB5_PLUGIN_OP_NOTSUPP) {
27954960Swillf 	    fprintf(stderr, gettext("%s: %s while permanently locking database\n"),
27964960Swillf 		    programname, error_message(kret));
27974960Swillf 	    exit_status++;
27984960Swillf 	    goto error;
27994960Swillf 	}
28000Sstevel@tonic-gate     }
28014960Swillf     else
28024960Swillf 	db_locked = 1;
28032881Smp153739 
28040Sstevel@tonic-gate 	if (log_ctx && log_ctx->iproprole) {
28050Sstevel@tonic-gate 		if (add_update)
28060Sstevel@tonic-gate 			caller = FKCOMMAND;
28070Sstevel@tonic-gate 		else
28080Sstevel@tonic-gate 			caller = FKPROPD;
28090Sstevel@tonic-gate 
28100Sstevel@tonic-gate 		if (ulog_map(kcontext, &global_params, caller)) {
28110Sstevel@tonic-gate 			fprintf(stderr,
28120Sstevel@tonic-gate 				gettext("%s: Could not map log\n"),
28130Sstevel@tonic-gate 				programname);
28140Sstevel@tonic-gate 			exit_status++;
28150Sstevel@tonic-gate 			goto error;
28160Sstevel@tonic-gate 		}
28170Sstevel@tonic-gate 
28180Sstevel@tonic-gate 		/*
28190Sstevel@tonic-gate 		 * We don't want to take out the ulog out from underneath
28200Sstevel@tonic-gate 		 * kadmind so we reinit the header log.
28210Sstevel@tonic-gate 		 *
28220Sstevel@tonic-gate 		 * We also don't want to add to the update log since we
28230Sstevel@tonic-gate 		 * are doing a whole sale replace of the db, because:
28240Sstevel@tonic-gate 		 * 	we could easily exceed # of update entries
28250Sstevel@tonic-gate 		 * 	we could implicity delete db entries during a replace
28260Sstevel@tonic-gate 		 *	no advantage in incr updates when entire db is replaced
28270Sstevel@tonic-gate 		 */
28280Sstevel@tonic-gate 		if (!update) {
28290Sstevel@tonic-gate                         memset(log_ctx->ulog, 0, sizeof (kdb_hlog_t));
28300Sstevel@tonic-gate 
28310Sstevel@tonic-gate                         log_ctx->ulog->kdb_hmagic = KDB_HMAGIC;
28320Sstevel@tonic-gate                         log_ctx->ulog->db_version_num = KDB_VERSION;
28330Sstevel@tonic-gate                         log_ctx->ulog->kdb_state = KDB_STABLE;
28340Sstevel@tonic-gate                         log_ctx->ulog->kdb_block = ULOG_BLOCK;
28350Sstevel@tonic-gate 
28360Sstevel@tonic-gate 			log_ctx->iproprole = IPROP_NULL;
28370Sstevel@tonic-gate 
28380Sstevel@tonic-gate 			if (!add_update) {
28390Sstevel@tonic-gate 				sscanf(buf, "%s %u %u %u", iheader, &last_sno,
28400Sstevel@tonic-gate 					&last_seconds, &last_useconds);
28410Sstevel@tonic-gate 
28420Sstevel@tonic-gate 				log_ctx->ulog->kdb_last_sno = last_sno;
28430Sstevel@tonic-gate 				log_ctx->ulog->kdb_last_time.seconds =
28440Sstevel@tonic-gate 				    last_seconds;
28450Sstevel@tonic-gate 				log_ctx->ulog->kdb_last_time.useconds =
28460Sstevel@tonic-gate 				    last_useconds;
28470Sstevel@tonic-gate 			}
28480Sstevel@tonic-gate 		}
28490Sstevel@tonic-gate 	}
28500Sstevel@tonic-gate 
28512881Smp153739     if (restore_dump(programname, kcontext, (dumpfile) ? dumpfile : stdin_name,
28524960Swillf 		     f, verbose, load)) {
28534960Swillf 	 fprintf(stderr, gettext(restfail_fmt),
28540Sstevel@tonic-gate 		 programname, load->name);
28550Sstevel@tonic-gate 	 exit_status++;
28560Sstevel@tonic-gate     }
28572881Smp153739 
28580Sstevel@tonic-gate     if (!update && load->create_kadm5 &&
28592881Smp153739 	((kret = kadm5_create_magic_princs(&newparams, kcontext)))) {
28600Sstevel@tonic-gate 	 /* error message printed by create_magic_princs */
28610Sstevel@tonic-gate 	 exit_status++;
28620Sstevel@tonic-gate     }
28630Sstevel@tonic-gate 
28644960Swillf     if (db_locked && (kret = krb5_db_unlock(kcontext))) {
28654960Swillf 	 /* change this error? */
28664960Swillf 		fprintf(stderr, gettext(dbunlockerr_fmt),
28674960Swillf 		 programname, dbname, error_message(kret));
28684960Swillf 	 exit_status++;
28694960Swillf     }
28704960Swillf 
28714960Swillf #if 0
28724960Swillf     if ((kret = krb5_db_fini(kcontext))) {
28734960Swillf 		fprintf(stderr, gettext(close_err_fmt),
28744960Swillf 		 programname, error_message(kret));
28754960Swillf 	 exit_status++;
28764960Swillf     }
28774960Swillf #endif
28784960Swillf 
28790Sstevel@tonic-gate     /* close policy db below */
28800Sstevel@tonic-gate 
28814960Swillf     if (exit_status == 0 && !update) {
28824960Swillf 	kret = krb5_db_promote(kcontext, db5util_db_args);
28834960Swillf 	/*
28844960Swillf 	 * Ignore a not supported error since there is nothing to do about it
28854960Swillf 	 * anyway.
28864960Swillf 	 */
28874960Swillf 	if (kret != 0 && kret != KRB5_PLUGIN_OP_NOTSUPP) {
28884960Swillf 	    fprintf(stderr, gettext("%s: cannot make newly loaded database live (%s)\n"),
28894960Swillf 		    programname, error_message(kret));
28904960Swillf 	    exit_status++;
28914960Swillf 	}
28924960Swillf     }
28934960Swillf 
28940Sstevel@tonic-gate error:
28950Sstevel@tonic-gate     /*
28962881Smp153739      * If not an update: if there was an error, destroy the temp database,
28972881Smp153739      * otherwise rename it into place.
28980Sstevel@tonic-gate      *
28990Sstevel@tonic-gate      * If an update: if there was no error, unlock the database.
29000Sstevel@tonic-gate      */
29010Sstevel@tonic-gate     if (!update) {
29020Sstevel@tonic-gate 	 if (exit_status) {
29034960Swillf 	      kret = krb5_db_destroy(kcontext, db5util_db_args);
29044960Swillf 	      /*
29054960Swillf 	       * Ignore a not supported error since there is nothing to do about
29064960Swillf 	       * it anyway.
29074960Swillf 	       */
29084960Swillf 	      if (kret != 0 && kret != KRB5_PLUGIN_OP_NOTSUPP) {
29094960Swillf 		   fprintf(stderr, gettext(dbdelerr_fmt),
29104960Swillf 			   programname, dbname, error_message(kret));
29110Sstevel@tonic-gate 		   exit_status++;
29120Sstevel@tonic-gate 	      }
29132881Smp153739 	 }
29140Sstevel@tonic-gate     }
29150Sstevel@tonic-gate 
29160Sstevel@tonic-gate     if (dumpfile) {
29172881Smp153739 	 (void) krb5_lock_file(kcontext, fileno(f), KRB5_LOCKMODE_UNLOCK);
29180Sstevel@tonic-gate 	 fclose(f);
29190Sstevel@tonic-gate     }
29202881Smp153739 
29210Sstevel@tonic-gate     if (dbname_tmp)
29220Sstevel@tonic-gate 	 free(dbname_tmp);
29230Sstevel@tonic-gate     krb5_free_context(kcontext);
29240Sstevel@tonic-gate }
2925