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 ®exp_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