1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3*0Sstevel@tonic-gate * Use is subject to license terms. 4*0Sstevel@tonic-gate */ 5*0Sstevel@tonic-gate 6*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate /* 9*0Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 10*0Sstevel@tonic-gate * 11*0Sstevel@tonic-gate * Openvision retains the copyright to derivative works of 12*0Sstevel@tonic-gate * this source code. Do *NOT* create a derivative of this 13*0Sstevel@tonic-gate * source code before consulting with your legal department. 14*0Sstevel@tonic-gate * Do *NOT* integrate *ANY* of this source code into another 15*0Sstevel@tonic-gate * product before consulting with your legal department. 16*0Sstevel@tonic-gate * 17*0Sstevel@tonic-gate * For further information, read the top-level Openvision 18*0Sstevel@tonic-gate * copyright which is contained in the top-level MIT Kerberos 19*0Sstevel@tonic-gate * copyright. 20*0Sstevel@tonic-gate * 21*0Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 22*0Sstevel@tonic-gate * 23*0Sstevel@tonic-gate */ 24*0Sstevel@tonic-gate 25*0Sstevel@tonic-gate 26*0Sstevel@tonic-gate /* 27*0Sstevel@tonic-gate * admin/edit/dump.c 28*0Sstevel@tonic-gate * 29*0Sstevel@tonic-gate * Copyright 1990,1991 by the Massachusetts Institute of Technology. 30*0Sstevel@tonic-gate * All Rights Reserved. 31*0Sstevel@tonic-gate * 32*0Sstevel@tonic-gate * Export of this software from the United States of America may 33*0Sstevel@tonic-gate * require a specific license from the United States Government. 34*0Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 35*0Sstevel@tonic-gate * export to obtain such a license before exporting. 36*0Sstevel@tonic-gate * 37*0Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 38*0Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 39*0Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 40*0Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 41*0Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 42*0Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 43*0Sstevel@tonic-gate * to distribution of the software without specific, written prior 44*0Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 45*0Sstevel@tonic-gate * your software as modified software and not distribute it in such a 46*0Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 47*0Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 48*0Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 49*0Sstevel@tonic-gate * or implied warranty. 50*0Sstevel@tonic-gate * 51*0Sstevel@tonic-gate * 52*0Sstevel@tonic-gate * Dump a KDC database 53*0Sstevel@tonic-gate */ 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gate #define KDB5_DISPATCH 56*0Sstevel@tonic-gate #define KRB5_KDB5_DBM__ 57*0Sstevel@tonic-gate #include <k5-int.h> 58*0Sstevel@tonic-gate /* #define these to avoid an indirection function; for future implementations, 59*0Sstevel@tonic-gate these may be redirected from a dispatch table/routine */ 60*0Sstevel@tonic-gate /* SUNWresync121 - this appears to be an orig SEAM thang */ 61*0Sstevel@tonic-gate #define krb5_dbm_db_set_name krb5_db_set_name 62*0Sstevel@tonic-gate #define krb5_dbm_db_set_nonblocking krb5_db_set_nonblocking 63*0Sstevel@tonic-gate #define krb5_dbm_db_init krb5_db_init 64*0Sstevel@tonic-gate #define krb5_dbm_db_get_age krb5_db_get_age 65*0Sstevel@tonic-gate #define krb5_dbm_db_create krb5_db_create 66*0Sstevel@tonic-gate #define krb5_dbm_db_rename krb5_db_rename 67*0Sstevel@tonic-gate #define krb5_dbm_db_get_principal krb5_db_get_principal 68*0Sstevel@tonic-gate #define krb5_dbm_db_free_principal krb5_db_free_principal 69*0Sstevel@tonic-gate #define krb5_dbm_db_put_principal krb5_db_put_principal 70*0Sstevel@tonic-gate #define krb5_dbm_db_delete_principal krb5_db_delete_principal 71*0Sstevel@tonic-gate #define krb5_dbm_db_lock krb5_db_lock 72*0Sstevel@tonic-gate #define krb5_dbm_db_unlock krb5_db_unlock 73*0Sstevel@tonic-gate #define krb5_dbm_db_set_lockmode krb5_db_set_lockmode 74*0Sstevel@tonic-gate #define krb5_dbm_db_close_database krb5_db_close_database 75*0Sstevel@tonic-gate #define krb5_dbm_db_open_database krb5_db_open_database 76*0Sstevel@tonic-gate #define krb5_dbm_db_iterate krb5_db_iterate 77*0Sstevel@tonic-gate 78*0Sstevel@tonic-gate #include <stdio.h> 79*0Sstevel@tonic-gate #include <com_err.h> 80*0Sstevel@tonic-gate #include <kadm5/admin.h> 81*0Sstevel@tonic-gate #include <kadm5/adb.h> 82*0Sstevel@tonic-gate #include <libintl.h> 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gate #include "kdb5_util.h" 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate #if HAVE_REGEX_H 87*0Sstevel@tonic-gate #include <regex.h> 88*0Sstevel@tonic-gate #endif /* HAVE_REGEX_H */ 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gate /* 91*0Sstevel@tonic-gate * Needed for master key conversion. 92*0Sstevel@tonic-gate */ 93*0Sstevel@tonic-gate extern krb5_keyblock master_key; 94*0Sstevel@tonic-gate extern krb5_principal master_princ; 95*0Sstevel@tonic-gate extern int valid_master_key; 96*0Sstevel@tonic-gate extern void usage(); 97*0Sstevel@tonic-gate static int mkey_convert; 98*0Sstevel@tonic-gate static krb5_keyblock new_master_key; 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate /* 101*0Sstevel@tonic-gate * Use compile(3) if no regcomp present. 102*0Sstevel@tonic-gate */ 103*0Sstevel@tonic-gate #if !defined(HAVE_REGCOMP) && defined(HAVE_REGEXP_H) 104*0Sstevel@tonic-gate #define INIT char *sp = instring; 105*0Sstevel@tonic-gate #define GETC() (*sp++) 106*0Sstevel@tonic-gate #define PEEKC() (*sp) 107*0Sstevel@tonic-gate #define UNGETC(c) (--sp) 108*0Sstevel@tonic-gate #define RETURN(c) return(c) 109*0Sstevel@tonic-gate #define ERROR(c) 110*0Sstevel@tonic-gate #define RE_BUF_SIZE 1024 111*0Sstevel@tonic-gate #include <regexp.h> 112*0Sstevel@tonic-gate #endif /* !HAVE_REGCOMP && HAVE_REGEXP_H */ 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate struct dump_args { 115*0Sstevel@tonic-gate char *programname; 116*0Sstevel@tonic-gate FILE *ofile; 117*0Sstevel@tonic-gate krb5_context kcontext; 118*0Sstevel@tonic-gate char **names; 119*0Sstevel@tonic-gate int nnames; 120*0Sstevel@tonic-gate int verbose; 121*0Sstevel@tonic-gate }; 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate static krb5_error_code dump_k5beta_iterator 124*0Sstevel@tonic-gate PROTOTYPE((krb5_pointer, 125*0Sstevel@tonic-gate krb5_db_entry *)); 126*0Sstevel@tonic-gate static krb5_error_code dump_k5beta6_iterator 127*0Sstevel@tonic-gate PROTOTYPE((krb5_pointer, 128*0Sstevel@tonic-gate krb5_db_entry *)); 129*0Sstevel@tonic-gate static krb5_error_code dump_iprop_iterator 130*0Sstevel@tonic-gate PROTOTYPE((krb5_pointer, 131*0Sstevel@tonic-gate krb5_db_entry *)); 132*0Sstevel@tonic-gate static krb5_error_code dump_k5beta7_princ 133*0Sstevel@tonic-gate PROTOTYPE((krb5_pointer, 134*0Sstevel@tonic-gate krb5_db_entry *)); 135*0Sstevel@tonic-gate static krb5_error_code dump_iprop_princ 136*0Sstevel@tonic-gate PROTOTYPE((krb5_pointer, 137*0Sstevel@tonic-gate krb5_db_entry *)); 138*0Sstevel@tonic-gate static krb5_error_code dump_ov_princ 139*0Sstevel@tonic-gate PROTOTYPE((krb5_pointer, 140*0Sstevel@tonic-gate krb5_db_entry *)); 141*0Sstevel@tonic-gate static void dump_k5beta7_policy PROTOTYPE((void *, osa_policy_ent_t)); 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gate typedef 144*0Sstevel@tonic-gate krb5_error_code(*dump_func) PROTOTYPE((krb5_pointer, 145*0Sstevel@tonic-gate krb5_db_entry *)); 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gate static int process_k5beta_record 148*0Sstevel@tonic-gate PROTOTYPE((char *, krb5_context, 149*0Sstevel@tonic-gate FILE *, int, int *, void *)); 150*0Sstevel@tonic-gate static int process_k5beta6_record 151*0Sstevel@tonic-gate PROTOTYPE((char *, krb5_context, 152*0Sstevel@tonic-gate FILE *, int, int *, void *)); 153*0Sstevel@tonic-gate static int process_k5beta7_record 154*0Sstevel@tonic-gate PROTOTYPE((char *, krb5_context, 155*0Sstevel@tonic-gate FILE *, int, int *, void *)); 156*0Sstevel@tonic-gate static int process_ov_record 157*0Sstevel@tonic-gate PROTOTYPE((char *, krb5_context, 158*0Sstevel@tonic-gate FILE *, int, int *, void *)); 159*0Sstevel@tonic-gate typedef 160*0Sstevel@tonic-gate krb5_error_code(*load_func) PROTOTYPE((char *, krb5_context, 161*0Sstevel@tonic-gate FILE *, int, int *, void *)); 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate typedef struct _dump_version { 164*0Sstevel@tonic-gate char *name; 165*0Sstevel@tonic-gate char *header; 166*0Sstevel@tonic-gate int updateonly; 167*0Sstevel@tonic-gate int create_kadm5; 168*0Sstevel@tonic-gate dump_func dump_princ; 169*0Sstevel@tonic-gate osa_adb_iter_policy_func dump_policy; 170*0Sstevel@tonic-gate load_func load_record; 171*0Sstevel@tonic-gate } dump_version; 172*0Sstevel@tonic-gate 173*0Sstevel@tonic-gate dump_version old_version = { 174*0Sstevel@tonic-gate "Kerberos version 5 old format", 175*0Sstevel@tonic-gate "kdb5_edit load_dump version 2.0\n", 176*0Sstevel@tonic-gate 0, 177*0Sstevel@tonic-gate 1, 178*0Sstevel@tonic-gate dump_k5beta_iterator, 179*0Sstevel@tonic-gate NULL, 180*0Sstevel@tonic-gate process_k5beta_record, 181*0Sstevel@tonic-gate }; 182*0Sstevel@tonic-gate dump_version beta6_version = { 183*0Sstevel@tonic-gate "Kerberos version 5 beta 6 format", 184*0Sstevel@tonic-gate "kdb5_edit load_dump version 3.0\n", 185*0Sstevel@tonic-gate 0, 186*0Sstevel@tonic-gate 1, 187*0Sstevel@tonic-gate dump_k5beta6_iterator, 188*0Sstevel@tonic-gate NULL, 189*0Sstevel@tonic-gate process_k5beta6_record, 190*0Sstevel@tonic-gate }; 191*0Sstevel@tonic-gate dump_version beta7_version = { 192*0Sstevel@tonic-gate "Kerberos version 5", 193*0Sstevel@tonic-gate "kdb5_util load_dump version 4\n", 194*0Sstevel@tonic-gate 0, 195*0Sstevel@tonic-gate 0, 196*0Sstevel@tonic-gate dump_k5beta7_princ, 197*0Sstevel@tonic-gate dump_k5beta7_policy, 198*0Sstevel@tonic-gate process_k5beta7_record, 199*0Sstevel@tonic-gate }; 200*0Sstevel@tonic-gate dump_version iprop_version = { 201*0Sstevel@tonic-gate "Kerberos iprop version", 202*0Sstevel@tonic-gate "iprop", 203*0Sstevel@tonic-gate 0, 204*0Sstevel@tonic-gate 0, 205*0Sstevel@tonic-gate dump_iprop_princ, 206*0Sstevel@tonic-gate dump_k5beta7_policy, 207*0Sstevel@tonic-gate process_k5beta7_record, 208*0Sstevel@tonic-gate }; 209*0Sstevel@tonic-gate dump_version ov_version = { 210*0Sstevel@tonic-gate "OpenV*Secure V1.0", 211*0Sstevel@tonic-gate "OpenV*Secure V1.0\t", 212*0Sstevel@tonic-gate 1, 213*0Sstevel@tonic-gate 1, 214*0Sstevel@tonic-gate dump_ov_princ, 215*0Sstevel@tonic-gate dump_k5beta7_policy, 216*0Sstevel@tonic-gate process_ov_record, 217*0Sstevel@tonic-gate }; 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate /* External data */ 220*0Sstevel@tonic-gate extern char *current_dbname; 221*0Sstevel@tonic-gate extern krb5_boolean dbactive; 222*0Sstevel@tonic-gate extern int exit_status; 223*0Sstevel@tonic-gate extern krb5_context util_context; 224*0Sstevel@tonic-gate extern kadm5_config_params global_params; 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate /* Strings */ 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gate static const char k5beta_dump_header[] = "kdb5_edit load_dump version 2.0\n"; 229*0Sstevel@tonic-gate static const char k5beta6_dump_header[] = "kdb5_edit load_dump version 3.0\n"; 230*0Sstevel@tonic-gate static const char k5beta7_dump_header[] = "kdb5_edit load_dump version 4\n"; 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gate static const char null_mprinc_name[] = "kdb5_dump@MISSING"; 233*0Sstevel@tonic-gate 234*0Sstevel@tonic-gate /* 235*0Sstevel@tonic-gate * We define gettext(s) to be s here, so that xgettext will extract the 236*0Sstevel@tonic-gate * strings to the .po file. At the end of the message section we will 237*0Sstevel@tonic-gate * undef gettext so that we can use it as a funtion. 238*0Sstevel@tonic-gate */ 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gate #define gettext(s) s 241*0Sstevel@tonic-gate 242*0Sstevel@tonic-gate /* Message strings */ 243*0Sstevel@tonic-gate static const char regex_err[] = 244*0Sstevel@tonic-gate gettext("%s: regular expression error - %s\n"); 245*0Sstevel@tonic-gate static const char regex_merr[] = 246*0Sstevel@tonic-gate gettext("%s: regular expression match error - %s\n"); 247*0Sstevel@tonic-gate static const char pname_unp_err[] = 248*0Sstevel@tonic-gate gettext("%s: cannot unparse principal name (%s)\n"); 249*0Sstevel@tonic-gate static const char mname_unp_err[] = 250*0Sstevel@tonic-gate gettext("%s: cannot unparse modifier name (%s)\n"); 251*0Sstevel@tonic-gate static const char nokeys_err[] = 252*0Sstevel@tonic-gate gettext("%s: cannot find any standard key for %s\n"); 253*0Sstevel@tonic-gate static const char sdump_tl_inc_err[] = 254*0Sstevel@tonic-gate gettext("%s: tagged data list inconsistency for %s " 255*0Sstevel@tonic-gate "(counted %d, stored %d)\n"); 256*0Sstevel@tonic-gate static const char stand_fmt_name[] = 257*0Sstevel@tonic-gate gettext("Kerberos version 5"); 258*0Sstevel@tonic-gate static const char old_fmt_name[] = 259*0Sstevel@tonic-gate gettext("Kerberos version 5 old format"); 260*0Sstevel@tonic-gate static const char b6_fmt_name[] = 261*0Sstevel@tonic-gate gettext("Kerberos version 5 beta 6 format"); 262*0Sstevel@tonic-gate static const char ofopen_error[] = 263*0Sstevel@tonic-gate gettext("%s: cannot open %s for writing (%s)\n"); 264*0Sstevel@tonic-gate static const char oflock_error[] = 265*0Sstevel@tonic-gate gettext("%s: cannot lock %s (%s)\n"); 266*0Sstevel@tonic-gate static const char dumprec_err[] = 267*0Sstevel@tonic-gate gettext("%s: error performing %s dump (%s)\n"); 268*0Sstevel@tonic-gate static const char dumphdr_err[] = 269*0Sstevel@tonic-gate gettext("%s: error dumping %s header (%s)\n"); 270*0Sstevel@tonic-gate static const char trash_end_fmt[] = 271*0Sstevel@tonic-gate gettext("%s(%d): ignoring trash at end of line: "); 272*0Sstevel@tonic-gate static const char read_name_string[] = 273*0Sstevel@tonic-gate gettext("name string"); 274*0Sstevel@tonic-gate static const char read_key_type[] = 275*0Sstevel@tonic-gate gettext("key type"); 276*0Sstevel@tonic-gate static const char read_key_data[] = 277*0Sstevel@tonic-gate gettext("key data"); 278*0Sstevel@tonic-gate static const char read_pr_data1[] = 279*0Sstevel@tonic-gate gettext("first set of principal attributes"); 280*0Sstevel@tonic-gate static const char read_mod_name[] = 281*0Sstevel@tonic-gate gettext("modifier name"); 282*0Sstevel@tonic-gate static const char read_pr_data2[] = 283*0Sstevel@tonic-gate gettext("second set of principal attributes"); 284*0Sstevel@tonic-gate static const char read_salt_data[] = 285*0Sstevel@tonic-gate gettext("salt data"); 286*0Sstevel@tonic-gate static const char read_akey_type[] = 287*0Sstevel@tonic-gate gettext("alternate key type"); 288*0Sstevel@tonic-gate static const char read_akey_data[] = 289*0Sstevel@tonic-gate gettext("alternate key data"); 290*0Sstevel@tonic-gate static const char read_asalt_type[] = 291*0Sstevel@tonic-gate gettext("alternate salt type"); 292*0Sstevel@tonic-gate static const char read_asalt_data[] = 293*0Sstevel@tonic-gate gettext("alternate salt data"); 294*0Sstevel@tonic-gate static const char read_exp_data[] = 295*0Sstevel@tonic-gate gettext("expansion data"); 296*0Sstevel@tonic-gate static const char store_err_fmt[] = 297*0Sstevel@tonic-gate gettext("%s(%d): cannot store %s(%s)\n"); 298*0Sstevel@tonic-gate static const char add_princ_fmt[] = 299*0Sstevel@tonic-gate gettext("%s\n"); 300*0Sstevel@tonic-gate static const char parse_err_fmt[] = 301*0Sstevel@tonic-gate gettext("%s(%d): cannot parse %s (%s)\n"); 302*0Sstevel@tonic-gate static const char read_err_fmt[] = 303*0Sstevel@tonic-gate gettext("%s(%d): cannot read %s\n"); 304*0Sstevel@tonic-gate static const char no_mem_fmt[] = 305*0Sstevel@tonic-gate gettext("%s(%d): no memory for buffers\n"); 306*0Sstevel@tonic-gate static const char rhead_err_fmt[] = 307*0Sstevel@tonic-gate gettext("%s(%d): cannot match size tokens\n"); 308*0Sstevel@tonic-gate static const char err_line_fmt[] = 309*0Sstevel@tonic-gate gettext("%s: error processing line %d of %s\n"); 310*0Sstevel@tonic-gate static const char head_bad_fmt[] = 311*0Sstevel@tonic-gate gettext("%s: dump header bad in %s\n"); 312*0Sstevel@tonic-gate static const char read_bytecnt[] = 313*0Sstevel@tonic-gate gettext("record byte count"); 314*0Sstevel@tonic-gate static const char read_encdata[] = 315*0Sstevel@tonic-gate gettext("encoded data"); 316*0Sstevel@tonic-gate static const char n_name_unp_fmt[] = 317*0Sstevel@tonic-gate gettext("%s(%s): cannot unparse name\n"); 318*0Sstevel@tonic-gate static const char n_dec_cont_fmt[] = 319*0Sstevel@tonic-gate gettext("%s(%s): cannot decode contents\n"); 320*0Sstevel@tonic-gate static const char read_nint_data[] = 321*0Sstevel@tonic-gate gettext("principal static attributes"); 322*0Sstevel@tonic-gate static const char read_tcontents[] = 323*0Sstevel@tonic-gate gettext("tagged data contents"); 324*0Sstevel@tonic-gate static const char read_ttypelen[] = 325*0Sstevel@tonic-gate gettext("tagged data type and length"); 326*0Sstevel@tonic-gate static const char read_kcontents[] = 327*0Sstevel@tonic-gate gettext("key data contents"); 328*0Sstevel@tonic-gate static const char read_ktypelen[] = 329*0Sstevel@tonic-gate gettext("key data type and length"); 330*0Sstevel@tonic-gate static const char read_econtents[] = 331*0Sstevel@tonic-gate gettext("extra data contents"); 332*0Sstevel@tonic-gate static const char k5beta_fmt_name[] = 333*0Sstevel@tonic-gate gettext("Kerberos version 5 old format"); 334*0Sstevel@tonic-gate static const char standard_fmt_name[] = 335*0Sstevel@tonic-gate gettext("Kerberos version 5 format"); 336*0Sstevel@tonic-gate static const char no_name_mem_fmt[] = 337*0Sstevel@tonic-gate gettext("%s: cannot get memory for temporary name\n"); 338*0Sstevel@tonic-gate static const char ctx_err_fmt[] = 339*0Sstevel@tonic-gate gettext("%s: cannot initialize Kerberos context\n"); 340*0Sstevel@tonic-gate static const char stdin_name[] = 341*0Sstevel@tonic-gate gettext("standard input"); 342*0Sstevel@tonic-gate static const char remaster_err_fmt[] = 343*0Sstevel@tonic-gate gettext("while re-encoding keys for principal %s with new master key"); 344*0Sstevel@tonic-gate static const char restfail_fmt[] = 345*0Sstevel@tonic-gate gettext("%s: %s restore failed\n"); 346*0Sstevel@tonic-gate static const char close_err_fmt[] = 347*0Sstevel@tonic-gate gettext("%s: cannot close database (%s)\n"); 348*0Sstevel@tonic-gate static const char dbinit_err_fmt[] = 349*0Sstevel@tonic-gate gettext("%s: cannot initialize database (%s)\n"); 350*0Sstevel@tonic-gate static const char dblock_err_fmt[] = 351*0Sstevel@tonic-gate gettext("%s: cannot initialize database lock (%s)\n"); 352*0Sstevel@tonic-gate static const char dbname_err_fmt[] = 353*0Sstevel@tonic-gate gettext("%s: cannot set database name to %s (%s)\n"); 354*0Sstevel@tonic-gate static const char dbdelerr_fmt[] = 355*0Sstevel@tonic-gate gettext("%s: cannot delete bad database %s (%s)\n"); 356*0Sstevel@tonic-gate static const char dbunlockerr_fmt[] = 357*0Sstevel@tonic-gate gettext("%s: cannot unlock database %s (%s)\n"); 358*0Sstevel@tonic-gate static const char dbrenerr_fmt[] = 359*0Sstevel@tonic-gate gettext("%s: cannot rename database %s to %s (%s)\n"); 360*0Sstevel@tonic-gate static const char dbcreaterr_fmt[] = 361*0Sstevel@tonic-gate gettext("%s: cannot create database %s (%s)\n"); 362*0Sstevel@tonic-gate static const char dfile_err_fmt[] = 363*0Sstevel@tonic-gate gettext("%s: cannot open %s (%s)\n"); 364*0Sstevel@tonic-gate 365*0Sstevel@tonic-gate /* 366*0Sstevel@tonic-gate * We now return you to your regularly scheduled program. 367*0Sstevel@tonic-gate */ 368*0Sstevel@tonic-gate #undef gettext 369*0Sstevel@tonic-gate 370*0Sstevel@tonic-gate static const char oldoption[] = "-old"; 371*0Sstevel@tonic-gate static const char b6option[] = "-b6"; 372*0Sstevel@tonic-gate static const char ipropoption[] = "-i"; 373*0Sstevel@tonic-gate static const char verboseoption[] = "-verbose"; 374*0Sstevel@tonic-gate static const char updateoption[] = "-update"; 375*0Sstevel@tonic-gate static const char hashoption[] = "-hash"; 376*0Sstevel@tonic-gate static const char ovoption[] = "-ov"; 377*0Sstevel@tonic-gate static const char dump_tmptrail[] = "~"; 378*0Sstevel@tonic-gate 379*0Sstevel@tonic-gate /* 380*0Sstevel@tonic-gate * Re-encrypt the key_data with the new master key... 381*0Sstevel@tonic-gate */ 382*0Sstevel@tonic-gate krb5_error_code master_key_convert(context, db_entry) 383*0Sstevel@tonic-gate krb5_context context; 384*0Sstevel@tonic-gate krb5_db_entry * db_entry; 385*0Sstevel@tonic-gate { 386*0Sstevel@tonic-gate krb5_error_code retval; 387*0Sstevel@tonic-gate krb5_keyblock v5plainkey, *key_ptr; 388*0Sstevel@tonic-gate krb5_keysalt keysalt; 389*0Sstevel@tonic-gate int i; 390*0Sstevel@tonic-gate krb5_key_data new_key_data, *key_data; 391*0Sstevel@tonic-gate krb5_boolean is_mkey; 392*0Sstevel@tonic-gate 393*0Sstevel@tonic-gate is_mkey = krb5_principal_compare(context, master_princ, db_entry->princ); 394*0Sstevel@tonic-gate 395*0Sstevel@tonic-gate if (is_mkey && db_entry->n_key_data != 1) 396*0Sstevel@tonic-gate fprintf(stderr, 397*0Sstevel@tonic-gate gettext( 398*0Sstevel@tonic-gate "Master key db entry has %d keys, expecting only 1!\n"), 399*0Sstevel@tonic-gate db_entry->n_key_data); 400*0Sstevel@tonic-gate for (i=0; i < db_entry->n_key_data; i++) { 401*0Sstevel@tonic-gate key_data = &db_entry->key_data[i]; 402*0Sstevel@tonic-gate if (key_data->key_data_length == 0) 403*0Sstevel@tonic-gate continue; 404*0Sstevel@tonic-gate retval = krb5_dbekd_decrypt_key_data(context, &master_key, 405*0Sstevel@tonic-gate key_data, &v5plainkey, 406*0Sstevel@tonic-gate &keysalt); 407*0Sstevel@tonic-gate if (retval) 408*0Sstevel@tonic-gate return retval; 409*0Sstevel@tonic-gate 410*0Sstevel@tonic-gate memset(&new_key_data, 0, sizeof(new_key_data)); 411*0Sstevel@tonic-gate key_ptr = is_mkey ? &new_master_key : &v5plainkey; 412*0Sstevel@tonic-gate retval = krb5_dbekd_encrypt_key_data(context, &new_master_key, 413*0Sstevel@tonic-gate key_ptr, &keysalt, 414*0Sstevel@tonic-gate key_data->key_data_kvno, 415*0Sstevel@tonic-gate &new_key_data); 416*0Sstevel@tonic-gate if (retval) 417*0Sstevel@tonic-gate return retval; 418*0Sstevel@tonic-gate krb5_free_keyblock_contents(context, &v5plainkey); 419*0Sstevel@tonic-gate free(key_data->key_data_contents); 420*0Sstevel@tonic-gate *key_data = new_key_data; 421*0Sstevel@tonic-gate } 422*0Sstevel@tonic-gate return 0; 423*0Sstevel@tonic-gate } 424*0Sstevel@tonic-gate 425*0Sstevel@tonic-gate /* 426*0Sstevel@tonic-gate * Update the "ok" file. 427*0Sstevel@tonic-gate */ 428*0Sstevel@tonic-gate void 429*0Sstevel@tonic-gate update_ok_file(file_name) 430*0Sstevel@tonic-gate char *file_name; 431*0Sstevel@tonic-gate { 432*0Sstevel@tonic-gate /* handle slave locking/failure stuff */ 433*0Sstevel@tonic-gate char *file_ok; 434*0Sstevel@tonic-gate int fd; 435*0Sstevel@tonic-gate static char ok[]=".dump_ok"; 436*0Sstevel@tonic-gate 437*0Sstevel@tonic-gate if ((file_ok = (char *)malloc(strlen(file_name) + strlen(ok) + 1)) 438*0Sstevel@tonic-gate == NULL) { 439*0Sstevel@tonic-gate com_err(progname, ENOMEM, 440*0Sstevel@tonic-gate gettext("while allocating filename " 441*0Sstevel@tonic-gate "for update_ok_file")); 442*0Sstevel@tonic-gate exit_status++; 443*0Sstevel@tonic-gate return; 444*0Sstevel@tonic-gate } 445*0Sstevel@tonic-gate strcpy(file_ok, file_name); 446*0Sstevel@tonic-gate strcat(file_ok, ok); 447*0Sstevel@tonic-gate if ((fd = open(file_ok, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) { 448*0Sstevel@tonic-gate com_err(progname, errno, 449*0Sstevel@tonic-gate gettext("while creating 'ok' file, '%s'"), 450*0Sstevel@tonic-gate file_ok); 451*0Sstevel@tonic-gate exit_status++; 452*0Sstevel@tonic-gate free(file_ok); 453*0Sstevel@tonic-gate return; 454*0Sstevel@tonic-gate } 455*0Sstevel@tonic-gate if (write(fd, "", 1) != 1) { 456*0Sstevel@tonic-gate com_err(progname, errno, 457*0Sstevel@tonic-gate gettext("while writing to 'ok' file, '%s'"), 458*0Sstevel@tonic-gate file_ok); 459*0Sstevel@tonic-gate exit_status++; 460*0Sstevel@tonic-gate free(file_ok); 461*0Sstevel@tonic-gate return; 462*0Sstevel@tonic-gate } 463*0Sstevel@tonic-gate free(file_ok); 464*0Sstevel@tonic-gate close(fd); 465*0Sstevel@tonic-gate } 466*0Sstevel@tonic-gate 467*0Sstevel@tonic-gate /* 468*0Sstevel@tonic-gate * name_matches() - See if a principal name matches a regular expression 469*0Sstevel@tonic-gate * or string. 470*0Sstevel@tonic-gate */ 471*0Sstevel@tonic-gate static int 472*0Sstevel@tonic-gate name_matches(name, arglist) 473*0Sstevel@tonic-gate char *name; 474*0Sstevel@tonic-gate struct dump_args *arglist; 475*0Sstevel@tonic-gate { 476*0Sstevel@tonic-gate #if HAVE_REGCOMP 477*0Sstevel@tonic-gate regex_t match_exp; 478*0Sstevel@tonic-gate regmatch_t match_match; 479*0Sstevel@tonic-gate int match_error; 480*0Sstevel@tonic-gate char match_errmsg[BUFSIZ]; 481*0Sstevel@tonic-gate size_t errmsg_size; 482*0Sstevel@tonic-gate 483*0Sstevel@tonic-gate #elif HAVE_REGEXP_H 484*0Sstevel@tonic-gate char regexp_buffer[RE_BUF_SIZE]; 485*0Sstevel@tonic-gate 486*0Sstevel@tonic-gate #elif HAVE_RE_COMP 487*0Sstevel@tonic-gate extern char *re_comp(); 488*0Sstevel@tonic-gate char *re_result; 489*0Sstevel@tonic-gate 490*0Sstevel@tonic-gate #endif /* HAVE_RE_COMP */ 491*0Sstevel@tonic-gate int i, match; 492*0Sstevel@tonic-gate 493*0Sstevel@tonic-gate /* 494*0Sstevel@tonic-gate * Plow, brute force, through the list of names/regular 495*0Sstevel@tonic-gate * expressions. 496*0Sstevel@tonic-gate */ 497*0Sstevel@tonic-gate match = (arglist->nnames) ? 0 : 1; 498*0Sstevel@tonic-gate for (i=0; i<arglist->nnames; i++) { 499*0Sstevel@tonic-gate #if HAVE_REGCOMP 500*0Sstevel@tonic-gate /* 501*0Sstevel@tonic-gate * Compile the regular expression. 502*0Sstevel@tonic-gate */ 503*0Sstevel@tonic-gate if (match_error = regcomp(&match_exp, 504*0Sstevel@tonic-gate arglist->names[i], 505*0Sstevel@tonic-gate REG_EXTENDED)) { 506*0Sstevel@tonic-gate errmsg_size = regerror(match_error, 507*0Sstevel@tonic-gate &match_exp, 508*0Sstevel@tonic-gate match_errmsg, 509*0Sstevel@tonic-gate sizeof(match_errmsg)); 510*0Sstevel@tonic-gate fprintf(stderr, gettext(regex_err), 511*0Sstevel@tonic-gate arglist->programname, match_errmsg); 512*0Sstevel@tonic-gate break; 513*0Sstevel@tonic-gate } 514*0Sstevel@tonic-gate /* 515*0Sstevel@tonic-gate * See if we have a match. 516*0Sstevel@tonic-gate */ 517*0Sstevel@tonic-gate if (match_error = regexec(&match_exp, 518*0Sstevel@tonic-gate name, 1, &match_match, 0)) { 519*0Sstevel@tonic-gate if (match_error != REG_NOMATCH) { 520*0Sstevel@tonic-gate errmsg_size = regerror(match_error, 521*0Sstevel@tonic-gate &match_exp, 522*0Sstevel@tonic-gate match_errmsg, 523*0Sstevel@tonic-gate sizeof(match_errmsg)); 524*0Sstevel@tonic-gate fprintf(stderr, gettext(regex_merr), 525*0Sstevel@tonic-gate arglist->programname, match_errmsg); 526*0Sstevel@tonic-gate break; 527*0Sstevel@tonic-gate } 528*0Sstevel@tonic-gate } else { 529*0Sstevel@tonic-gate /* 530*0Sstevel@tonic-gate * We have a match. See if it matches the whole 531*0Sstevel@tonic-gate * name. 532*0Sstevel@tonic-gate */ 533*0Sstevel@tonic-gate if ((match_match.rm_so == 0) && 534*0Sstevel@tonic-gate (match_match.rm_eo == strlen(name))) 535*0Sstevel@tonic-gate match = 1; 536*0Sstevel@tonic-gate } 537*0Sstevel@tonic-gate regfree(&match_exp); 538*0Sstevel@tonic-gate #elif HAVE_REGEXP_H 539*0Sstevel@tonic-gate /* 540*0Sstevel@tonic-gate * Compile the regular expression. 541*0Sstevel@tonic-gate */ 542*0Sstevel@tonic-gate compile(arglist->names[i], 543*0Sstevel@tonic-gate regexp_buffer, 544*0Sstevel@tonic-gate ®exp_buffer[RE_BUF_SIZE], 545*0Sstevel@tonic-gate '\0'); 546*0Sstevel@tonic-gate if (step(name, regexp_buffer)) { 547*0Sstevel@tonic-gate if ((loc1 == name) && 548*0Sstevel@tonic-gate (loc2 == &name[strlen(name)])) 549*0Sstevel@tonic-gate match = 1; 550*0Sstevel@tonic-gate } 551*0Sstevel@tonic-gate #elif HAVE_RE_COMP 552*0Sstevel@tonic-gate /* 553*0Sstevel@tonic-gate * Compile the regular expression. 554*0Sstevel@tonic-gate */ 555*0Sstevel@tonic-gate if (re_result = re_comp(arglist->names[i])) { 556*0Sstevel@tonic-gate fprintf(stderr, gettext(regex_err), 557*0Sstevel@tonic-gate arglist->programname, re_result); 558*0Sstevel@tonic-gate break; 559*0Sstevel@tonic-gate } 560*0Sstevel@tonic-gate if (re_exec(name)) 561*0Sstevel@tonic-gate match = 1; 562*0Sstevel@tonic-gate #else /* HAVE_RE_COMP */ 563*0Sstevel@tonic-gate /* 564*0Sstevel@tonic-gate * If no regular expression support, then just compare the 565*0Sstevel@tonic-gate * strings. 566*0Sstevel@tonic-gate */ 567*0Sstevel@tonic-gate if (strcmp(arglist->names[i], name) == 0) 568*0Sstevel@tonic-gate match = 1; 569*0Sstevel@tonic-gate #endif /* HAVE_REGCOMP */ 570*0Sstevel@tonic-gate if (match) 571*0Sstevel@tonic-gate break; 572*0Sstevel@tonic-gate } 573*0Sstevel@tonic-gate return(match); 574*0Sstevel@tonic-gate } 575*0Sstevel@tonic-gate 576*0Sstevel@tonic-gate static krb5_error_code 577*0Sstevel@tonic-gate find_enctype(dbentp, enctype, salttype, kentp) 578*0Sstevel@tonic-gate krb5_db_entry *dbentp; 579*0Sstevel@tonic-gate krb5_enctype enctype; 580*0Sstevel@tonic-gate krb5_int32 salttype; 581*0Sstevel@tonic-gate krb5_key_data **kentp; 582*0Sstevel@tonic-gate { 583*0Sstevel@tonic-gate int i; 584*0Sstevel@tonic-gate int maxkvno; 585*0Sstevel@tonic-gate krb5_key_data *datap; 586*0Sstevel@tonic-gate 587*0Sstevel@tonic-gate maxkvno = -1; 588*0Sstevel@tonic-gate datap = (krb5_key_data *) NULL; 589*0Sstevel@tonic-gate for (i=0; i<dbentp->n_key_data; i++) { 590*0Sstevel@tonic-gate if (( (krb5_enctype)dbentp->key_data[i].key_data_type[0] == enctype) && 591*0Sstevel@tonic-gate ((dbentp->key_data[i].key_data_type[1] == salttype) || 592*0Sstevel@tonic-gate (salttype < 0))) { 593*0Sstevel@tonic-gate maxkvno = dbentp->key_data[i].key_data_kvno; 594*0Sstevel@tonic-gate datap = &dbentp->key_data[i]; 595*0Sstevel@tonic-gate } 596*0Sstevel@tonic-gate } 597*0Sstevel@tonic-gate if (maxkvno >= 0) { 598*0Sstevel@tonic-gate *kentp = datap; 599*0Sstevel@tonic-gate return(0); 600*0Sstevel@tonic-gate } 601*0Sstevel@tonic-gate return(ENOENT); 602*0Sstevel@tonic-gate } 603*0Sstevel@tonic-gate 604*0Sstevel@tonic-gate /* 605*0Sstevel@tonic-gate * dump_k5beta_header() - Make a dump header that is recognizable by Kerberos 606*0Sstevel@tonic-gate * Version 5 Beta 5 and previous releases. 607*0Sstevel@tonic-gate */ 608*0Sstevel@tonic-gate static krb5_error_code 609*0Sstevel@tonic-gate dump_k5beta_header(arglist) 610*0Sstevel@tonic-gate struct dump_args *arglist; 611*0Sstevel@tonic-gate { 612*0Sstevel@tonic-gate /* The old header consists of the leading string */ 613*0Sstevel@tonic-gate fprintf(arglist->ofile, k5beta_dump_header); 614*0Sstevel@tonic-gate return(0); 615*0Sstevel@tonic-gate } 616*0Sstevel@tonic-gate 617*0Sstevel@tonic-gate /* 618*0Sstevel@tonic-gate * dump_k5beta_iterator() - Dump an entry in a format that is usable 619*0Sstevel@tonic-gate * by Kerberos Version 5 Beta 5 and previous 620*0Sstevel@tonic-gate * releases. 621*0Sstevel@tonic-gate */ 622*0Sstevel@tonic-gate static krb5_error_code 623*0Sstevel@tonic-gate dump_k5beta_iterator(ptr, entry) 624*0Sstevel@tonic-gate krb5_pointer ptr; 625*0Sstevel@tonic-gate krb5_db_entry *entry; 626*0Sstevel@tonic-gate { 627*0Sstevel@tonic-gate krb5_error_code retval; 628*0Sstevel@tonic-gate struct dump_args *arg; 629*0Sstevel@tonic-gate char *name, *mod_name; 630*0Sstevel@tonic-gate krb5_principal mod_princ; 631*0Sstevel@tonic-gate krb5_key_data *pkey, *akey, nullkey; 632*0Sstevel@tonic-gate krb5_timestamp mod_date, last_pwd_change; 633*0Sstevel@tonic-gate int i; 634*0Sstevel@tonic-gate 635*0Sstevel@tonic-gate /* Initialize */ 636*0Sstevel@tonic-gate arg = (struct dump_args *) ptr; 637*0Sstevel@tonic-gate name = (char *) NULL; 638*0Sstevel@tonic-gate mod_name = (char *) NULL; 639*0Sstevel@tonic-gate memset(&nullkey, 0, sizeof(nullkey)); 640*0Sstevel@tonic-gate 641*0Sstevel@tonic-gate /* 642*0Sstevel@tonic-gate * Flatten the principal name. 643*0Sstevel@tonic-gate */ 644*0Sstevel@tonic-gate if ((retval = krb5_unparse_name(arg->kcontext, 645*0Sstevel@tonic-gate entry->princ, 646*0Sstevel@tonic-gate &name))) { 647*0Sstevel@tonic-gate fprintf(stderr, gettext(pname_unp_err), 648*0Sstevel@tonic-gate arg->programname, error_message(retval)); 649*0Sstevel@tonic-gate return(retval); 650*0Sstevel@tonic-gate } 651*0Sstevel@tonic-gate 652*0Sstevel@tonic-gate /* 653*0Sstevel@tonic-gate * Re-encode the keys in the new master key, if necessary. 654*0Sstevel@tonic-gate */ 655*0Sstevel@tonic-gate if (mkey_convert) { 656*0Sstevel@tonic-gate retval = master_key_convert(arg->kcontext, entry); 657*0Sstevel@tonic-gate if (retval) { 658*0Sstevel@tonic-gate com_err(arg->programname, retval, remaster_err_fmt, name); 659*0Sstevel@tonic-gate return retval; 660*0Sstevel@tonic-gate } 661*0Sstevel@tonic-gate } 662*0Sstevel@tonic-gate 663*0Sstevel@tonic-gate /* 664*0Sstevel@tonic-gate * If we don't have any match strings, or if our name matches, then 665*0Sstevel@tonic-gate * proceed with the dump, otherwise, just forget about it. 666*0Sstevel@tonic-gate */ 667*0Sstevel@tonic-gate if (!arg->nnames || name_matches(name, arg)) { 668*0Sstevel@tonic-gate /* 669*0Sstevel@tonic-gate * Deserialize the modifier record. 670*0Sstevel@tonic-gate */ 671*0Sstevel@tonic-gate mod_name = (char *) NULL; 672*0Sstevel@tonic-gate mod_princ = NULL; 673*0Sstevel@tonic-gate last_pwd_change = mod_date = 0; 674*0Sstevel@tonic-gate pkey = akey = (krb5_key_data *) NULL; 675*0Sstevel@tonic-gate if (!(retval = krb5_dbe_lookup_mod_princ_data(arg->kcontext, 676*0Sstevel@tonic-gate entry, 677*0Sstevel@tonic-gate &mod_date, 678*0Sstevel@tonic-gate &mod_princ))) { 679*0Sstevel@tonic-gate if (mod_princ) { 680*0Sstevel@tonic-gate /* 681*0Sstevel@tonic-gate * Flatten the modifier name. 682*0Sstevel@tonic-gate */ 683*0Sstevel@tonic-gate if ((retval = krb5_unparse_name(arg->kcontext, 684*0Sstevel@tonic-gate mod_princ, 685*0Sstevel@tonic-gate &mod_name))) 686*0Sstevel@tonic-gate fprintf(stderr, gettext(mname_unp_err), 687*0Sstevel@tonic-gate arg->programname, 688*0Sstevel@tonic-gate error_message(retval)); 689*0Sstevel@tonic-gate krb5_free_principal(arg->kcontext, mod_princ); 690*0Sstevel@tonic-gate } 691*0Sstevel@tonic-gate } 692*0Sstevel@tonic-gate if (!mod_name) 693*0Sstevel@tonic-gate mod_name = strdup(null_mprinc_name); 694*0Sstevel@tonic-gate 695*0Sstevel@tonic-gate /* 696*0Sstevel@tonic-gate * Find the last password change record and set it 697*0Sstevel@tonic-gate * straight. 698*0Sstevel@tonic-gate */ 699*0Sstevel@tonic-gate if ((retval = 700*0Sstevel@tonic-gate krb5_dbe_lookup_last_pwd_change(arg->kcontext, entry, 701*0Sstevel@tonic-gate &last_pwd_change))) { 702*0Sstevel@tonic-gate fprintf(stderr, gettext(nokeys_err), 703*0Sstevel@tonic-gate arg->programname, name); 704*0Sstevel@tonic-gate krb5_xfree(mod_name); 705*0Sstevel@tonic-gate krb5_xfree(name); 706*0Sstevel@tonic-gate return(retval); 707*0Sstevel@tonic-gate } 708*0Sstevel@tonic-gate 709*0Sstevel@tonic-gate /* 710*0Sstevel@tonic-gate * Find the 'primary' key and the 'alternate' key. 711*0Sstevel@tonic-gate */ 712*0Sstevel@tonic-gate if ((retval = find_enctype(entry, 713*0Sstevel@tonic-gate ENCTYPE_DES_CBC_CRC, 714*0Sstevel@tonic-gate KRB5_KDB_SALTTYPE_NORMAL, 715*0Sstevel@tonic-gate &pkey)) && 716*0Sstevel@tonic-gate (retval = find_enctype(entry, 717*0Sstevel@tonic-gate ENCTYPE_DES_CBC_CRC, 718*0Sstevel@tonic-gate KRB5_KDB_SALTTYPE_V4, 719*0Sstevel@tonic-gate &akey))) { 720*0Sstevel@tonic-gate fprintf(stderr, gettext(nokeys_err), 721*0Sstevel@tonic-gate arg->programname, name); 722*0Sstevel@tonic-gate krb5_xfree(mod_name); 723*0Sstevel@tonic-gate krb5_xfree(name); 724*0Sstevel@tonic-gate return(retval); 725*0Sstevel@tonic-gate } 726*0Sstevel@tonic-gate /* 727*0Sstevel@tonic-gate * If we only have one type, then ship it out as the 728*0Sstevel@tonic-gate * primary. 729*0Sstevel@tonic-gate */ 730*0Sstevel@tonic-gate if (!pkey && akey) { 731*0Sstevel@tonic-gate pkey = akey; 732*0Sstevel@tonic-gate akey = &nullkey; 733*0Sstevel@tonic-gate } else { 734*0Sstevel@tonic-gate if (!akey) 735*0Sstevel@tonic-gate akey = &nullkey; 736*0Sstevel@tonic-gate } 737*0Sstevel@tonic-gate 738*0Sstevel@tonic-gate /* 739*0Sstevel@tonic-gate * First put out strings representing the length of the 740*0Sstevel@tonic-gate * variable length data in this record, then the name and 741*0Sstevel@tonic-gate * the primary key type. 742*0Sstevel@tonic-gate */ 743*0Sstevel@tonic-gate fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%d\t%s\t%d\t", 744*0Sstevel@tonic-gate strlen(name), 745*0Sstevel@tonic-gate strlen(mod_name), 746*0Sstevel@tonic-gate (krb5_int32) pkey->key_data_length[0], 747*0Sstevel@tonic-gate (krb5_int32) akey->key_data_length[0], 748*0Sstevel@tonic-gate (krb5_int32) pkey->key_data_length[1], 749*0Sstevel@tonic-gate (krb5_int32) akey->key_data_length[1], 750*0Sstevel@tonic-gate name, 751*0Sstevel@tonic-gate (krb5_int32) pkey->key_data_type[0]); 752*0Sstevel@tonic-gate for (i=0; i<pkey->key_data_length[0]; i++) { 753*0Sstevel@tonic-gate fprintf(arg->ofile, "%02x", 754*0Sstevel@tonic-gate pkey->key_data_contents[0][i]); 755*0Sstevel@tonic-gate } 756*0Sstevel@tonic-gate /* 757*0Sstevel@tonic-gate * Second, print out strings representing the standard 758*0Sstevel@tonic-gate * integer data in this record. 759*0Sstevel@tonic-gate */ 760*0Sstevel@tonic-gate fprintf(arg->ofile, 761*0Sstevel@tonic-gate "\t%u\t%u\t%u\t%u\t%u\t%u\t%u" 762*0Sstevel@tonic-gate "\t%u\t%u\t%u\t%s\t%u\t%u\t%u\t", 763*0Sstevel@tonic-gate (krb5_int32) pkey->key_data_kvno, 764*0Sstevel@tonic-gate entry->max_life, entry->max_renewable_life, 765*0Sstevel@tonic-gate 1 /* Fake mkvno */, entry->expiration, 766*0Sstevel@tonic-gate entry->pw_expiration, last_pwd_change, 767*0Sstevel@tonic-gate entry->last_success, entry->last_failed, 768*0Sstevel@tonic-gate entry->fail_auth_count, mod_name, mod_date, 769*0Sstevel@tonic-gate entry->attributes, pkey->key_data_type[1]); 770*0Sstevel@tonic-gate 771*0Sstevel@tonic-gate /* Pound out the salt data, if present. */ 772*0Sstevel@tonic-gate for (i=0; i<pkey->key_data_length[1]; i++) { 773*0Sstevel@tonic-gate fprintf(arg->ofile, "%02x", 774*0Sstevel@tonic-gate pkey->key_data_contents[1][i]); 775*0Sstevel@tonic-gate } 776*0Sstevel@tonic-gate /* Pound out the alternate key type and contents */ 777*0Sstevel@tonic-gate fprintf(arg->ofile, "\t%u\t", akey->key_data_type[0]); 778*0Sstevel@tonic-gate for (i=0; i<akey->key_data_length[0]; i++) { 779*0Sstevel@tonic-gate fprintf(arg->ofile, "%02x", 780*0Sstevel@tonic-gate akey->key_data_contents[0][i]); 781*0Sstevel@tonic-gate } 782*0Sstevel@tonic-gate /* Pound out the alternate salt type and contents */ 783*0Sstevel@tonic-gate fprintf(arg->ofile, "\t%u\t", akey->key_data_type[1]); 784*0Sstevel@tonic-gate for (i=0; i<akey->key_data_length[1]; i++) { 785*0Sstevel@tonic-gate fprintf(arg->ofile, "%02x", 786*0Sstevel@tonic-gate akey->key_data_contents[1][i]); 787*0Sstevel@tonic-gate } 788*0Sstevel@tonic-gate /* Pound out the expansion data. (is null) */ 789*0Sstevel@tonic-gate for (i=0; i < 8; i++) { 790*0Sstevel@tonic-gate fprintf(arg->ofile, "\t%u", 0); 791*0Sstevel@tonic-gate } 792*0Sstevel@tonic-gate fprintf(arg->ofile, ";\n"); 793*0Sstevel@tonic-gate /* If we're blabbing, do it */ 794*0Sstevel@tonic-gate if (arg->verbose) 795*0Sstevel@tonic-gate fprintf(stderr, "%s\n", name); 796*0Sstevel@tonic-gate krb5_xfree(mod_name); 797*0Sstevel@tonic-gate } 798*0Sstevel@tonic-gate krb5_xfree(name); 799*0Sstevel@tonic-gate return(0); 800*0Sstevel@tonic-gate } 801*0Sstevel@tonic-gate 802*0Sstevel@tonic-gate /* 803*0Sstevel@tonic-gate * dump_k5beta6_iterator() - Output a dump record in krb5b6 format. 804*0Sstevel@tonic-gate */ 805*0Sstevel@tonic-gate static krb5_error_code 806*0Sstevel@tonic-gate dump_k5beta6_iterator(ptr, entry) 807*0Sstevel@tonic-gate krb5_pointer ptr; 808*0Sstevel@tonic-gate krb5_db_entry *entry; 809*0Sstevel@tonic-gate { 810*0Sstevel@tonic-gate krb5_error_code retval; 811*0Sstevel@tonic-gate struct dump_args *arg; 812*0Sstevel@tonic-gate char *name; 813*0Sstevel@tonic-gate krb5_tl_data *tlp; 814*0Sstevel@tonic-gate krb5_key_data *kdata; 815*0Sstevel@tonic-gate int counter, skip, i, j; 816*0Sstevel@tonic-gate 817*0Sstevel@tonic-gate /* Initialize */ 818*0Sstevel@tonic-gate arg = (struct dump_args *) ptr; 819*0Sstevel@tonic-gate name = (char *) NULL; 820*0Sstevel@tonic-gate 821*0Sstevel@tonic-gate /* 822*0Sstevel@tonic-gate * Flatten the principal name. 823*0Sstevel@tonic-gate */ 824*0Sstevel@tonic-gate if ((retval = krb5_unparse_name(arg->kcontext, 825*0Sstevel@tonic-gate entry->princ, 826*0Sstevel@tonic-gate &name))) { 827*0Sstevel@tonic-gate fprintf(stderr, gettext(pname_unp_err), 828*0Sstevel@tonic-gate arg->programname, error_message(retval)); 829*0Sstevel@tonic-gate return(retval); 830*0Sstevel@tonic-gate } 831*0Sstevel@tonic-gate 832*0Sstevel@tonic-gate /* 833*0Sstevel@tonic-gate * Re-encode the keys in the new master key, if necessary. 834*0Sstevel@tonic-gate */ 835*0Sstevel@tonic-gate if (mkey_convert) { 836*0Sstevel@tonic-gate retval = master_key_convert(arg->kcontext, entry); 837*0Sstevel@tonic-gate if (retval) { 838*0Sstevel@tonic-gate com_err(arg->programname, retval, remaster_err_fmt, name); 839*0Sstevel@tonic-gate return retval; 840*0Sstevel@tonic-gate } 841*0Sstevel@tonic-gate } 842*0Sstevel@tonic-gate 843*0Sstevel@tonic-gate /* 844*0Sstevel@tonic-gate * If we don't have any match strings, or if our name matches, then 845*0Sstevel@tonic-gate * proceed with the dump, otherwise, just forget about it. 846*0Sstevel@tonic-gate */ 847*0Sstevel@tonic-gate if (!arg->nnames || name_matches(name, arg)) { 848*0Sstevel@tonic-gate /* 849*0Sstevel@tonic-gate * We'd like to just blast out the contents as they would 850*0Sstevel@tonic-gate * appear in the database so that we can just suck it back 851*0Sstevel@tonic-gate * in, but it doesn't lend itself to easy editing. 852*0Sstevel@tonic-gate */ 853*0Sstevel@tonic-gate 854*0Sstevel@tonic-gate /* 855*0Sstevel@tonic-gate * The dump format is as follows: len strlen(name) 856*0Sstevel@tonic-gate * n_tl_data n_key_data e_length name attributes max_life 857*0Sstevel@tonic-gate * max_renewable_life expiration pw_expiration last_success 858*0Sstevel@tonic-gate * last_failed fail_auth_count n_tl_data*[type length 859*0Sstevel@tonic-gate * <contents>] n_key_data*[ver kvno ver*(type length 860*0Sstevel@tonic-gate * <contents>)] <e_data> Fields which are not encapsulated 861*0Sstevel@tonic-gate * by angle-brackets are to appear verbatim. Bracketed 862*0Sstevel@tonic-gate * fields absence is indicated by a -1 in its place 863*0Sstevel@tonic-gate */ 864*0Sstevel@tonic-gate 865*0Sstevel@tonic-gate /* 866*0Sstevel@tonic-gate * Make sure that the tagged list is reasonably correct. 867*0Sstevel@tonic-gate */ 868*0Sstevel@tonic-gate counter = skip = 0; 869*0Sstevel@tonic-gate for (tlp = entry->tl_data; tlp; tlp = tlp->tl_data_next) { 870*0Sstevel@tonic-gate /* 871*0Sstevel@tonic-gate * don't dump tl data types we know aren't 872*0Sstevel@tonic-gate * understood by earlier revisions [krb5-admin/89] 873*0Sstevel@tonic-gate */ 874*0Sstevel@tonic-gate switch (tlp->tl_data_type) { 875*0Sstevel@tonic-gate case KRB5_TL_KADM_DATA: 876*0Sstevel@tonic-gate skip++; 877*0Sstevel@tonic-gate break; 878*0Sstevel@tonic-gate default: 879*0Sstevel@tonic-gate counter++; 880*0Sstevel@tonic-gate break; 881*0Sstevel@tonic-gate } 882*0Sstevel@tonic-gate } 883*0Sstevel@tonic-gate 884*0Sstevel@tonic-gate if (counter + skip == entry->n_tl_data) { 885*0Sstevel@tonic-gate /* Pound out header */ 886*0Sstevel@tonic-gate fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%s\t", 887*0Sstevel@tonic-gate (int) entry->len, 888*0Sstevel@tonic-gate strlen(name), 889*0Sstevel@tonic-gate counter, 890*0Sstevel@tonic-gate (int) entry->n_key_data, 891*0Sstevel@tonic-gate (int) entry->e_length, 892*0Sstevel@tonic-gate name); 893*0Sstevel@tonic-gate fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t", 894*0Sstevel@tonic-gate entry->attributes, 895*0Sstevel@tonic-gate entry->max_life, 896*0Sstevel@tonic-gate entry->max_renewable_life, 897*0Sstevel@tonic-gate entry->expiration, 898*0Sstevel@tonic-gate entry->pw_expiration, 899*0Sstevel@tonic-gate entry->last_success, 900*0Sstevel@tonic-gate entry->last_failed, 901*0Sstevel@tonic-gate entry->fail_auth_count); 902*0Sstevel@tonic-gate /* Pound out tagged data. */ 903*0Sstevel@tonic-gate for (tlp = entry->tl_data; tlp; 904*0Sstevel@tonic-gate tlp = tlp->tl_data_next) { 905*0Sstevel@tonic-gate if (tlp->tl_data_type == KRB5_TL_KADM_DATA) 906*0Sstevel@tonic-gate /* see above, [krb5-admin/89] */ 907*0Sstevel@tonic-gate continue; 908*0Sstevel@tonic-gate 909*0Sstevel@tonic-gate fprintf(arg->ofile, "%d\t%d\t", 910*0Sstevel@tonic-gate (int) tlp->tl_data_type, 911*0Sstevel@tonic-gate (int) tlp->tl_data_length); 912*0Sstevel@tonic-gate if (tlp->tl_data_length) 913*0Sstevel@tonic-gate for (i = 0; 914*0Sstevel@tonic-gate i < tlp->tl_data_length; 915*0Sstevel@tonic-gate i++) 916*0Sstevel@tonic-gate fprintf(arg->ofile, "%02x", 917*0Sstevel@tonic-gate tlp-> 918*0Sstevel@tonic-gate tl_data_contents[i]); 919*0Sstevel@tonic-gate else 920*0Sstevel@tonic-gate fprintf(arg->ofile, "%d", -1); 921*0Sstevel@tonic-gate fprintf(arg->ofile, "\t"); 922*0Sstevel@tonic-gate } 923*0Sstevel@tonic-gate 924*0Sstevel@tonic-gate /* Pound out key data */ 925*0Sstevel@tonic-gate for (counter = 0; 926*0Sstevel@tonic-gate counter < entry->n_key_data; counter++) { 927*0Sstevel@tonic-gate kdata = &entry->key_data[counter]; 928*0Sstevel@tonic-gate fprintf(arg->ofile, "%d\t%d\t", 929*0Sstevel@tonic-gate (int) kdata->key_data_ver, 930*0Sstevel@tonic-gate (int) kdata->key_data_kvno); 931*0Sstevel@tonic-gate for (i=0; i<kdata->key_data_ver; i++) { 932*0Sstevel@tonic-gate fprintf(arg->ofile, "%d\t%d\t", 933*0Sstevel@tonic-gate kdata->key_data_type[i], 934*0Sstevel@tonic-gate kdata->key_data_length[i]); 935*0Sstevel@tonic-gate if (kdata->key_data_length[i]) 936*0Sstevel@tonic-gate for (j = 0; 937*0Sstevel@tonic-gate j < kdata-> 938*0Sstevel@tonic-gate key_data_length[i]; 939*0Sstevel@tonic-gate j++) 940*0Sstevel@tonic-gate fprintf(arg->ofile, 941*0Sstevel@tonic-gate "%02x", 942*0Sstevel@tonic-gate kdata-> 943*0Sstevel@tonic-gate key_data_contents 944*0Sstevel@tonic-gate [i][j]); 945*0Sstevel@tonic-gate else 946*0Sstevel@tonic-gate fprintf(arg->ofile, "%d", -1); 947*0Sstevel@tonic-gate fprintf(arg->ofile, "\t"); 948*0Sstevel@tonic-gate } 949*0Sstevel@tonic-gate } 950*0Sstevel@tonic-gate 951*0Sstevel@tonic-gate /* Pound out extra data */ 952*0Sstevel@tonic-gate if (entry->e_length) 953*0Sstevel@tonic-gate for (i=0; i<entry->e_length; i++) 954*0Sstevel@tonic-gate fprintf(arg->ofile, "%02x", 955*0Sstevel@tonic-gate entry->e_data[i]); 956*0Sstevel@tonic-gate else 957*0Sstevel@tonic-gate fprintf(arg->ofile, "%d", -1); 958*0Sstevel@tonic-gate 959*0Sstevel@tonic-gate /* Print trailer */ 960*0Sstevel@tonic-gate fprintf(arg->ofile, ";\n"); 961*0Sstevel@tonic-gate 962*0Sstevel@tonic-gate if (arg->verbose) 963*0Sstevel@tonic-gate fprintf(stderr, "%s\n", name); 964*0Sstevel@tonic-gate } else { 965*0Sstevel@tonic-gate fprintf(stderr, gettext(sdump_tl_inc_err), 966*0Sstevel@tonic-gate arg->programname, name, counter + skip, 967*0Sstevel@tonic-gate (int) entry->n_tl_data); 968*0Sstevel@tonic-gate retval = EINVAL; 969*0Sstevel@tonic-gate } 970*0Sstevel@tonic-gate } 971*0Sstevel@tonic-gate krb5_xfree(name); 972*0Sstevel@tonic-gate return(retval); 973*0Sstevel@tonic-gate } 974*0Sstevel@tonic-gate /* 975*0Sstevel@tonic-gate * dump_iprop_iterator() - Output a dump record in iprop format. 976*0Sstevel@tonic-gate */ 977*0Sstevel@tonic-gate static krb5_error_code 978*0Sstevel@tonic-gate dump_iprop_iterator(ptr, entry) 979*0Sstevel@tonic-gate krb5_pointer ptr; 980*0Sstevel@tonic-gate krb5_db_entry *entry; 981*0Sstevel@tonic-gate { 982*0Sstevel@tonic-gate krb5_error_code retval; 983*0Sstevel@tonic-gate struct dump_args *arg; 984*0Sstevel@tonic-gate char *name; 985*0Sstevel@tonic-gate krb5_tl_data *tlp; 986*0Sstevel@tonic-gate krb5_key_data *kdata; 987*0Sstevel@tonic-gate int counter, i, j; 988*0Sstevel@tonic-gate 989*0Sstevel@tonic-gate /* Initialize */ 990*0Sstevel@tonic-gate arg = (struct dump_args *) ptr; 991*0Sstevel@tonic-gate name = (char *) NULL; 992*0Sstevel@tonic-gate 993*0Sstevel@tonic-gate /* 994*0Sstevel@tonic-gate * Flatten the principal name. 995*0Sstevel@tonic-gate */ 996*0Sstevel@tonic-gate if ((retval = krb5_unparse_name(arg->kcontext, 997*0Sstevel@tonic-gate entry->princ, 998*0Sstevel@tonic-gate &name))) { 999*0Sstevel@tonic-gate fprintf(stderr, gettext(pname_unp_err), 1000*0Sstevel@tonic-gate arg->programname, error_message(retval)); 1001*0Sstevel@tonic-gate return(retval); 1002*0Sstevel@tonic-gate } 1003*0Sstevel@tonic-gate 1004*0Sstevel@tonic-gate /* 1005*0Sstevel@tonic-gate * Re-encode the keys in the new master key, if necessary. 1006*0Sstevel@tonic-gate */ 1007*0Sstevel@tonic-gate if (mkey_convert) { 1008*0Sstevel@tonic-gate retval = master_key_convert(arg->kcontext, entry); 1009*0Sstevel@tonic-gate if (retval) { 1010*0Sstevel@tonic-gate com_err(arg->programname, retval, remaster_err_fmt, name); 1011*0Sstevel@tonic-gate return retval; 1012*0Sstevel@tonic-gate } 1013*0Sstevel@tonic-gate } 1014*0Sstevel@tonic-gate 1015*0Sstevel@tonic-gate /* 1016*0Sstevel@tonic-gate * If we don't have any match strings, or if our name matches, then 1017*0Sstevel@tonic-gate * proceed with the dump, otherwise, just forget about it. 1018*0Sstevel@tonic-gate */ 1019*0Sstevel@tonic-gate if (!arg->nnames || name_matches(name, arg)) { 1020*0Sstevel@tonic-gate /* 1021*0Sstevel@tonic-gate * We'd like to just blast out the contents as they would 1022*0Sstevel@tonic-gate * appear in the database so that we can just suck it back 1023*0Sstevel@tonic-gate * in, but it doesn't lend itself to easy editing. 1024*0Sstevel@tonic-gate */ 1025*0Sstevel@tonic-gate 1026*0Sstevel@tonic-gate /* 1027*0Sstevel@tonic-gate * The dump format is as follows: len strlen(name) 1028*0Sstevel@tonic-gate * n_tl_data n_key_data e_length name attributes max_life 1029*0Sstevel@tonic-gate * max_renewable_life expiration pw_expiration last_success 1030*0Sstevel@tonic-gate * last_failed fail_auth_count n_tl_data*[type length 1031*0Sstevel@tonic-gate * <contents>] n_key_data*[ver kvno ver*(type length 1032*0Sstevel@tonic-gate * <contents>)] <e_data> Fields which are not encapsulated 1033*0Sstevel@tonic-gate * by angle-brackets are to appear verbatim. Bracketed 1034*0Sstevel@tonic-gate * fields absence is indicated by a -1 in its place 1035*0Sstevel@tonic-gate */ 1036*0Sstevel@tonic-gate 1037*0Sstevel@tonic-gate /* 1038*0Sstevel@tonic-gate * Make sure that the tagged list is reasonably correct. 1039*0Sstevel@tonic-gate */ 1040*0Sstevel@tonic-gate counter = 0; 1041*0Sstevel@tonic-gate for (tlp = entry->tl_data; tlp; tlp = tlp->tl_data_next) 1042*0Sstevel@tonic-gate counter++; 1043*0Sstevel@tonic-gate 1044*0Sstevel@tonic-gate if (counter == entry->n_tl_data) { 1045*0Sstevel@tonic-gate /* Pound out header */ 1046*0Sstevel@tonic-gate fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%s\t", 1047*0Sstevel@tonic-gate (int) entry->len, 1048*0Sstevel@tonic-gate strlen(name), 1049*0Sstevel@tonic-gate (int) entry->n_tl_data, 1050*0Sstevel@tonic-gate (int) entry->n_key_data, 1051*0Sstevel@tonic-gate (int) entry->e_length, 1052*0Sstevel@tonic-gate name); 1053*0Sstevel@tonic-gate fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t", 1054*0Sstevel@tonic-gate entry->attributes, 1055*0Sstevel@tonic-gate entry->max_life, 1056*0Sstevel@tonic-gate entry->max_renewable_life, 1057*0Sstevel@tonic-gate entry->expiration, 1058*0Sstevel@tonic-gate entry->pw_expiration, 1059*0Sstevel@tonic-gate entry->last_success, 1060*0Sstevel@tonic-gate entry->last_failed, 1061*0Sstevel@tonic-gate entry->fail_auth_count); 1062*0Sstevel@tonic-gate /* Pound out tagged data. */ 1063*0Sstevel@tonic-gate for (tlp = entry->tl_data; tlp; 1064*0Sstevel@tonic-gate tlp = tlp->tl_data_next) { 1065*0Sstevel@tonic-gate fprintf(arg->ofile, "%d\t%d\t", 1066*0Sstevel@tonic-gate (int) tlp->tl_data_type, 1067*0Sstevel@tonic-gate (int) tlp->tl_data_length); 1068*0Sstevel@tonic-gate if (tlp->tl_data_length) 1069*0Sstevel@tonic-gate for (i = 0; 1070*0Sstevel@tonic-gate i < tlp->tl_data_length; 1071*0Sstevel@tonic-gate i++) 1072*0Sstevel@tonic-gate fprintf(arg->ofile, "%02x", 1073*0Sstevel@tonic-gate tlp-> 1074*0Sstevel@tonic-gate tl_data_contents[i]); 1075*0Sstevel@tonic-gate else 1076*0Sstevel@tonic-gate fprintf(arg->ofile, "%d", -1); 1077*0Sstevel@tonic-gate fprintf(arg->ofile, "\t"); 1078*0Sstevel@tonic-gate } 1079*0Sstevel@tonic-gate 1080*0Sstevel@tonic-gate /* Pound out key data */ 1081*0Sstevel@tonic-gate for (counter = 0; 1082*0Sstevel@tonic-gate counter < entry->n_key_data; counter++) { 1083*0Sstevel@tonic-gate kdata = &entry->key_data[counter]; 1084*0Sstevel@tonic-gate fprintf(arg->ofile, "%d\t%d\t", 1085*0Sstevel@tonic-gate (int) kdata->key_data_ver, 1086*0Sstevel@tonic-gate (int) kdata->key_data_kvno); 1087*0Sstevel@tonic-gate for (i=0; i<kdata->key_data_ver; i++) { 1088*0Sstevel@tonic-gate fprintf(arg->ofile, "%d\t%d\t", 1089*0Sstevel@tonic-gate kdata->key_data_type[i], 1090*0Sstevel@tonic-gate kdata->key_data_length[i]); 1091*0Sstevel@tonic-gate if (kdata->key_data_length[i]) 1092*0Sstevel@tonic-gate for (j = 0; 1093*0Sstevel@tonic-gate j < kdata-> 1094*0Sstevel@tonic-gate key_data_length[i]; 1095*0Sstevel@tonic-gate j++) 1096*0Sstevel@tonic-gate fprintf(arg->ofile, 1097*0Sstevel@tonic-gate "%02x", 1098*0Sstevel@tonic-gate kdata-> 1099*0Sstevel@tonic-gate key_data_contents 1100*0Sstevel@tonic-gate [i][j]); 1101*0Sstevel@tonic-gate else 1102*0Sstevel@tonic-gate fprintf(arg->ofile, "%d", -1); 1103*0Sstevel@tonic-gate fprintf(arg->ofile, "\t"); 1104*0Sstevel@tonic-gate } 1105*0Sstevel@tonic-gate } 1106*0Sstevel@tonic-gate 1107*0Sstevel@tonic-gate /* Pound out extra data */ 1108*0Sstevel@tonic-gate if (entry->e_length) 1109*0Sstevel@tonic-gate for (i=0; i<entry->e_length; i++) 1110*0Sstevel@tonic-gate fprintf(arg->ofile, "%02x", 1111*0Sstevel@tonic-gate entry->e_data[i]); 1112*0Sstevel@tonic-gate else 1113*0Sstevel@tonic-gate fprintf(arg->ofile, "%d", -1); 1114*0Sstevel@tonic-gate 1115*0Sstevel@tonic-gate /* Print trailer */ 1116*0Sstevel@tonic-gate fprintf(arg->ofile, ";\n"); 1117*0Sstevel@tonic-gate 1118*0Sstevel@tonic-gate if (arg->verbose) 1119*0Sstevel@tonic-gate fprintf(stderr, "%s\n", name); 1120*0Sstevel@tonic-gate } else { 1121*0Sstevel@tonic-gate fprintf(stderr, gettext(sdump_tl_inc_err), 1122*0Sstevel@tonic-gate arg->programname, name, counter, 1123*0Sstevel@tonic-gate (int) entry->n_tl_data); 1124*0Sstevel@tonic-gate retval = EINVAL; 1125*0Sstevel@tonic-gate } 1126*0Sstevel@tonic-gate } 1127*0Sstevel@tonic-gate krb5_xfree(name); 1128*0Sstevel@tonic-gate return(retval); 1129*0Sstevel@tonic-gate } 1130*0Sstevel@tonic-gate 1131*0Sstevel@tonic-gate /* 1132*0Sstevel@tonic-gate * dump_k5beta7_iterator() - Output a dump record in krb5b7 format. 1133*0Sstevel@tonic-gate */ 1134*0Sstevel@tonic-gate static krb5_error_code 1135*0Sstevel@tonic-gate dump_k5beta7_princ(ptr, entry) 1136*0Sstevel@tonic-gate krb5_pointer ptr; 1137*0Sstevel@tonic-gate krb5_db_entry *entry; 1138*0Sstevel@tonic-gate { 1139*0Sstevel@tonic-gate krb5_error_code retval; 1140*0Sstevel@tonic-gate struct dump_args *arg; 1141*0Sstevel@tonic-gate char *name; 1142*0Sstevel@tonic-gate int tmp_nnames; 1143*0Sstevel@tonic-gate 1144*0Sstevel@tonic-gate /* Initialize */ 1145*0Sstevel@tonic-gate arg = (struct dump_args *) ptr; 1146*0Sstevel@tonic-gate name = (char *) NULL; 1147*0Sstevel@tonic-gate 1148*0Sstevel@tonic-gate /* 1149*0Sstevel@tonic-gate * Flatten the principal name. 1150*0Sstevel@tonic-gate */ 1151*0Sstevel@tonic-gate if ((retval = krb5_unparse_name(arg->kcontext, 1152*0Sstevel@tonic-gate entry->princ, 1153*0Sstevel@tonic-gate &name))) { 1154*0Sstevel@tonic-gate fprintf(stderr, gettext(pname_unp_err), 1155*0Sstevel@tonic-gate arg->programname, error_message(retval)); 1156*0Sstevel@tonic-gate return(retval); 1157*0Sstevel@tonic-gate } 1158*0Sstevel@tonic-gate /* 1159*0Sstevel@tonic-gate * If we don't have any match strings, or if our name matches, then 1160*0Sstevel@tonic-gate * proceed with the dump, otherwise, just forget about it. 1161*0Sstevel@tonic-gate */ 1162*0Sstevel@tonic-gate if (!arg->nnames || name_matches(name, arg)) { 1163*0Sstevel@tonic-gate fprintf(arg->ofile, "princ\t"); 1164*0Sstevel@tonic-gate 1165*0Sstevel@tonic-gate /* save the callee from matching the name again */ 1166*0Sstevel@tonic-gate tmp_nnames = arg->nnames; 1167*0Sstevel@tonic-gate arg->nnames = 0; 1168*0Sstevel@tonic-gate retval = dump_k5beta6_iterator(ptr, entry); 1169*0Sstevel@tonic-gate arg->nnames = tmp_nnames; 1170*0Sstevel@tonic-gate } 1171*0Sstevel@tonic-gate free(name); 1172*0Sstevel@tonic-gate return (retval); 1173*0Sstevel@tonic-gate } 1174*0Sstevel@tonic-gate 1175*0Sstevel@tonic-gate /* 1176*0Sstevel@tonic-gate * dump_iprop_princ() - Output a dump record in iprop format. 1177*0Sstevel@tonic-gate * This was created in order to dump more data, such as kadm5 tl 1178*0Sstevel@tonic-gate */ 1179*0Sstevel@tonic-gate static krb5_error_code 1180*0Sstevel@tonic-gate dump_iprop_princ(ptr, entry) 1181*0Sstevel@tonic-gate krb5_pointer ptr; 1182*0Sstevel@tonic-gate krb5_db_entry *entry; 1183*0Sstevel@tonic-gate { 1184*0Sstevel@tonic-gate krb5_error_code retval; 1185*0Sstevel@tonic-gate struct dump_args *arg; 1186*0Sstevel@tonic-gate char *name; 1187*0Sstevel@tonic-gate int tmp_nnames; 1188*0Sstevel@tonic-gate 1189*0Sstevel@tonic-gate /* Initialize */ 1190*0Sstevel@tonic-gate arg = (struct dump_args *) ptr; 1191*0Sstevel@tonic-gate name = (char *) NULL; 1192*0Sstevel@tonic-gate 1193*0Sstevel@tonic-gate /* 1194*0Sstevel@tonic-gate * Flatten the principal name. 1195*0Sstevel@tonic-gate */ 1196*0Sstevel@tonic-gate if ((retval = krb5_unparse_name(arg->kcontext, 1197*0Sstevel@tonic-gate entry->princ, 1198*0Sstevel@tonic-gate &name))) { 1199*0Sstevel@tonic-gate fprintf(stderr, gettext(pname_unp_err), 1200*0Sstevel@tonic-gate arg->programname, error_message(retval)); 1201*0Sstevel@tonic-gate return(retval); 1202*0Sstevel@tonic-gate } 1203*0Sstevel@tonic-gate /* 1204*0Sstevel@tonic-gate * If we don't have any match strings, or if our name matches, then 1205*0Sstevel@tonic-gate * proceed with the dump, otherwise, just forget about it. 1206*0Sstevel@tonic-gate */ 1207*0Sstevel@tonic-gate if (!arg->nnames || name_matches(name, arg)) { 1208*0Sstevel@tonic-gate fprintf(arg->ofile, "princ\t"); 1209*0Sstevel@tonic-gate 1210*0Sstevel@tonic-gate /* save the callee from matching the name again */ 1211*0Sstevel@tonic-gate tmp_nnames = arg->nnames; 1212*0Sstevel@tonic-gate arg->nnames = 0; 1213*0Sstevel@tonic-gate retval = dump_iprop_iterator(ptr, entry); 1214*0Sstevel@tonic-gate arg->nnames = tmp_nnames; 1215*0Sstevel@tonic-gate } 1216*0Sstevel@tonic-gate free(name); 1217*0Sstevel@tonic-gate return (retval); 1218*0Sstevel@tonic-gate } 1219*0Sstevel@tonic-gate void 1220*0Sstevel@tonic-gate dump_k5beta7_policy(void *data, osa_policy_ent_t entry) 1221*0Sstevel@tonic-gate { 1222*0Sstevel@tonic-gate struct dump_args *arg; 1223*0Sstevel@tonic-gate 1224*0Sstevel@tonic-gate arg = (struct dump_args *) data; 1225*0Sstevel@tonic-gate fprintf(arg->ofile, "policy\t%s\t%d\t%d\t%d\t%d\t%d\t%d\n", entry->name, 1226*0Sstevel@tonic-gate entry->pw_min_life, entry->pw_max_life, entry->pw_min_length, 1227*0Sstevel@tonic-gate entry->pw_min_classes, entry->pw_history_num, 1228*0Sstevel@tonic-gate entry->policy_refcnt); 1229*0Sstevel@tonic-gate } 1230*0Sstevel@tonic-gate 1231*0Sstevel@tonic-gate void 1232*0Sstevel@tonic-gate print_key_data(FILE * f, krb5_key_data * key_data) 1233*0Sstevel@tonic-gate { 1234*0Sstevel@tonic-gate int c; 1235*0Sstevel@tonic-gate 1236*0Sstevel@tonic-gate fprintf(f, "%d\t%d\t", key_data->key_data_type[0], 1237*0Sstevel@tonic-gate key_data->key_data_length[0]); 1238*0Sstevel@tonic-gate for(c = 0; c < key_data->key_data_length[0]; c++) 1239*0Sstevel@tonic-gate fprintf(f, "%02x ", 1240*0Sstevel@tonic-gate key_data->key_data_contents[0][c]); 1241*0Sstevel@tonic-gate } 1242*0Sstevel@tonic-gate 1243*0Sstevel@tonic-gate /* 1244*0Sstevel@tonic-gate * Function: print_princ 1245*0Sstevel@tonic-gate * 1246*0Sstevel@tonic-gate * Purpose: output osa_adb_princ_ent data in a human 1247*0Sstevel@tonic-gate * readable format (which is a format suitable for 1248*0Sstevel@tonic-gate * ovsec_adm_import consumption) 1249*0Sstevel@tonic-gate * 1250*0Sstevel@tonic-gate * Arguments: 1251*0Sstevel@tonic-gate * data (input) pointer to a structure containing a FILE * 1252*0Sstevel@tonic-gate * and a record counter. 1253*0Sstevel@tonic-gate * entry (input) entry to get dumped. 1254*0Sstevel@tonic-gate * <return value> void 1255*0Sstevel@tonic-gate * 1256*0Sstevel@tonic-gate * Requires: 1257*0Sstevel@tonic-gate * nuttin 1258*0Sstevel@tonic-gate * 1259*0Sstevel@tonic-gate * Effects: 1260*0Sstevel@tonic-gate * writes data to the specified file pointerp. 1261*0Sstevel@tonic-gate * 1262*0Sstevel@tonic-gate * Modifies: 1263*0Sstevel@tonic-gate * nuttin 1264*0Sstevel@tonic-gate * 1265*0Sstevel@tonic-gate */ 1266*0Sstevel@tonic-gate static krb5_error_code 1267*0Sstevel@tonic-gate dump_ov_princ(krb5_pointer ptr, krb5_db_entry * kdb) 1268*0Sstevel@tonic-gate { 1269*0Sstevel@tonic-gate char *princstr; 1270*0Sstevel@tonic-gate int x, y, foundcrc, ret; 1271*0Sstevel@tonic-gate struct dump_args *arg; 1272*0Sstevel@tonic-gate krb5_tl_data tl_data; 1273*0Sstevel@tonic-gate osa_princ_ent_rec adb; 1274*0Sstevel@tonic-gate XDR xdrs; 1275*0Sstevel@tonic-gate 1276*0Sstevel@tonic-gate arg = (struct dump_args *) ptr; 1277*0Sstevel@tonic-gate /* 1278*0Sstevel@tonic-gate * XXX Currently, lookup_tl_data always returns zero; it sets 1279*0Sstevel@tonic-gate * tl_data->tl_data_length to zero if the type isn't found. This 1280*0Sstevel@tonic-gate * should be fixed... 1281*0Sstevel@tonic-gate */ 1282*0Sstevel@tonic-gate /* 1283*0Sstevel@tonic-gate * XXX Should this function do nothing for a principal with no 1284*0Sstevel@tonic-gate * admin data, or print a record of "default" values? See comment 1285*0Sstevel@tonic-gate * in server_kdb.c to help decide. 1286*0Sstevel@tonic-gate */ 1287*0Sstevel@tonic-gate tl_data.tl_data_type = KRB5_TL_KADM_DATA; 1288*0Sstevel@tonic-gate if ((ret = krb5_dbe_lookup_tl_data(arg->kcontext, kdb, &tl_data)) || 1289*0Sstevel@tonic-gate (tl_data.tl_data_length == 0)) 1290*0Sstevel@tonic-gate return (0); 1291*0Sstevel@tonic-gate 1292*0Sstevel@tonic-gate memset(&adb, 0, sizeof(adb)); 1293*0Sstevel@tonic-gate xdrmem_create(&xdrs, (const caddr_t) tl_data.tl_data_contents, 1294*0Sstevel@tonic-gate tl_data.tl_data_length, XDR_DECODE); 1295*0Sstevel@tonic-gate if (! xdr_osa_princ_ent_rec(&xdrs, &adb)) { 1296*0Sstevel@tonic-gate xdr_destroy(&xdrs); 1297*0Sstevel@tonic-gate return(OSA_ADB_XDR_FAILURE); 1298*0Sstevel@tonic-gate } 1299*0Sstevel@tonic-gate xdr_destroy(&xdrs); 1300*0Sstevel@tonic-gate 1301*0Sstevel@tonic-gate krb5_unparse_name(arg->kcontext, kdb->princ, &princstr); 1302*0Sstevel@tonic-gate fprintf(arg->ofile, "princ\t%s\t", princstr); 1303*0Sstevel@tonic-gate if(adb.policy == NULL) 1304*0Sstevel@tonic-gate fputc('\t', arg->ofile); 1305*0Sstevel@tonic-gate else 1306*0Sstevel@tonic-gate fprintf(arg->ofile, "%s\t", adb.policy); 1307*0Sstevel@tonic-gate fprintf(arg->ofile, "%x\t%d\t%d\t%d", adb.aux_attributes, 1308*0Sstevel@tonic-gate adb.old_key_len,adb.old_key_next, adb.admin_history_kvno); 1309*0Sstevel@tonic-gate 1310*0Sstevel@tonic-gate for (x = 0; x < adb.old_key_len; x++) { 1311*0Sstevel@tonic-gate foundcrc = 0; 1312*0Sstevel@tonic-gate for (y = 0; y < adb.old_keys[x].n_key_data; y++) { 1313*0Sstevel@tonic-gate krb5_key_data *key_data = &adb.old_keys[x].key_data[y]; 1314*0Sstevel@tonic-gate 1315*0Sstevel@tonic-gate if (key_data->key_data_type[0] != ENCTYPE_DES_CBC_CRC) 1316*0Sstevel@tonic-gate continue; 1317*0Sstevel@tonic-gate if (foundcrc) { 1318*0Sstevel@tonic-gate fprintf(stderr, 1319*0Sstevel@tonic-gate gettext("Warning! Multiple DES-CBC-CRC " 1320*0Sstevel@tonic-gate "keys for principal %s; skipping " 1321*0Sstevel@tonic-gate "duplicates.\n"), 1322*0Sstevel@tonic-gate princstr); 1323*0Sstevel@tonic-gate continue; 1324*0Sstevel@tonic-gate } 1325*0Sstevel@tonic-gate foundcrc++; 1326*0Sstevel@tonic-gate 1327*0Sstevel@tonic-gate fputc('\t', arg->ofile); 1328*0Sstevel@tonic-gate print_key_data(arg->ofile, key_data); 1329*0Sstevel@tonic-gate } 1330*0Sstevel@tonic-gate if (!foundcrc) 1331*0Sstevel@tonic-gate fprintf(stderr, 1332*0Sstevel@tonic-gate gettext("Warning! No DES-CBC-CRC key " 1333*0Sstevel@tonic-gate "for principal %s, cannot generate " 1334*0Sstevel@tonic-gate "OV-compatible record; skipping\n"), 1335*0Sstevel@tonic-gate princstr); 1336*0Sstevel@tonic-gate } 1337*0Sstevel@tonic-gate 1338*0Sstevel@tonic-gate fputc('\n', arg->ofile); 1339*0Sstevel@tonic-gate free(princstr); 1340*0Sstevel@tonic-gate return (0); 1341*0Sstevel@tonic-gate } 1342*0Sstevel@tonic-gate 1343*0Sstevel@tonic-gate /* 1344*0Sstevel@tonic-gate * usage is: 1345*0Sstevel@tonic-gate * dump_db [-i] [-old] [-b6] [-ov] [-verbose] [filename [principals...]] 1346*0Sstevel@tonic-gate */ 1347*0Sstevel@tonic-gate void 1348*0Sstevel@tonic-gate dump_db(argc, argv) 1349*0Sstevel@tonic-gate int argc; 1350*0Sstevel@tonic-gate char **argv; 1351*0Sstevel@tonic-gate { 1352*0Sstevel@tonic-gate FILE *f; 1353*0Sstevel@tonic-gate struct dump_args arglist; 1354*0Sstevel@tonic-gate int error; 1355*0Sstevel@tonic-gate char *programname; 1356*0Sstevel@tonic-gate char *ofile; 1357*0Sstevel@tonic-gate krb5_error_code kret, retval; 1358*0Sstevel@tonic-gate dump_version *dump; 1359*0Sstevel@tonic-gate int aindex; 1360*0Sstevel@tonic-gate krb5_boolean locked; 1361*0Sstevel@tonic-gate extern osa_adb_policy_t policy_db; 1362*0Sstevel@tonic-gate char *new_mkey_file = 0; 1363*0Sstevel@tonic-gate bool_t dump_sno = FALSE; 1364*0Sstevel@tonic-gate kdb_log_context *log_ctx; 1365*0Sstevel@tonic-gate 1366*0Sstevel@tonic-gate /* 1367*0Sstevel@tonic-gate * Parse the arguments. 1368*0Sstevel@tonic-gate */ 1369*0Sstevel@tonic-gate programname = argv[0]; 1370*0Sstevel@tonic-gate if (strrchr(programname, (int) '/')) 1371*0Sstevel@tonic-gate programname = strrchr(argv[0], (int) '/') + 1; 1372*0Sstevel@tonic-gate ofile = (char *) NULL; 1373*0Sstevel@tonic-gate error = 0; 1374*0Sstevel@tonic-gate dump = &beta7_version; 1375*0Sstevel@tonic-gate arglist.verbose = 0; 1376*0Sstevel@tonic-gate new_mkey_file = 0; 1377*0Sstevel@tonic-gate mkey_convert = 0; 1378*0Sstevel@tonic-gate log_ctx = util_context->kdblog_context; 1379*0Sstevel@tonic-gate 1380*0Sstevel@tonic-gate /* 1381*0Sstevel@tonic-gate * Parse the qualifiers. 1382*0Sstevel@tonic-gate */ 1383*0Sstevel@tonic-gate for (aindex = 1; aindex < argc; aindex++) { 1384*0Sstevel@tonic-gate if (strcmp(argv[aindex], oldoption) == 0) 1385*0Sstevel@tonic-gate dump = &old_version; 1386*0Sstevel@tonic-gate else if (strcmp(argv[aindex], b6option) == 0) 1387*0Sstevel@tonic-gate dump = &beta6_version; 1388*0Sstevel@tonic-gate else if (strcmp(argv[aindex], ovoption) == 0) 1389*0Sstevel@tonic-gate dump = &ov_version; 1390*0Sstevel@tonic-gate else if (!strcmp(argv[aindex], ipropoption)) { 1391*0Sstevel@tonic-gate if (log_ctx && log_ctx->iproprole) { 1392*0Sstevel@tonic-gate dump = &iprop_version; 1393*0Sstevel@tonic-gate /* 1394*0Sstevel@tonic-gate * dump_sno is used to indicate if the serial 1395*0Sstevel@tonic-gate * # should be populated in the output 1396*0Sstevel@tonic-gate * file to be used later by iprop for updating 1397*0Sstevel@tonic-gate * the slave's update log when loading 1398*0Sstevel@tonic-gate */ 1399*0Sstevel@tonic-gate dump_sno = TRUE; 1400*0Sstevel@tonic-gate } else { 1401*0Sstevel@tonic-gate fprintf(stderr, gettext("Iprop not enabled\n")); 1402*0Sstevel@tonic-gate exit_status++; 1403*0Sstevel@tonic-gate return; 1404*0Sstevel@tonic-gate } 1405*0Sstevel@tonic-gate } 1406*0Sstevel@tonic-gate else if (strcmp(argv[aindex], verboseoption) == 0) 1407*0Sstevel@tonic-gate arglist.verbose++; 1408*0Sstevel@tonic-gate else if (!strcmp(argv[aindex], "-mkey_convert")) 1409*0Sstevel@tonic-gate mkey_convert = 1; 1410*0Sstevel@tonic-gate else if (!strcmp(argv[aindex], "-new_mkey_file")) { 1411*0Sstevel@tonic-gate new_mkey_file = argv[++aindex]; 1412*0Sstevel@tonic-gate mkey_convert = 1; 1413*0Sstevel@tonic-gate } else 1414*0Sstevel@tonic-gate break; 1415*0Sstevel@tonic-gate } 1416*0Sstevel@tonic-gate 1417*0Sstevel@tonic-gate arglist.names = (char **) NULL; 1418*0Sstevel@tonic-gate arglist.nnames = 0; 1419*0Sstevel@tonic-gate if (aindex < argc) { 1420*0Sstevel@tonic-gate ofile = argv[aindex]; 1421*0Sstevel@tonic-gate aindex++; 1422*0Sstevel@tonic-gate if (aindex < argc) { 1423*0Sstevel@tonic-gate arglist.names = &argv[aindex]; 1424*0Sstevel@tonic-gate arglist.nnames = argc - aindex; 1425*0Sstevel@tonic-gate } 1426*0Sstevel@tonic-gate } 1427*0Sstevel@tonic-gate 1428*0Sstevel@tonic-gate /* 1429*0Sstevel@tonic-gate * Make sure the database is open. The policy database only has 1430*0Sstevel@tonic-gate * to be opened if we try a dump that uses it. 1431*0Sstevel@tonic-gate */ 1432*0Sstevel@tonic-gate if (!dbactive || (dump->dump_policy != NULL && policy_db == NULL)) { 1433*0Sstevel@tonic-gate com_err(argv[0], 0, Err_no_database); 1434*0Sstevel@tonic-gate exit_status++; 1435*0Sstevel@tonic-gate return; 1436*0Sstevel@tonic-gate } 1437*0Sstevel@tonic-gate 1438*0Sstevel@tonic-gate /* 1439*0Sstevel@tonic-gate * If we're doing a master key conversion, set up for it. 1440*0Sstevel@tonic-gate */ 1441*0Sstevel@tonic-gate if (mkey_convert) { 1442*0Sstevel@tonic-gate if (!valid_master_key) { 1443*0Sstevel@tonic-gate /* TRUE here means read the keyboard, but only once */ 1444*0Sstevel@tonic-gate retval = krb5_db_fetch_mkey(util_context, 1445*0Sstevel@tonic-gate master_princ, 1446*0Sstevel@tonic-gate global_params.enctype, 1447*0Sstevel@tonic-gate TRUE, FALSE, 1448*0Sstevel@tonic-gate (char *) NULL, 0, 1449*0Sstevel@tonic-gate &master_key); 1450*0Sstevel@tonic-gate if (retval) { 1451*0Sstevel@tonic-gate com_err(argv[0], retval, 1452*0Sstevel@tonic-gate gettext("while reading master key")); 1453*0Sstevel@tonic-gate exit(1); 1454*0Sstevel@tonic-gate } 1455*0Sstevel@tonic-gate retval = krb5_db_verify_master_key(util_context, 1456*0Sstevel@tonic-gate master_princ, 1457*0Sstevel@tonic-gate &master_key); 1458*0Sstevel@tonic-gate if (retval) { 1459*0Sstevel@tonic-gate com_err(argv[0], retval, 1460*0Sstevel@tonic-gate gettext("while verifying master key")); 1461*0Sstevel@tonic-gate exit(1); 1462*0Sstevel@tonic-gate } 1463*0Sstevel@tonic-gate } 1464*0Sstevel@tonic-gate if (!new_mkey_file) 1465*0Sstevel@tonic-gate printf(gettext("Please enter new master key....\n")); 1466*0Sstevel@tonic-gate 1467*0Sstevel@tonic-gate if ((retval = krb5_db_fetch_mkey(util_context, master_princ, 1468*0Sstevel@tonic-gate global_params.enctype, 1469*0Sstevel@tonic-gate !new_mkey_file, TRUE, 1470*0Sstevel@tonic-gate new_mkey_file, 0, 1471*0Sstevel@tonic-gate &new_master_key))) { 1472*0Sstevel@tonic-gate com_err(argv[0], retval, 1473*0Sstevel@tonic-gate gettext("while reading new master key")); 1474*0Sstevel@tonic-gate exit(1); 1475*0Sstevel@tonic-gate } 1476*0Sstevel@tonic-gate } 1477*0Sstevel@tonic-gate 1478*0Sstevel@tonic-gate kret = 0; 1479*0Sstevel@tonic-gate locked = 0; 1480*0Sstevel@tonic-gate if (ofile && strcmp(ofile, "-")) { 1481*0Sstevel@tonic-gate /* 1482*0Sstevel@tonic-gate * Make sure that we don't open and truncate on the fopen, 1483*0Sstevel@tonic-gate * since that may hose an on-going kprop process. 1484*0Sstevel@tonic-gate * 1485*0Sstevel@tonic-gate * We could also control this by opening for read and write, 1486*0Sstevel@tonic-gate * doing an flock with LOCK_EX, and then truncating the 1487*0Sstevel@tonic-gate * file once we have gotten the lock, but that would 1488*0Sstevel@tonic-gate * involve more OS dependencies than I want to get into. 1489*0Sstevel@tonic-gate */ 1490*0Sstevel@tonic-gate unlink(ofile); 1491*0Sstevel@tonic-gate if (!(f = fopen(ofile, "w"))) { 1492*0Sstevel@tonic-gate fprintf(stderr, gettext(ofopen_error), 1493*0Sstevel@tonic-gate programname, ofile, error_message(errno)); 1494*0Sstevel@tonic-gate exit_status++; 1495*0Sstevel@tonic-gate return; 1496*0Sstevel@tonic-gate } 1497*0Sstevel@tonic-gate if ((kret = krb5_lock_file(util_context, 1498*0Sstevel@tonic-gate fileno(f), 1499*0Sstevel@tonic-gate KRB5_LOCKMODE_EXCLUSIVE))) { 1500*0Sstevel@tonic-gate fprintf(stderr, gettext(oflock_error), 1501*0Sstevel@tonic-gate programname, ofile, error_message(kret)); 1502*0Sstevel@tonic-gate exit_status++; 1503*0Sstevel@tonic-gate } else 1504*0Sstevel@tonic-gate locked = 1; 1505*0Sstevel@tonic-gate } else { 1506*0Sstevel@tonic-gate f = stdout; 1507*0Sstevel@tonic-gate } 1508*0Sstevel@tonic-gate if (f && !(kret)) { 1509*0Sstevel@tonic-gate arglist.programname = programname; 1510*0Sstevel@tonic-gate arglist.ofile = f; 1511*0Sstevel@tonic-gate arglist.kcontext = util_context; 1512*0Sstevel@tonic-gate fprintf(arglist.ofile, "%s", dump->header); 1513*0Sstevel@tonic-gate 1514*0Sstevel@tonic-gate if (dump_sno) { 1515*0Sstevel@tonic-gate if (ulog_map(util_context, &global_params, FKCOMMAND)) { 1516*0Sstevel@tonic-gate fprintf(stderr, 1517*0Sstevel@tonic-gate gettext("%s: Could not map log\n"), programname); 1518*0Sstevel@tonic-gate exit_status++; 1519*0Sstevel@tonic-gate goto error; 1520*0Sstevel@tonic-gate } 1521*0Sstevel@tonic-gate 1522*0Sstevel@tonic-gate /* 1523*0Sstevel@tonic-gate * We grab the lock twice (once again in the iterator call), 1524*0Sstevel@tonic-gate * but that's ok since the lock func handles incr locks held. 1525*0Sstevel@tonic-gate */ 1526*0Sstevel@tonic-gate if (krb5_db_lock(util_context, KRB5_LOCKMODE_SHARED)) { 1527*0Sstevel@tonic-gate fprintf(stderr, 1528*0Sstevel@tonic-gate gettext("%s: Couldn't grab lock\n"), programname); 1529*0Sstevel@tonic-gate exit_status++; 1530*0Sstevel@tonic-gate goto error; 1531*0Sstevel@tonic-gate } 1532*0Sstevel@tonic-gate 1533*0Sstevel@tonic-gate fprintf(f, " %u", log_ctx->ulog->kdb_last_sno); 1534*0Sstevel@tonic-gate fprintf(f, " %u", log_ctx->ulog->kdb_last_time.seconds); 1535*0Sstevel@tonic-gate fprintf(f, " %u", log_ctx->ulog->kdb_last_time.useconds); 1536*0Sstevel@tonic-gate } 1537*0Sstevel@tonic-gate 1538*0Sstevel@tonic-gate if (dump->header[strlen(dump->header)-1] != '\n') 1539*0Sstevel@tonic-gate fputc('\n', arglist.ofile); 1540*0Sstevel@tonic-gate 1541*0Sstevel@tonic-gate if ((kret = krb5_dbm_db_iterate(util_context, 1542*0Sstevel@tonic-gate dump->dump_princ, 1543*0Sstevel@tonic-gate (krb5_pointer) &arglist))) { 1544*0Sstevel@tonic-gate fprintf(stderr, gettext(dumprec_err), 1545*0Sstevel@tonic-gate programname, dump->name, error_message(kret)); 1546*0Sstevel@tonic-gate exit_status++; 1547*0Sstevel@tonic-gate if (dump_sno) 1548*0Sstevel@tonic-gate (void) krb5_db_unlock(util_context); 1549*0Sstevel@tonic-gate } 1550*0Sstevel@tonic-gate if (dump->dump_policy && 1551*0Sstevel@tonic-gate (kret = osa_adb_iter_policy(policy_db, dump->dump_policy, 1552*0Sstevel@tonic-gate &arglist))) { 1553*0Sstevel@tonic-gate fprintf(stderr, gettext(dumprec_err), 1554*0Sstevel@tonic-gate programname, dump->name, 1555*0Sstevel@tonic-gate error_message(kret)); 1556*0Sstevel@tonic-gate exit_status++; 1557*0Sstevel@tonic-gate } 1558*0Sstevel@tonic-gate 1559*0Sstevel@tonic-gate error: 1560*0Sstevel@tonic-gate if (ofile && f != stdout && !exit_status) { 1561*0Sstevel@tonic-gate fclose(f); 1562*0Sstevel@tonic-gate update_ok_file(ofile); 1563*0Sstevel@tonic-gate } 1564*0Sstevel@tonic-gate } 1565*0Sstevel@tonic-gate if (locked) 1566*0Sstevel@tonic-gate (void) krb5_lock_file(util_context, 1567*0Sstevel@tonic-gate fileno(f), KRB5_LOCKMODE_UNLOCK); 1568*0Sstevel@tonic-gate } 1569*0Sstevel@tonic-gate 1570*0Sstevel@tonic-gate /* 1571*0Sstevel@tonic-gate * Read a string of bytes while counting the number of lines passed. 1572*0Sstevel@tonic-gate */ 1573*0Sstevel@tonic-gate static int 1574*0Sstevel@tonic-gate read_string(f, buf, len, lp) 1575*0Sstevel@tonic-gate FILE *f; 1576*0Sstevel@tonic-gate char *buf; 1577*0Sstevel@tonic-gate int len; 1578*0Sstevel@tonic-gate int *lp; 1579*0Sstevel@tonic-gate { 1580*0Sstevel@tonic-gate int c; 1581*0Sstevel@tonic-gate int i, retval; 1582*0Sstevel@tonic-gate 1583*0Sstevel@tonic-gate retval = 0; 1584*0Sstevel@tonic-gate for (i=0; i<len; i++) { 1585*0Sstevel@tonic-gate c = fgetc(f); 1586*0Sstevel@tonic-gate if (c < 0) { 1587*0Sstevel@tonic-gate retval = 1; 1588*0Sstevel@tonic-gate break; 1589*0Sstevel@tonic-gate } 1590*0Sstevel@tonic-gate if (c == '\n') 1591*0Sstevel@tonic-gate (*lp)++; 1592*0Sstevel@tonic-gate buf[i] = (char) c; 1593*0Sstevel@tonic-gate } 1594*0Sstevel@tonic-gate buf[len] = '\0'; 1595*0Sstevel@tonic-gate return(retval); 1596*0Sstevel@tonic-gate } 1597*0Sstevel@tonic-gate 1598*0Sstevel@tonic-gate /* 1599*0Sstevel@tonic-gate * Read a string of two character representations of bytes. 1600*0Sstevel@tonic-gate */ 1601*0Sstevel@tonic-gate static int 1602*0Sstevel@tonic-gate read_octet_string(f, buf, len) 1603*0Sstevel@tonic-gate FILE *f; 1604*0Sstevel@tonic-gate krb5_octet *buf; 1605*0Sstevel@tonic-gate int len; 1606*0Sstevel@tonic-gate { 1607*0Sstevel@tonic-gate int c; 1608*0Sstevel@tonic-gate int i, retval; 1609*0Sstevel@tonic-gate 1610*0Sstevel@tonic-gate retval = 0; 1611*0Sstevel@tonic-gate for (i=0; i<len; i++) { 1612*0Sstevel@tonic-gate if (fscanf(f, "%02x", &c) != 1) { 1613*0Sstevel@tonic-gate retval = 1; 1614*0Sstevel@tonic-gate break; 1615*0Sstevel@tonic-gate } 1616*0Sstevel@tonic-gate buf[i] = (krb5_octet) c; 1617*0Sstevel@tonic-gate } 1618*0Sstevel@tonic-gate return(retval); 1619*0Sstevel@tonic-gate } 1620*0Sstevel@tonic-gate 1621*0Sstevel@tonic-gate /* 1622*0Sstevel@tonic-gate * Find the end of an old format record. 1623*0Sstevel@tonic-gate */ 1624*0Sstevel@tonic-gate static void 1625*0Sstevel@tonic-gate find_record_end(f, fn, lineno) 1626*0Sstevel@tonic-gate FILE *f; 1627*0Sstevel@tonic-gate char *fn; 1628*0Sstevel@tonic-gate int lineno; 1629*0Sstevel@tonic-gate { 1630*0Sstevel@tonic-gate int ch; 1631*0Sstevel@tonic-gate 1632*0Sstevel@tonic-gate if (((ch = fgetc(f)) != ';') || ((ch = fgetc(f)) != '\n')) { 1633*0Sstevel@tonic-gate fprintf(stderr, gettext(trash_end_fmt), fn, lineno); 1634*0Sstevel@tonic-gate while (ch != '\n') { 1635*0Sstevel@tonic-gate putc(ch, stderr); 1636*0Sstevel@tonic-gate ch = fgetc(f); 1637*0Sstevel@tonic-gate } 1638*0Sstevel@tonic-gate putc(ch, stderr); 1639*0Sstevel@tonic-gate } 1640*0Sstevel@tonic-gate } 1641*0Sstevel@tonic-gate 1642*0Sstevel@tonic-gate #if 0 1643*0Sstevel@tonic-gate /* 1644*0Sstevel@tonic-gate * update_tl_data() - Generate the tl_data entries. 1645*0Sstevel@tonic-gate */ 1646*0Sstevel@tonic-gate static krb5_error_code 1647*0Sstevel@tonic-gate update_tl_data(kcontext, dbentp, mod_name, mod_date, last_pwd_change) 1648*0Sstevel@tonic-gate krb5_context kcontext; 1649*0Sstevel@tonic-gate krb5_db_entry *dbentp; 1650*0Sstevel@tonic-gate krb5_principal mod_name; 1651*0Sstevel@tonic-gate krb5_timestamp mod_date; 1652*0Sstevel@tonic-gate krb5_timestamp last_pwd_change; 1653*0Sstevel@tonic-gate { 1654*0Sstevel@tonic-gate krb5_error_code kret; 1655*0Sstevel@tonic-gate 1656*0Sstevel@tonic-gate kret = 0 ; 1657*0Sstevel@tonic-gate 1658*0Sstevel@tonic-gate /* 1659*0Sstevel@tonic-gate * Handle modification principal. 1660*0Sstevel@tonic-gate */ 1661*0Sstevel@tonic-gate if (mod_name) { 1662*0Sstevel@tonic-gate krb5_tl_mod_princ mprinc; 1663*0Sstevel@tonic-gate 1664*0Sstevel@tonic-gate memset(&mprinc, 0, sizeof(mprinc)); 1665*0Sstevel@tonic-gate if (!(kret = krb5_copy_principal(kcontext, 1666*0Sstevel@tonic-gate mod_name, 1667*0Sstevel@tonic-gate &mprinc.mod_princ))) { 1668*0Sstevel@tonic-gate mprinc.mod_date = mod_date; 1669*0Sstevel@tonic-gate kret = krb5_dbe_encode_mod_princ_data(kcontext, 1670*0Sstevel@tonic-gate &mprinc, 1671*0Sstevel@tonic-gate dbentp); 1672*0Sstevel@tonic-gate } 1673*0Sstevel@tonic-gate if (mprinc.mod_princ) 1674*0Sstevel@tonic-gate krb5_free_principal(kcontext, mprinc.mod_princ); 1675*0Sstevel@tonic-gate } 1676*0Sstevel@tonic-gate /* 1677*0Sstevel@tonic-gate * Handle last password change. 1678*0Sstevel@tonic-gate */ 1679*0Sstevel@tonic-gate if (!kret) { 1680*0Sstevel@tonic-gate krb5_tl_data *pwchg; 1681*0Sstevel@tonic-gate krb5_boolean linked; 1682*0Sstevel@tonic-gate 1683*0Sstevel@tonic-gate /* Find a previously existing entry */ 1684*0Sstevel@tonic-gate for (pwchg = dbentp->tl_data; 1685*0Sstevel@tonic-gate (pwchg) && (pwchg->tl_data_type != KRB5_TL_LAST_PWD_CHANGE); 1686*0Sstevel@tonic-gate pwchg = pwchg->tl_data_next); 1687*0Sstevel@tonic-gate 1688*0Sstevel@tonic-gate /* Check to see if we found one. */ 1689*0Sstevel@tonic-gate linked = 0; 1690*0Sstevel@tonic-gate if (!pwchg) { 1691*0Sstevel@tonic-gate /* No, allocate a new one */ 1692*0Sstevel@tonic-gate if ((pwchg = (krb5_tl_data *) 1693*0Sstevel@tonic-gate malloc(sizeof (krb5_tl_data)))) { 1694*0Sstevel@tonic-gate memset(pwchg, 0, sizeof(krb5_tl_data)); 1695*0Sstevel@tonic-gate if (!(pwchg->tl_data_contents = 1696*0Sstevel@tonic-gate (krb5_octet *) malloc(sizeof (krb5_timestamp)))) { 1697*0Sstevel@tonic-gate free(pwchg); 1698*0Sstevel@tonic-gate pwchg = (krb5_tl_data *) NULL; 1699*0Sstevel@tonic-gate } else { 1700*0Sstevel@tonic-gate pwchg->tl_data_type = KRB5_TL_LAST_PWD_CHANGE; 1701*0Sstevel@tonic-gate pwchg->tl_data_length = 1702*0Sstevel@tonic-gate (krb5_int16) sizeof (krb5_timestamp); 1703*0Sstevel@tonic-gate } 1704*0Sstevel@tonic-gate } 1705*0Sstevel@tonic-gate } else 1706*0Sstevel@tonic-gate linked = 1; 1707*0Sstevel@tonic-gate 1708*0Sstevel@tonic-gate /* Do we have an entry? */ 1709*0Sstevel@tonic-gate if (pwchg && pwchg->tl_data_contents) { 1710*0Sstevel@tonic-gate /* Encode it */ 1711*0Sstevel@tonic-gate krb5_kdb_encode_int32(last_pwd_change, 1712*0Sstevel@tonic-gate pwchg->tl_data_contents); 1713*0Sstevel@tonic-gate /* Link it in if necessary */ 1714*0Sstevel@tonic-gate if (!linked) { 1715*0Sstevel@tonic-gate pwchg->tl_data_next = dbentp->tl_data; 1716*0Sstevel@tonic-gate dbentp->tl_data = pwchg; 1717*0Sstevel@tonic-gate dbentp->n_tl_data++; 1718*0Sstevel@tonic-gate } 1719*0Sstevel@tonic-gate } else 1720*0Sstevel@tonic-gate kret = ENOMEM; 1721*0Sstevel@tonic-gate } 1722*0Sstevel@tonic-gate return(kret); 1723*0Sstevel@tonic-gate } 1724*0Sstevel@tonic-gate 1725*0Sstevel@tonic-gate #endif 1726*0Sstevel@tonic-gate 1727*0Sstevel@tonic-gate static int 1728*0Sstevel@tonic-gate k5beta_parse_and_store(char *fname, krb5_context kcontext, int verbose, 1729*0Sstevel@tonic-gate int *linenop, krb5_db_entry *dbent, 1730*0Sstevel@tonic-gate char *name, char *mod_name, 1731*0Sstevel@tonic-gate krb5_timestamp last_pwd_change, 1732*0Sstevel@tonic-gate krb5_timestamp mod_date 1733*0Sstevel@tonic-gate ) 1734*0Sstevel@tonic-gate { 1735*0Sstevel@tonic-gate int error; 1736*0Sstevel@tonic-gate int retval = 1; 1737*0Sstevel@tonic-gate krb5_error_code kret; 1738*0Sstevel@tonic-gate krb5_principal mod_princ; 1739*0Sstevel@tonic-gate krb5_key_data *pkey, *akey; 1740*0Sstevel@tonic-gate 1741*0Sstevel@tonic-gate pkey = &dbent->key_data[0]; 1742*0Sstevel@tonic-gate akey = &dbent->key_data[1]; 1743*0Sstevel@tonic-gate 1744*0Sstevel@tonic-gate if (!(kret = krb5_parse_name(kcontext, name, &dbent->princ))) { 1745*0Sstevel@tonic-gate if (!(kret = 1746*0Sstevel@tonic-gate krb5_parse_name(kcontext, mod_name, &mod_princ))) { 1747*0Sstevel@tonic-gate if (!(kret = krb5_dbe_update_mod_princ_data( 1748*0Sstevel@tonic-gate kcontext, dbent, 1749*0Sstevel@tonic-gate mod_date, mod_princ)) && 1750*0Sstevel@tonic-gate !(kret = krb5_dbe_update_last_pwd_change( 1751*0Sstevel@tonic-gate kcontext, dbent, last_pwd_change))) { 1752*0Sstevel@tonic-gate int one = 1; 1753*0Sstevel@tonic-gate 1754*0Sstevel@tonic-gate dbent->len = KRB5_KDB_V1_BASE_LENGTH; 1755*0Sstevel@tonic-gate pkey->key_data_ver = 1756*0Sstevel@tonic-gate (pkey->key_data_type[1] || 1757*0Sstevel@tonic-gate pkey->key_data_length[1]) ? 2 : 1; 1758*0Sstevel@tonic-gate akey->key_data_ver = 1759*0Sstevel@tonic-gate (akey->key_data_type[1] || 1760*0Sstevel@tonic-gate akey->key_data_length[1]) ? 2 : 1; 1761*0Sstevel@tonic-gate if ((pkey->key_data_type[0] == 1762*0Sstevel@tonic-gate akey->key_data_type[0]) && 1763*0Sstevel@tonic-gate (pkey->key_data_type[1] == 1764*0Sstevel@tonic-gate akey->key_data_type[1])) 1765*0Sstevel@tonic-gate dbent->n_key_data--; 1766*0Sstevel@tonic-gate else if ((akey->key_data_type[0] == 0) && 1767*0Sstevel@tonic-gate (akey->key_data_length[0] == 0) && 1768*0Sstevel@tonic-gate (akey->key_data_type[1] == 0) && 1769*0Sstevel@tonic-gate (akey->key_data_length[1] == 0)) 1770*0Sstevel@tonic-gate dbent->n_key_data--; 1771*0Sstevel@tonic-gate if ((kret = krb5_db_put_principal( 1772*0Sstevel@tonic-gate kcontext, dbent, &one)) || 1773*0Sstevel@tonic-gate (one != 1)) { 1774*0Sstevel@tonic-gate fprintf(stderr, gettext(store_err_fmt), 1775*0Sstevel@tonic-gate fname, *linenop, name, 1776*0Sstevel@tonic-gate error_message(kret)); 1777*0Sstevel@tonic-gate error++; 1778*0Sstevel@tonic-gate } else { 1779*0Sstevel@tonic-gate if (verbose) 1780*0Sstevel@tonic-gate fprintf(stderr, 1781*0Sstevel@tonic-gate gettext(add_princ_fmt), 1782*0Sstevel@tonic-gate name); 1783*0Sstevel@tonic-gate retval = 0; 1784*0Sstevel@tonic-gate } 1785*0Sstevel@tonic-gate dbent->n_key_data = 2; 1786*0Sstevel@tonic-gate } 1787*0Sstevel@tonic-gate krb5_free_principal(kcontext, mod_princ); 1788*0Sstevel@tonic-gate } else { 1789*0Sstevel@tonic-gate fprintf(stderr, 1790*0Sstevel@tonic-gate gettext(parse_err_fmt), 1791*0Sstevel@tonic-gate fname, *linenop, mod_name, 1792*0Sstevel@tonic-gate error_message(kret)); 1793*0Sstevel@tonic-gate error++; 1794*0Sstevel@tonic-gate } 1795*0Sstevel@tonic-gate } else { 1796*0Sstevel@tonic-gate fprintf(stderr, gettext(parse_err_fmt), 1797*0Sstevel@tonic-gate fname, *linenop, name, 1798*0Sstevel@tonic-gate error_message(kret)); 1799*0Sstevel@tonic-gate error++; 1800*0Sstevel@tonic-gate } 1801*0Sstevel@tonic-gate 1802*0Sstevel@tonic-gate return (retval); 1803*0Sstevel@tonic-gate } 1804*0Sstevel@tonic-gate 1805*0Sstevel@tonic-gate /* 1806*0Sstevel@tonic-gate * process_k5beta_record() - Handle a dump record in old format. 1807*0Sstevel@tonic-gate * 1808*0Sstevel@tonic-gate * Returns -1 for end of file, 0 for success and 1 for failure. 1809*0Sstevel@tonic-gate */ 1810*0Sstevel@tonic-gate static int 1811*0Sstevel@tonic-gate process_k5beta_record(fname, kcontext, filep, verbose, linenop, pol_db) 1812*0Sstevel@tonic-gate char *fname; 1813*0Sstevel@tonic-gate krb5_context kcontext; 1814*0Sstevel@tonic-gate FILE *filep; 1815*0Sstevel@tonic-gate int verbose; 1816*0Sstevel@tonic-gate int *linenop; 1817*0Sstevel@tonic-gate void *pol_db; 1818*0Sstevel@tonic-gate { 1819*0Sstevel@tonic-gate int nmatched; 1820*0Sstevel@tonic-gate int retval; 1821*0Sstevel@tonic-gate krb5_db_entry dbent; 1822*0Sstevel@tonic-gate int name_len, mod_name_len, key_len; 1823*0Sstevel@tonic-gate int alt_key_len, salt_len, alt_salt_len; 1824*0Sstevel@tonic-gate char *name; 1825*0Sstevel@tonic-gate char *mod_name; 1826*0Sstevel@tonic-gate int tmpint1, tmpint2, tmpint3; 1827*0Sstevel@tonic-gate int error; 1828*0Sstevel@tonic-gate const char *try2read; 1829*0Sstevel@tonic-gate int i; 1830*0Sstevel@tonic-gate krb5_key_data *pkey, *akey; 1831*0Sstevel@tonic-gate krb5_timestamp last_pwd_change, mod_date; 1832*0Sstevel@tonic-gate krb5_principal mod_princ; 1833*0Sstevel@tonic-gate krb5_error_code kret; 1834*0Sstevel@tonic-gate krb5_octet *shortcopy1 = NULL; /* SUNWresync121 memleak fix */ 1835*0Sstevel@tonic-gate krb5_octet *shortcopy2 = NULL; 1836*0Sstevel@tonic-gate 1837*0Sstevel@tonic-gate try2read = (char *) NULL; 1838*0Sstevel@tonic-gate (*linenop)++; 1839*0Sstevel@tonic-gate retval = 1; 1840*0Sstevel@tonic-gate memset((char *)&dbent, 0, sizeof(dbent)); 1841*0Sstevel@tonic-gate 1842*0Sstevel@tonic-gate /* Make sure we've got key_data entries */ 1843*0Sstevel@tonic-gate if (krb5_dbe_create_key_data(kcontext, &dbent) || 1844*0Sstevel@tonic-gate krb5_dbe_create_key_data(kcontext, &dbent)) { 1845*0Sstevel@tonic-gate krb5_db_free_principal(kcontext, &dbent, 1); 1846*0Sstevel@tonic-gate return(1); 1847*0Sstevel@tonic-gate } 1848*0Sstevel@tonic-gate pkey = &dbent.key_data[0]; 1849*0Sstevel@tonic-gate akey = &dbent.key_data[1]; 1850*0Sstevel@tonic-gate 1851*0Sstevel@tonic-gate /* 1852*0Sstevel@tonic-gate * Match the sizes. 6 tokens to match. 1853*0Sstevel@tonic-gate */ 1854*0Sstevel@tonic-gate nmatched = fscanf(filep, "%d\t%d\t%d\t%d\t%d\t%d\t", 1855*0Sstevel@tonic-gate &name_len, &mod_name_len, &key_len, 1856*0Sstevel@tonic-gate &alt_key_len, &salt_len, &alt_salt_len); 1857*0Sstevel@tonic-gate if (nmatched == 6) { 1858*0Sstevel@tonic-gate pkey->key_data_length[0] = key_len; 1859*0Sstevel@tonic-gate akey->key_data_length[0] = alt_key_len; 1860*0Sstevel@tonic-gate pkey->key_data_length[1] = salt_len; 1861*0Sstevel@tonic-gate akey->key_data_length[1] = alt_salt_len; 1862*0Sstevel@tonic-gate name = (char *) NULL; 1863*0Sstevel@tonic-gate mod_name = (char *) NULL; 1864*0Sstevel@tonic-gate /* 1865*0Sstevel@tonic-gate * Get the memory for the variable length fields. 1866*0Sstevel@tonic-gate */ 1867*0Sstevel@tonic-gate if ((name = (char *) malloc((size_t) (name_len + 1))) && 1868*0Sstevel@tonic-gate (mod_name = (char *) malloc((size_t) (mod_name_len + 1))) && 1869*0Sstevel@tonic-gate (!key_len || 1870*0Sstevel@tonic-gate (pkey->key_data_contents[0] = 1871*0Sstevel@tonic-gate (krb5_octet *) malloc((size_t) (key_len + 1)))) && 1872*0Sstevel@tonic-gate (!alt_key_len || 1873*0Sstevel@tonic-gate (akey->key_data_contents[0] = 1874*0Sstevel@tonic-gate (krb5_octet *) 1875*0Sstevel@tonic-gate malloc((size_t) (alt_key_len + 1)))) && 1876*0Sstevel@tonic-gate (!salt_len || 1877*0Sstevel@tonic-gate (pkey->key_data_contents[1] = 1878*0Sstevel@tonic-gate (krb5_octet *) malloc((size_t) (salt_len + 1)))) && 1879*0Sstevel@tonic-gate (!alt_salt_len || 1880*0Sstevel@tonic-gate (akey->key_data_contents[1] = 1881*0Sstevel@tonic-gate (krb5_octet *) 1882*0Sstevel@tonic-gate malloc((size_t) (alt_salt_len + 1))))) { 1883*0Sstevel@tonic-gate error = 0; 1884*0Sstevel@tonic-gate 1885*0Sstevel@tonic-gate /* Read the principal name */ 1886*0Sstevel@tonic-gate if (read_string(filep, name, name_len, linenop)) { 1887*0Sstevel@tonic-gate try2read = read_name_string; 1888*0Sstevel@tonic-gate error++; 1889*0Sstevel@tonic-gate } 1890*0Sstevel@tonic-gate /* Read the key type */ 1891*0Sstevel@tonic-gate if (!error && 1892*0Sstevel@tonic-gate (fscanf(filep, "\t%d\t", &tmpint1) != 1)) { 1893*0Sstevel@tonic-gate try2read = read_key_type; 1894*0Sstevel@tonic-gate error++; 1895*0Sstevel@tonic-gate } 1896*0Sstevel@tonic-gate pkey->key_data_type[0] = tmpint1; 1897*0Sstevel@tonic-gate /* Read the old format key */ 1898*0Sstevel@tonic-gate if (!error && read_octet_string(filep, 1899*0Sstevel@tonic-gate pkey->key_data_contents[0], 1900*0Sstevel@tonic-gate pkey->key_data_length[0])) { 1901*0Sstevel@tonic-gate try2read = read_key_data; 1902*0Sstevel@tonic-gate error++; 1903*0Sstevel@tonic-gate } 1904*0Sstevel@tonic-gate /* convert to a new format key */ 1905*0Sstevel@tonic-gate /* 1906*0Sstevel@tonic-gate * the encrypted version is stored as the 1907*0Sstevel@tonic-gate * unencrypted key length (4 bytes, MSB first) 1908*0Sstevel@tonic-gate * followed by the encrypted key. 1909*0Sstevel@tonic-gate */ 1910*0Sstevel@tonic-gate if ((pkey->key_data_length[0] > 4) && 1911*0Sstevel@tonic-gate (pkey->key_data_contents[0][0] == 0) && 1912*0Sstevel@tonic-gate (pkey->key_data_contents[0][1] == 0)) { 1913*0Sstevel@tonic-gate /* 1914*0Sstevel@tonic-gate * this really does look like an old key, 1915*0Sstevel@tonic-gate * so drop and swap 1916*0Sstevel@tonic-gate */ 1917*0Sstevel@tonic-gate /* 1918*0Sstevel@tonic-gate * the *new* length is 2 bytes, LSB first, 1919*0Sstevel@tonic-gate * sigh. 1920*0Sstevel@tonic-gate */ 1921*0Sstevel@tonic-gate size_t shortlen = pkey->key_data_length[0] - 4 + 2; 1922*0Sstevel@tonic-gate krb5_octet *origdata = pkey->key_data_contents[0]; 1923*0Sstevel@tonic-gate 1924*0Sstevel@tonic-gate shortcopy1 = (krb5_octet *) malloc(shortlen); 1925*0Sstevel@tonic-gate if (shortcopy1) { 1926*0Sstevel@tonic-gate shortcopy1[0] = origdata[3]; 1927*0Sstevel@tonic-gate shortcopy1[1] = origdata[2]; 1928*0Sstevel@tonic-gate memcpy(shortcopy1 + 2, origdata + 4, shortlen - 2); 1929*0Sstevel@tonic-gate free(origdata); 1930*0Sstevel@tonic-gate pkey->key_data_length[0] = shortlen; 1931*0Sstevel@tonic-gate pkey->key_data_contents[0] = shortcopy1; 1932*0Sstevel@tonic-gate } else { 1933*0Sstevel@tonic-gate fprintf(stderr, gettext(no_mem_fmt), fname, *linenop); 1934*0Sstevel@tonic-gate error++; 1935*0Sstevel@tonic-gate } 1936*0Sstevel@tonic-gate } 1937*0Sstevel@tonic-gate /* Read principal attributes */ 1938*0Sstevel@tonic-gate if (!error && 1939*0Sstevel@tonic-gate (fscanf(filep, "\t%u\t%u\t%u\t%u\t%u\t%u" 1940*0Sstevel@tonic-gate "\t%u\t%u\t%u\t%u\t", 1941*0Sstevel@tonic-gate &tmpint1, &dbent.max_life, 1942*0Sstevel@tonic-gate &dbent.max_renewable_life, 1943*0Sstevel@tonic-gate &tmpint2, &dbent.expiration, 1944*0Sstevel@tonic-gate &dbent.pw_expiration, &last_pwd_change, 1945*0Sstevel@tonic-gate &dbent.last_success, &dbent.last_failed, 1946*0Sstevel@tonic-gate &tmpint3) != 10)) { 1947*0Sstevel@tonic-gate try2read = read_pr_data1; 1948*0Sstevel@tonic-gate error++; 1949*0Sstevel@tonic-gate } 1950*0Sstevel@tonic-gate pkey->key_data_kvno = tmpint1; 1951*0Sstevel@tonic-gate dbent.fail_auth_count = tmpint3; 1952*0Sstevel@tonic-gate /* Read modifier name */ 1953*0Sstevel@tonic-gate if (!error && read_string(filep, 1954*0Sstevel@tonic-gate mod_name, 1955*0Sstevel@tonic-gate mod_name_len, 1956*0Sstevel@tonic-gate linenop)) { 1957*0Sstevel@tonic-gate try2read = read_mod_name; 1958*0Sstevel@tonic-gate error++; 1959*0Sstevel@tonic-gate } 1960*0Sstevel@tonic-gate /* Read second set of attributes */ 1961*0Sstevel@tonic-gate if (!error && (fscanf(filep, "\t%u\t%u\t%u\t", 1962*0Sstevel@tonic-gate &mod_date, &dbent.attributes, 1963*0Sstevel@tonic-gate &tmpint1) != 3)) { 1964*0Sstevel@tonic-gate try2read = read_pr_data2; 1965*0Sstevel@tonic-gate error++; 1966*0Sstevel@tonic-gate } 1967*0Sstevel@tonic-gate pkey->key_data_type[1] = tmpint1; 1968*0Sstevel@tonic-gate /* Read salt data */ 1969*0Sstevel@tonic-gate if (!error && read_octet_string(filep, 1970*0Sstevel@tonic-gate pkey->key_data_contents[1], 1971*0Sstevel@tonic-gate pkey->key_data_length[1])) { 1972*0Sstevel@tonic-gate try2read = read_salt_data; 1973*0Sstevel@tonic-gate error++; 1974*0Sstevel@tonic-gate } 1975*0Sstevel@tonic-gate /* Read alternate key type */ 1976*0Sstevel@tonic-gate if (!error && 1977*0Sstevel@tonic-gate (fscanf(filep, "\t%u\t", &tmpint1) != 1)) { 1978*0Sstevel@tonic-gate try2read = read_akey_type; 1979*0Sstevel@tonic-gate error++; 1980*0Sstevel@tonic-gate } 1981*0Sstevel@tonic-gate akey->key_data_type[0] = tmpint1; 1982*0Sstevel@tonic-gate /* Read alternate key */ 1983*0Sstevel@tonic-gate if (!error && read_octet_string(filep, 1984*0Sstevel@tonic-gate akey->key_data_contents[0], 1985*0Sstevel@tonic-gate akey->key_data_length[0])) { 1986*0Sstevel@tonic-gate try2read = read_akey_data; 1987*0Sstevel@tonic-gate error++; 1988*0Sstevel@tonic-gate } 1989*0Sstevel@tonic-gate /* convert to a new format key */ 1990*0Sstevel@tonic-gate /* 1991*0Sstevel@tonic-gate * the encrypted version is stored as the 1992*0Sstevel@tonic-gate * unencrypted key length (4 bytes, MSB first) 1993*0Sstevel@tonic-gate * followed by the encrypted key. 1994*0Sstevel@tonic-gate */ 1995*0Sstevel@tonic-gate if ((akey->key_data_length[0] > 4) && 1996*0Sstevel@tonic-gate (akey->key_data_contents[0][0] == 0) && 1997*0Sstevel@tonic-gate (akey->key_data_contents[0][1] == 0)) { 1998*0Sstevel@tonic-gate /* 1999*0Sstevel@tonic-gate * this really does look like an old key, 2000*0Sstevel@tonic-gate * so drop and swap 2001*0Sstevel@tonic-gate */ 2002*0Sstevel@tonic-gate /* 2003*0Sstevel@tonic-gate * the *new* length is 2 bytes, LSB first, 2004*0Sstevel@tonic-gate * sigh. 2005*0Sstevel@tonic-gate */ 2006*0Sstevel@tonic-gate size_t shortlen = akey->key_data_length[0] - 4 + 2; 2007*0Sstevel@tonic-gate 2008*0Sstevel@tonic-gate krb5_octet *origdata = akey->key_data_contents[0]; 2009*0Sstevel@tonic-gate 2010*0Sstevel@tonic-gate shortcopy2 = (krb5_octet *) malloc(shortlen); 2011*0Sstevel@tonic-gate if (shortcopy2) { 2012*0Sstevel@tonic-gate shortcopy2[0] = origdata[3]; 2013*0Sstevel@tonic-gate shortcopy2[1] = origdata[2]; 2014*0Sstevel@tonic-gate memcpy(shortcopy2 + 2, 2015*0Sstevel@tonic-gate origdata + 4, shortlen - 2); 2016*0Sstevel@tonic-gate free(origdata); 2017*0Sstevel@tonic-gate akey->key_data_length[0] = shortlen; 2018*0Sstevel@tonic-gate akey->key_data_contents[0] = shortcopy2; 2019*0Sstevel@tonic-gate } else { 2020*0Sstevel@tonic-gate fprintf(stderr, gettext(no_mem_fmt), fname, *linenop); 2021*0Sstevel@tonic-gate error++; 2022*0Sstevel@tonic-gate } 2023*0Sstevel@tonic-gate } 2024*0Sstevel@tonic-gate /* Read alternate salt type */ 2025*0Sstevel@tonic-gate if (!error && 2026*0Sstevel@tonic-gate (fscanf(filep, "\t%u\t", &tmpint1) != 1)) { 2027*0Sstevel@tonic-gate try2read = read_asalt_type; 2028*0Sstevel@tonic-gate error++; 2029*0Sstevel@tonic-gate } 2030*0Sstevel@tonic-gate akey->key_data_type[1] = tmpint1; 2031*0Sstevel@tonic-gate /* Read alternate salt data */ 2032*0Sstevel@tonic-gate if (!error && read_octet_string(filep, 2033*0Sstevel@tonic-gate akey->key_data_contents[1], 2034*0Sstevel@tonic-gate akey->key_data_length[1])) { 2035*0Sstevel@tonic-gate try2read = read_asalt_data; 2036*0Sstevel@tonic-gate error++; 2037*0Sstevel@tonic-gate } 2038*0Sstevel@tonic-gate /* Read expansion data - discard it */ 2039*0Sstevel@tonic-gate if (!error) { 2040*0Sstevel@tonic-gate for (i=0; i<8; i++) { 2041*0Sstevel@tonic-gate if (fscanf(filep, 2042*0Sstevel@tonic-gate "\t%u", &tmpint1) != 1) { 2043*0Sstevel@tonic-gate try2read = read_exp_data; 2044*0Sstevel@tonic-gate error++; 2045*0Sstevel@tonic-gate break; 2046*0Sstevel@tonic-gate } 2047*0Sstevel@tonic-gate } 2048*0Sstevel@tonic-gate if (!error) 2049*0Sstevel@tonic-gate find_record_end(filep, fname, *linenop); 2050*0Sstevel@tonic-gate } 2051*0Sstevel@tonic-gate /* 2052*0Sstevel@tonic-gate * If no error, then we're done reading. Now parse 2053*0Sstevel@tonic-gate * the names and store the database dbent. 2054*0Sstevel@tonic-gate */ 2055*0Sstevel@tonic-gate if (!error) { 2056*0Sstevel@tonic-gate retval = k5beta_parse_and_store( 2057*0Sstevel@tonic-gate fname, kcontext, verbose, 2058*0Sstevel@tonic-gate linenop, &dbent, name, mod_name, 2059*0Sstevel@tonic-gate last_pwd_change, mod_date); 2060*0Sstevel@tonic-gate } else { 2061*0Sstevel@tonic-gate fprintf(stderr, gettext(read_err_fmt), 2062*0Sstevel@tonic-gate fname, *linenop, try2read); 2063*0Sstevel@tonic-gate } 2064*0Sstevel@tonic-gate } else { 2065*0Sstevel@tonic-gate fprintf(stderr, gettext(no_mem_fmt), fname, *linenop); 2066*0Sstevel@tonic-gate } 2067*0Sstevel@tonic-gate 2068*0Sstevel@tonic-gate krb5_db_free_principal(kcontext, &dbent, 1); 2069*0Sstevel@tonic-gate if (mod_name) 2070*0Sstevel@tonic-gate free(mod_name); 2071*0Sstevel@tonic-gate if (name) 2072*0Sstevel@tonic-gate free(name); 2073*0Sstevel@tonic-gate } else { 2074*0Sstevel@tonic-gate if (nmatched != EOF) 2075*0Sstevel@tonic-gate fprintf(stderr, gettext(rhead_err_fmt), 2076*0Sstevel@tonic-gate fname, *linenop); 2077*0Sstevel@tonic-gate else 2078*0Sstevel@tonic-gate retval = -1; 2079*0Sstevel@tonic-gate } 2080*0Sstevel@tonic-gate 2081*0Sstevel@tonic-gate if (shortcopy1) 2082*0Sstevel@tonic-gate free(shortcopy1); 2083*0Sstevel@tonic-gate if (shortcopy2) 2084*0Sstevel@tonic-gate free(shortcopy2); 2085*0Sstevel@tonic-gate 2086*0Sstevel@tonic-gate return (retval); 2087*0Sstevel@tonic-gate } 2088*0Sstevel@tonic-gate 2089*0Sstevel@tonic-gate static int 2090*0Sstevel@tonic-gate get_k5beta6_tag_data(FILE *filep, krb5_db_entry dbentry, const char **try2read) 2091*0Sstevel@tonic-gate { 2092*0Sstevel@tonic-gate int error = 0; 2093*0Sstevel@tonic-gate int i; 2094*0Sstevel@tonic-gate 2095*0Sstevel@tonic-gate krb5_int32 t1, t2, t3, t4, t5, t6, t7, t8, t9; 2096*0Sstevel@tonic-gate int nread; 2097*0Sstevel@tonic-gate krb5_tl_data *tl; 2098*0Sstevel@tonic-gate 2099*0Sstevel@tonic-gate for (tl = dbentry.tl_data; tl; tl = tl->tl_data_next) { 2100*0Sstevel@tonic-gate nread = fscanf(filep, "%d\t%d\t", &t1, &t2); 2101*0Sstevel@tonic-gate if (nread == 2) { 2102*0Sstevel@tonic-gate tl->tl_data_type = (krb5_int16) t1; 2103*0Sstevel@tonic-gate tl->tl_data_length = (krb5_int16) t2; 2104*0Sstevel@tonic-gate if (tl->tl_data_length) { 2105*0Sstevel@tonic-gate if (!(tl->tl_data_contents = 2106*0Sstevel@tonic-gate (krb5_octet *) 2107*0Sstevel@tonic-gate malloc((size_t) t2 + 1)) || 2108*0Sstevel@tonic-gate read_octet_string(filep, 2109*0Sstevel@tonic-gate tl->tl_data_contents, t2)) { 2110*0Sstevel@tonic-gate *try2read = read_tcontents; 2111*0Sstevel@tonic-gate error++; 2112*0Sstevel@tonic-gate break; 2113*0Sstevel@tonic-gate } 2114*0Sstevel@tonic-gate } else { 2115*0Sstevel@tonic-gate /* Should be a null field */ 2116*0Sstevel@tonic-gate nread = fscanf(filep, "%d", &t9); 2117*0Sstevel@tonic-gate if ((nread != 1) || (t9 != -1)) { 2118*0Sstevel@tonic-gate error++; 2119*0Sstevel@tonic-gate *try2read = read_tcontents; 2120*0Sstevel@tonic-gate break; 2121*0Sstevel@tonic-gate } 2122*0Sstevel@tonic-gate } 2123*0Sstevel@tonic-gate } else { 2124*0Sstevel@tonic-gate *try2read = read_ttypelen; 2125*0Sstevel@tonic-gate error++; 2126*0Sstevel@tonic-gate break; 2127*0Sstevel@tonic-gate } 2128*0Sstevel@tonic-gate } 2129*0Sstevel@tonic-gate 2130*0Sstevel@tonic-gate return (error); 2131*0Sstevel@tonic-gate } 2132*0Sstevel@tonic-gate 2133*0Sstevel@tonic-gate static int 2134*0Sstevel@tonic-gate get_k5beta6_key_data(FILE *filep, krb5_db_entry dbentry, const char **try2read) 2135*0Sstevel@tonic-gate { 2136*0Sstevel@tonic-gate int error = 0; 2137*0Sstevel@tonic-gate int i, j; 2138*0Sstevel@tonic-gate 2139*0Sstevel@tonic-gate krb5_int32 t1, t2, t3, t4, t5, t6, t7, t8, t9; 2140*0Sstevel@tonic-gate int nread; 2141*0Sstevel@tonic-gate krb5_key_data *kdatap; 2142*0Sstevel@tonic-gate 2143*0Sstevel@tonic-gate for (i = 0; !error && (i < dbentry.n_key_data); i++) { 2144*0Sstevel@tonic-gate kdatap = &dbentry.key_data[i]; 2145*0Sstevel@tonic-gate nread = fscanf(filep, "%d\t%d\t", &t1, &t2); 2146*0Sstevel@tonic-gate if (nread == 2) { 2147*0Sstevel@tonic-gate kdatap->key_data_ver = (krb5_int16) t1; 2148*0Sstevel@tonic-gate kdatap->key_data_kvno = (krb5_int16) t2; 2149*0Sstevel@tonic-gate 2150*0Sstevel@tonic-gate for (j = 0; j < t1; j++) { 2151*0Sstevel@tonic-gate nread = fscanf(filep, "%d\t%d\t", &t3, &t4); 2152*0Sstevel@tonic-gate if (nread == 2) { 2153*0Sstevel@tonic-gate kdatap->key_data_type[j] = t3; 2154*0Sstevel@tonic-gate kdatap->key_data_length[j] = t4; 2155*0Sstevel@tonic-gate if (t4) { 2156*0Sstevel@tonic-gate if (!(kdatap-> 2157*0Sstevel@tonic-gate key_data_contents[j] = 2158*0Sstevel@tonic-gate (krb5_octet *) 2159*0Sstevel@tonic-gate malloc((size_t) t4 2160*0Sstevel@tonic-gate + 1)) || 2161*0Sstevel@tonic-gate read_octet_string(filep, 2162*0Sstevel@tonic-gate kdatap-> 2163*0Sstevel@tonic-gate key_data_contents[j], 2164*0Sstevel@tonic-gate t4)) { 2165*0Sstevel@tonic-gate *try2read = 2166*0Sstevel@tonic-gate read_kcontents; 2167*0Sstevel@tonic-gate error++; 2168*0Sstevel@tonic-gate break; 2169*0Sstevel@tonic-gate } 2170*0Sstevel@tonic-gate } else { 2171*0Sstevel@tonic-gate /* Should be a null field */ 2172*0Sstevel@tonic-gate nread = fscanf(filep, 2173*0Sstevel@tonic-gate "%d", &t9); 2174*0Sstevel@tonic-gate if ((nread != 1) || 2175*0Sstevel@tonic-gate (t9 != -1)) { 2176*0Sstevel@tonic-gate error++; 2177*0Sstevel@tonic-gate *try2read = 2178*0Sstevel@tonic-gate read_kcontents; 2179*0Sstevel@tonic-gate break; 2180*0Sstevel@tonic-gate } 2181*0Sstevel@tonic-gate } 2182*0Sstevel@tonic-gate } else { 2183*0Sstevel@tonic-gate *try2read = read_ktypelen; 2184*0Sstevel@tonic-gate error++; 2185*0Sstevel@tonic-gate break; 2186*0Sstevel@tonic-gate } 2187*0Sstevel@tonic-gate } 2188*0Sstevel@tonic-gate } 2189*0Sstevel@tonic-gate } 2190*0Sstevel@tonic-gate return (error); 2191*0Sstevel@tonic-gate } 2192*0Sstevel@tonic-gate 2193*0Sstevel@tonic-gate /* 2194*0Sstevel@tonic-gate * process_k5beta6_record() - Handle a dump record in krb5b6 format. 2195*0Sstevel@tonic-gate * 2196*0Sstevel@tonic-gate * Returns -1 for end of file, 0 for success and 1 for failure. 2197*0Sstevel@tonic-gate */ 2198*0Sstevel@tonic-gate static int 2199*0Sstevel@tonic-gate process_k5beta6_record(fname, kcontext, filep, verbose, linenop, pol_db) 2200*0Sstevel@tonic-gate char *fname; 2201*0Sstevel@tonic-gate krb5_context kcontext; 2202*0Sstevel@tonic-gate FILE *filep; 2203*0Sstevel@tonic-gate int verbose; 2204*0Sstevel@tonic-gate int *linenop; 2205*0Sstevel@tonic-gate void *pol_db; 2206*0Sstevel@tonic-gate { 2207*0Sstevel@tonic-gate int retval; 2208*0Sstevel@tonic-gate krb5_db_entry dbentry; 2209*0Sstevel@tonic-gate krb5_int32 t1, t2, t3, t4, t5, t6, t7, t8, t9; 2210*0Sstevel@tonic-gate int nread; 2211*0Sstevel@tonic-gate int error; 2212*0Sstevel@tonic-gate int i, j, one; 2213*0Sstevel@tonic-gate char *name; 2214*0Sstevel@tonic-gate krb5_key_data *kp, *kdatap; 2215*0Sstevel@tonic-gate krb5_tl_data **tlp, *tl; 2216*0Sstevel@tonic-gate krb5_octet *op; 2217*0Sstevel@tonic-gate krb5_error_code kret; 2218*0Sstevel@tonic-gate const char *try2read; 2219*0Sstevel@tonic-gate 2220*0Sstevel@tonic-gate try2read = (char *) NULL; 2221*0Sstevel@tonic-gate memset((char *) &dbentry, 0, sizeof(dbentry)); 2222*0Sstevel@tonic-gate (*linenop)++; 2223*0Sstevel@tonic-gate retval = 1; 2224*0Sstevel@tonic-gate name = (char *) NULL; 2225*0Sstevel@tonic-gate kp = (krb5_key_data *) NULL; 2226*0Sstevel@tonic-gate op = (krb5_octet *) NULL; 2227*0Sstevel@tonic-gate error = 0; 2228*0Sstevel@tonic-gate kret = 0; 2229*0Sstevel@tonic-gate nread = fscanf(filep, "%d\t%d\t%d\t%d\t%d\t", &t1, &t2, &t3, &t4, &t5); 2230*0Sstevel@tonic-gate if (nread == 5) { 2231*0Sstevel@tonic-gate /* Get memory for flattened principal name */ 2232*0Sstevel@tonic-gate if (!(name = (char *) malloc((size_t) t2 + 1))) 2233*0Sstevel@tonic-gate error++; 2234*0Sstevel@tonic-gate 2235*0Sstevel@tonic-gate /* Get memory for and form tagged data linked list */ 2236*0Sstevel@tonic-gate tlp = &dbentry.tl_data; 2237*0Sstevel@tonic-gate for (i=0; i<t3; i++) { 2238*0Sstevel@tonic-gate if ((*tlp = (krb5_tl_data *) 2239*0Sstevel@tonic-gate malloc(sizeof (krb5_tl_data)))) { 2240*0Sstevel@tonic-gate memset(*tlp, 0, sizeof(krb5_tl_data)); 2241*0Sstevel@tonic-gate tlp = &((*tlp)->tl_data_next); 2242*0Sstevel@tonic-gate dbentry.n_tl_data++; 2243*0Sstevel@tonic-gate } else { 2244*0Sstevel@tonic-gate error++; 2245*0Sstevel@tonic-gate break; 2246*0Sstevel@tonic-gate } 2247*0Sstevel@tonic-gate } 2248*0Sstevel@tonic-gate 2249*0Sstevel@tonic-gate /* Get memory for key list */ 2250*0Sstevel@tonic-gate if (t4 && !(kp = (krb5_key_data *) malloc((size_t) 2251*0Sstevel@tonic-gate (t4*sizeof(krb5_key_data))))) 2252*0Sstevel@tonic-gate error++; 2253*0Sstevel@tonic-gate 2254*0Sstevel@tonic-gate /* Get memory for extra data */ 2255*0Sstevel@tonic-gate if (t5 && !(op = (krb5_octet *) malloc((size_t) t5))) 2256*0Sstevel@tonic-gate error++; 2257*0Sstevel@tonic-gate 2258*0Sstevel@tonic-gate if (!error) { 2259*0Sstevel@tonic-gate dbentry.len = t1; 2260*0Sstevel@tonic-gate dbentry.n_key_data = t4; 2261*0Sstevel@tonic-gate dbentry.e_length = t5; 2262*0Sstevel@tonic-gate if (kp) { 2263*0Sstevel@tonic-gate memset(kp, 0, 2264*0Sstevel@tonic-gate (size_t) (t4 * sizeof (krb5_key_data))); 2265*0Sstevel@tonic-gate dbentry.key_data = kp; 2266*0Sstevel@tonic-gate kp = (krb5_key_data *) NULL; 2267*0Sstevel@tonic-gate } 2268*0Sstevel@tonic-gate if (op) { 2269*0Sstevel@tonic-gate memset(op, 0, (size_t) t5); 2270*0Sstevel@tonic-gate dbentry.e_data = op; 2271*0Sstevel@tonic-gate op = (krb5_octet *) NULL; 2272*0Sstevel@tonic-gate } 2273*0Sstevel@tonic-gate /* Read in and parse the principal name */ 2274*0Sstevel@tonic-gate if (!read_string(filep, name, t2, linenop) && 2275*0Sstevel@tonic-gate !(kret = krb5_parse_name(kcontext, 2276*0Sstevel@tonic-gate name, &dbentry.princ))) { 2277*0Sstevel@tonic-gate 2278*0Sstevel@tonic-gate /* Get the fixed principal attributes */ 2279*0Sstevel@tonic-gate nread = fscanf(filep, "%d\t%d\t%d\t%d" 2280*0Sstevel@tonic-gate "\t%d\t%d\t%d\t%d\t", 2281*0Sstevel@tonic-gate &t2, &t3, &t4, &t5, 2282*0Sstevel@tonic-gate &t6, &t7, &t8, &t9); 2283*0Sstevel@tonic-gate if (nread == 8) { 2284*0Sstevel@tonic-gate dbentry.attributes = (krb5_flags) t2; 2285*0Sstevel@tonic-gate dbentry.max_life = (krb5_deltat) t3; 2286*0Sstevel@tonic-gate dbentry.max_renewable_life = 2287*0Sstevel@tonic-gate (krb5_deltat) t4; 2288*0Sstevel@tonic-gate dbentry.expiration = 2289*0Sstevel@tonic-gate (krb5_timestamp) t5; 2290*0Sstevel@tonic-gate dbentry.pw_expiration = 2291*0Sstevel@tonic-gate (krb5_timestamp) t6; 2292*0Sstevel@tonic-gate dbentry.last_success = 2293*0Sstevel@tonic-gate (krb5_timestamp) t7; 2294*0Sstevel@tonic-gate dbentry.last_failed = 2295*0Sstevel@tonic-gate (krb5_timestamp) t8; 2296*0Sstevel@tonic-gate dbentry.fail_auth_count = 2297*0Sstevel@tonic-gate (krb5_kvno) t9; 2298*0Sstevel@tonic-gate } else { 2299*0Sstevel@tonic-gate try2read = read_nint_data; 2300*0Sstevel@tonic-gate error++; 2301*0Sstevel@tonic-gate } 2302*0Sstevel@tonic-gate 2303*0Sstevel@tonic-gate /* 2304*0Sstevel@tonic-gate * Get the tagged data. 2305*0Sstevel@tonic-gate * 2306*0Sstevel@tonic-gate * Really, this code ought to discard tl data 2307*0Sstevel@tonic-gate * types that it knows are special to the 2308*0Sstevel@tonic-gate * current version and were not supported 2309*0Sstevel@tonic-gate * in the previous version. But it's a pain 2310*0Sstevel@tonic-gate * to implement that here, and doing it at 2311*0Sstevel@tonic-gate * dump time has almost as good an effect, 2312*0Sstevel@tonic-gate * so that's what I did. [krb5-admin/89/ 2313*0Sstevel@tonic-gate */ 2314*0Sstevel@tonic-gate if (!error && dbentry.n_tl_data) { 2315*0Sstevel@tonic-gate error = get_k5beta6_tag_data( 2316*0Sstevel@tonic-gate filep, 2317*0Sstevel@tonic-gate dbentry, 2318*0Sstevel@tonic-gate &try2read); 2319*0Sstevel@tonic-gate } 2320*0Sstevel@tonic-gate /* Get the key data */ 2321*0Sstevel@tonic-gate if (!error && dbentry.n_key_data) { 2322*0Sstevel@tonic-gate error = get_k5beta6_key_data( 2323*0Sstevel@tonic-gate filep, 2324*0Sstevel@tonic-gate dbentry, 2325*0Sstevel@tonic-gate &try2read); 2326*0Sstevel@tonic-gate } 2327*0Sstevel@tonic-gate /* Get the extra data */ 2328*0Sstevel@tonic-gate if (!error && dbentry.e_length) { 2329*0Sstevel@tonic-gate if (read_octet_string(filep, 2330*0Sstevel@tonic-gate dbentry.e_data, 2331*0Sstevel@tonic-gate (int) dbentry.e_length)) { 2332*0Sstevel@tonic-gate try2read = read_econtents; 2333*0Sstevel@tonic-gate error++; 2334*0Sstevel@tonic-gate } 2335*0Sstevel@tonic-gate } else { 2336*0Sstevel@tonic-gate nread = fscanf(filep, "%d", &t9); 2337*0Sstevel@tonic-gate if ((nread != 1) || (t9 != -1)) { 2338*0Sstevel@tonic-gate error++; 2339*0Sstevel@tonic-gate try2read = read_econtents; 2340*0Sstevel@tonic-gate } 2341*0Sstevel@tonic-gate } 2342*0Sstevel@tonic-gate 2343*0Sstevel@tonic-gate /* Finally, find the end of the record. */ 2344*0Sstevel@tonic-gate if (!error) 2345*0Sstevel@tonic-gate find_record_end(filep, fname, *linenop); 2346*0Sstevel@tonic-gate 2347*0Sstevel@tonic-gate /* 2348*0Sstevel@tonic-gate * We have either read in all the data or 2349*0Sstevel@tonic-gate * choked. 2350*0Sstevel@tonic-gate */ 2351*0Sstevel@tonic-gate if (!error) { 2352*0Sstevel@tonic-gate one = 1; 2353*0Sstevel@tonic-gate if ((kret = krb5_db_put_principal( 2354*0Sstevel@tonic-gate kcontext, 2355*0Sstevel@tonic-gate &dbentry, 2356*0Sstevel@tonic-gate &one))) { 2357*0Sstevel@tonic-gate fprintf(stderr, 2358*0Sstevel@tonic-gate gettext(store_err_fmt), 2359*0Sstevel@tonic-gate fname, *linenop, 2360*0Sstevel@tonic-gate name, error_message(kret)); 2361*0Sstevel@tonic-gate } else { 2362*0Sstevel@tonic-gate if (verbose) 2363*0Sstevel@tonic-gate fprintf(stderr, 2364*0Sstevel@tonic-gate gettext( 2365*0Sstevel@tonic-gate add_princ_fmt), 2366*0Sstevel@tonic-gate name); 2367*0Sstevel@tonic-gate retval = 0; 2368*0Sstevel@tonic-gate } 2369*0Sstevel@tonic-gate } else { 2370*0Sstevel@tonic-gate fprintf(stderr, gettext(read_err_fmt), 2371*0Sstevel@tonic-gate fname, *linenop, try2read); 2372*0Sstevel@tonic-gate } 2373*0Sstevel@tonic-gate } else { 2374*0Sstevel@tonic-gate if (kret) 2375*0Sstevel@tonic-gate fprintf(stderr, gettext(parse_err_fmt), 2376*0Sstevel@tonic-gate fname, *linenop, name, 2377*0Sstevel@tonic-gate error_message(kret)); 2378*0Sstevel@tonic-gate else 2379*0Sstevel@tonic-gate fprintf(stderr, gettext(no_mem_fmt), 2380*0Sstevel@tonic-gate fname, *linenop); 2381*0Sstevel@tonic-gate } 2382*0Sstevel@tonic-gate } else { 2383*0Sstevel@tonic-gate fprintf(stderr, 2384*0Sstevel@tonic-gate gettext(rhead_err_fmt), fname, *linenop); 2385*0Sstevel@tonic-gate } 2386*0Sstevel@tonic-gate 2387*0Sstevel@tonic-gate if (op) 2388*0Sstevel@tonic-gate free(op); 2389*0Sstevel@tonic-gate if (kp) 2390*0Sstevel@tonic-gate free(kp); 2391*0Sstevel@tonic-gate if (name) 2392*0Sstevel@tonic-gate free(name); 2393*0Sstevel@tonic-gate krb5_db_free_principal(kcontext, &dbentry, 1); 2394*0Sstevel@tonic-gate } else { 2395*0Sstevel@tonic-gate if (nread == EOF) 2396*0Sstevel@tonic-gate retval = -1; 2397*0Sstevel@tonic-gate } 2398*0Sstevel@tonic-gate return(retval); 2399*0Sstevel@tonic-gate } 2400*0Sstevel@tonic-gate 2401*0Sstevel@tonic-gate int 2402*0Sstevel@tonic-gate process_k5beta7_policy(fname, kcontext, filep, verbose, linenop, pol_db) 2403*0Sstevel@tonic-gate char *fname; 2404*0Sstevel@tonic-gate krb5_context kcontext; 2405*0Sstevel@tonic-gate FILE *filep; 2406*0Sstevel@tonic-gate int verbose; 2407*0Sstevel@tonic-gate int *linenop; 2408*0Sstevel@tonic-gate void *pol_db; 2409*0Sstevel@tonic-gate { 2410*0Sstevel@tonic-gate osa_policy_ent_rec rec; 2411*0Sstevel@tonic-gate char namebuf[1024]; 2412*0Sstevel@tonic-gate int nread, ret; 2413*0Sstevel@tonic-gate 2414*0Sstevel@tonic-gate (*linenop)++; 2415*0Sstevel@tonic-gate rec.name = namebuf; 2416*0Sstevel@tonic-gate 2417*0Sstevel@tonic-gate nread = fscanf(filep, "%1024s\t%d\t%d\t%d\t%d\t%d\t%d", rec.name, 2418*0Sstevel@tonic-gate &rec.pw_min_life, &rec.pw_max_life, 2419*0Sstevel@tonic-gate &rec.pw_min_length, &rec.pw_min_classes, 2420*0Sstevel@tonic-gate &rec.pw_history_num, &rec.policy_refcnt); 2421*0Sstevel@tonic-gate if (nread == EOF) 2422*0Sstevel@tonic-gate return (-1); 2423*0Sstevel@tonic-gate else if (nread != 7) { 2424*0Sstevel@tonic-gate fprintf(stderr, 2425*0Sstevel@tonic-gate gettext("cannot parse policy on line %d (%d read)\n"), 2426*0Sstevel@tonic-gate *linenop, nread); 2427*0Sstevel@tonic-gate return (1); 2428*0Sstevel@tonic-gate } 2429*0Sstevel@tonic-gate 2430*0Sstevel@tonic-gate if ((ret = osa_adb_create_policy(pol_db, &rec))) { 2431*0Sstevel@tonic-gate if (ret == OSA_ADB_DUP && 2432*0Sstevel@tonic-gate ((ret = osa_adb_put_policy(pol_db, &rec)))) { 2433*0Sstevel@tonic-gate fprintf(stderr, gettext("cannot create policy on line %d: %s\n"), 2434*0Sstevel@tonic-gate *linenop, error_message(ret)); 2435*0Sstevel@tonic-gate return (1); 2436*0Sstevel@tonic-gate } 2437*0Sstevel@tonic-gate } 2438*0Sstevel@tonic-gate if (verbose) 2439*0Sstevel@tonic-gate fprintf(stderr, gettext("created policy %s\n"), rec.name); 2440*0Sstevel@tonic-gate 2441*0Sstevel@tonic-gate return (0); 2442*0Sstevel@tonic-gate } 2443*0Sstevel@tonic-gate 2444*0Sstevel@tonic-gate /* 2445*0Sstevel@tonic-gate * process_k5beta7_record() - Handle a dump record in krb5b6 format. 2446*0Sstevel@tonic-gate * 2447*0Sstevel@tonic-gate * Returns -1 for end of file, 0 for success and 1 for failure. 2448*0Sstevel@tonic-gate */ 2449*0Sstevel@tonic-gate static int 2450*0Sstevel@tonic-gate process_k5beta7_record(fname, kcontext, filep, verbose, linenop, pol_db) 2451*0Sstevel@tonic-gate char *fname; 2452*0Sstevel@tonic-gate krb5_context kcontext; 2453*0Sstevel@tonic-gate FILE *filep; 2454*0Sstevel@tonic-gate int verbose; 2455*0Sstevel@tonic-gate int *linenop; 2456*0Sstevel@tonic-gate void *pol_db; 2457*0Sstevel@tonic-gate { 2458*0Sstevel@tonic-gate int nread; 2459*0Sstevel@tonic-gate char rectype[100]; 2460*0Sstevel@tonic-gate 2461*0Sstevel@tonic-gate nread = fscanf(filep, "%100s\t", rectype); 2462*0Sstevel@tonic-gate if (nread == EOF) 2463*0Sstevel@tonic-gate return (-1); 2464*0Sstevel@tonic-gate else if (nread != 1) 2465*0Sstevel@tonic-gate return (1); 2466*0Sstevel@tonic-gate if (strcmp(rectype, "princ") == 0) 2467*0Sstevel@tonic-gate process_k5beta6_record(fname, kcontext, filep, verbose, 2468*0Sstevel@tonic-gate linenop, pol_db); 2469*0Sstevel@tonic-gate else if (strcmp(rectype, "policy") == 0) 2470*0Sstevel@tonic-gate process_k5beta7_policy(fname, kcontext, filep, verbose, 2471*0Sstevel@tonic-gate linenop, pol_db); 2472*0Sstevel@tonic-gate else { 2473*0Sstevel@tonic-gate fprintf(stderr, 2474*0Sstevel@tonic-gate gettext("unknown record type \"%s\" on line %d\n"), 2475*0Sstevel@tonic-gate rectype, *linenop); 2476*0Sstevel@tonic-gate return (1); 2477*0Sstevel@tonic-gate } 2478*0Sstevel@tonic-gate 2479*0Sstevel@tonic-gate return (0); 2480*0Sstevel@tonic-gate } 2481*0Sstevel@tonic-gate 2482*0Sstevel@tonic-gate /* 2483*0Sstevel@tonic-gate * process_ov_record() - Handle a dump record in OpenV*Secure 1.0 format. 2484*0Sstevel@tonic-gate * 2485*0Sstevel@tonic-gate * Returns -1 for end of file, 0 for success and 1 for failure. 2486*0Sstevel@tonic-gate */ 2487*0Sstevel@tonic-gate static int 2488*0Sstevel@tonic-gate process_ov_record(fname, kcontext, filep, verbose, linenop, pol_db) 2489*0Sstevel@tonic-gate char *fname; 2490*0Sstevel@tonic-gate krb5_context kcontext; 2491*0Sstevel@tonic-gate FILE *filep; 2492*0Sstevel@tonic-gate int verbose; 2493*0Sstevel@tonic-gate int *linenop; 2494*0Sstevel@tonic-gate void *pol_db; 2495*0Sstevel@tonic-gate { 2496*0Sstevel@tonic-gate int nread; 2497*0Sstevel@tonic-gate char rectype[100]; 2498*0Sstevel@tonic-gate 2499*0Sstevel@tonic-gate nread = fscanf(filep, "%100s\t", rectype); 2500*0Sstevel@tonic-gate if (nread == EOF) 2501*0Sstevel@tonic-gate return (-1); 2502*0Sstevel@tonic-gate else if (nread != 1) 2503*0Sstevel@tonic-gate return (1); 2504*0Sstevel@tonic-gate if (strcmp(rectype, "princ") == 0) 2505*0Sstevel@tonic-gate process_ov_principal(fname, kcontext, filep, verbose, 2506*0Sstevel@tonic-gate linenop, pol_db); 2507*0Sstevel@tonic-gate else if (strcmp(rectype, "policy") == 0) 2508*0Sstevel@tonic-gate process_k5beta7_policy(fname, kcontext, filep, verbose, 2509*0Sstevel@tonic-gate linenop, pol_db); 2510*0Sstevel@tonic-gate else if (strcmp(rectype, "End") == 0) 2511*0Sstevel@tonic-gate return (-1); 2512*0Sstevel@tonic-gate else { 2513*0Sstevel@tonic-gate fprintf(stderr, 2514*0Sstevel@tonic-gate gettext("unknown record type \"%s\" on line %d\n"), 2515*0Sstevel@tonic-gate rectype, *linenop); 2516*0Sstevel@tonic-gate return (1); 2517*0Sstevel@tonic-gate } 2518*0Sstevel@tonic-gate 2519*0Sstevel@tonic-gate return (0); 2520*0Sstevel@tonic-gate } 2521*0Sstevel@tonic-gate 2522*0Sstevel@tonic-gate /* 2523*0Sstevel@tonic-gate * restore_dump() - Restore the database from any version dump file. 2524*0Sstevel@tonic-gate */ 2525*0Sstevel@tonic-gate static int 2526*0Sstevel@tonic-gate restore_dump(programname, kcontext, dumpfile, f, verbose, dump, pol_db) 2527*0Sstevel@tonic-gate char *programname; 2528*0Sstevel@tonic-gate krb5_context kcontext; 2529*0Sstevel@tonic-gate char *dumpfile; 2530*0Sstevel@tonic-gate FILE *f; 2531*0Sstevel@tonic-gate int verbose; 2532*0Sstevel@tonic-gate dump_version *dump; 2533*0Sstevel@tonic-gate osa_adb_policy_t pol_db; 2534*0Sstevel@tonic-gate { 2535*0Sstevel@tonic-gate int error; 2536*0Sstevel@tonic-gate int lineno; 2537*0Sstevel@tonic-gate 2538*0Sstevel@tonic-gate error = 0; 2539*0Sstevel@tonic-gate lineno = 1; 2540*0Sstevel@tonic-gate 2541*0Sstevel@tonic-gate /* 2542*0Sstevel@tonic-gate * Process the records. 2543*0Sstevel@tonic-gate */ 2544*0Sstevel@tonic-gate while (!(error = (*dump->load_record)(dumpfile, 2545*0Sstevel@tonic-gate kcontext, 2546*0Sstevel@tonic-gate f, 2547*0Sstevel@tonic-gate verbose, 2548*0Sstevel@tonic-gate &lineno, 2549*0Sstevel@tonic-gate pol_db))); 2550*0Sstevel@tonic-gate if (error != -1) 2551*0Sstevel@tonic-gate fprintf(stderr, gettext(err_line_fmt), 2552*0Sstevel@tonic-gate programname, lineno, dumpfile); 2553*0Sstevel@tonic-gate else 2554*0Sstevel@tonic-gate error = 0; 2555*0Sstevel@tonic-gate 2556*0Sstevel@tonic-gate return(error); 2557*0Sstevel@tonic-gate } 2558*0Sstevel@tonic-gate 2559*0Sstevel@tonic-gate /* 2560*0Sstevel@tonic-gate * Usage: load_db [-i] [-old] [-ov] [-b6] [-verbose] [-update] [-hash] filename 2561*0Sstevel@tonic-gate */ 2562*0Sstevel@tonic-gate void 2563*0Sstevel@tonic-gate load_db(argc, argv) 2564*0Sstevel@tonic-gate int argc; 2565*0Sstevel@tonic-gate char **argv; 2566*0Sstevel@tonic-gate { 2567*0Sstevel@tonic-gate kadm5_config_params newparams; 2568*0Sstevel@tonic-gate osa_adb_policy_t tmppol_db; 2569*0Sstevel@tonic-gate krb5_error_code kret; 2570*0Sstevel@tonic-gate krb5_context kcontext; 2571*0Sstevel@tonic-gate FILE *f; 2572*0Sstevel@tonic-gate extern char *optarg; 2573*0Sstevel@tonic-gate extern int optind; 2574*0Sstevel@tonic-gate char *programname; 2575*0Sstevel@tonic-gate char *dumpfile; 2576*0Sstevel@tonic-gate char *dbname; 2577*0Sstevel@tonic-gate char *dbname_tmp; 2578*0Sstevel@tonic-gate char buf[BUFSIZ]; 2579*0Sstevel@tonic-gate dump_version *load; 2580*0Sstevel@tonic-gate int update, verbose; 2581*0Sstevel@tonic-gate krb5_int32 crflags; 2582*0Sstevel@tonic-gate int aindex; 2583*0Sstevel@tonic-gate bool_t add_update = TRUE; 2584*0Sstevel@tonic-gate char iheader[MAX_HEADER]; 2585*0Sstevel@tonic-gate uint32_t caller, last_sno, last_seconds, last_useconds; 2586*0Sstevel@tonic-gate kdb_log_context *log_ctx; 2587*0Sstevel@tonic-gate 2588*0Sstevel@tonic-gate /* 2589*0Sstevel@tonic-gate * Parse the arguments. 2590*0Sstevel@tonic-gate */ 2591*0Sstevel@tonic-gate programname = argv[0]; 2592*0Sstevel@tonic-gate if (strrchr(programname, (int) '/')) 2593*0Sstevel@tonic-gate programname = strrchr(argv[0], (int) '/') + 1; 2594*0Sstevel@tonic-gate dumpfile = (char *) NULL; 2595*0Sstevel@tonic-gate dbname = global_params.dbname; 2596*0Sstevel@tonic-gate load = NULL; 2597*0Sstevel@tonic-gate update = 0; 2598*0Sstevel@tonic-gate verbose = 0; 2599*0Sstevel@tonic-gate crflags = KRB5_KDB_CREATE_BTREE; 2600*0Sstevel@tonic-gate exit_status = 0; 2601*0Sstevel@tonic-gate dbname_tmp = (char *) NULL; 2602*0Sstevel@tonic-gate tmppol_db = NULL; 2603*0Sstevel@tonic-gate log_ctx = util_context->kdblog_context; 2604*0Sstevel@tonic-gate 2605*0Sstevel@tonic-gate for (aindex = 1; aindex < argc; aindex++) { 2606*0Sstevel@tonic-gate if (strcmp(argv[aindex], oldoption) == 0) 2607*0Sstevel@tonic-gate load = &old_version; 2608*0Sstevel@tonic-gate else if (strcmp(argv[aindex], b6option) == 0) 2609*0Sstevel@tonic-gate load = &beta6_version; 2610*0Sstevel@tonic-gate else if (strcmp(argv[aindex], ovoption) == 0) 2611*0Sstevel@tonic-gate load = &ov_version; 2612*0Sstevel@tonic-gate else if (!strcmp(argv[aindex], ipropoption)) { 2613*0Sstevel@tonic-gate if (log_ctx && log_ctx->iproprole) { 2614*0Sstevel@tonic-gate load = &iprop_version; 2615*0Sstevel@tonic-gate add_update = FALSE; 2616*0Sstevel@tonic-gate } else { 2617*0Sstevel@tonic-gate fprintf(stderr, gettext("Iprop not enabled\n")); 2618*0Sstevel@tonic-gate exit_status++; 2619*0Sstevel@tonic-gate return; 2620*0Sstevel@tonic-gate } 2621*0Sstevel@tonic-gate } else if (strcmp(argv[aindex], verboseoption) == 0) 2622*0Sstevel@tonic-gate verbose = 1; 2623*0Sstevel@tonic-gate else if (strcmp(argv[aindex], updateoption) == 0) 2624*0Sstevel@tonic-gate update = 1; 2625*0Sstevel@tonic-gate else if (!strcmp(argv[aindex], hashoption)) 2626*0Sstevel@tonic-gate crflags = KRB5_KDB_CREATE_HASH; 2627*0Sstevel@tonic-gate else 2628*0Sstevel@tonic-gate break; 2629*0Sstevel@tonic-gate } 2630*0Sstevel@tonic-gate if ((argc - aindex) != 1) { 2631*0Sstevel@tonic-gate usage(); 2632*0Sstevel@tonic-gate return; 2633*0Sstevel@tonic-gate } 2634*0Sstevel@tonic-gate dumpfile = argv[aindex]; 2635*0Sstevel@tonic-gate 2636*0Sstevel@tonic-gate if (!(dbname_tmp = (char *) malloc(strlen(dbname)+ 2637*0Sstevel@tonic-gate strlen(dump_tmptrail)+1))) { 2638*0Sstevel@tonic-gate fprintf(stderr, gettext(no_name_mem_fmt), argv[0]); 2639*0Sstevel@tonic-gate exit_status++; 2640*0Sstevel@tonic-gate return; 2641*0Sstevel@tonic-gate } 2642*0Sstevel@tonic-gate strcpy(dbname_tmp, dbname); 2643*0Sstevel@tonic-gate strcat(dbname_tmp, dump_tmptrail); 2644*0Sstevel@tonic-gate 2645*0Sstevel@tonic-gate /* 2646*0Sstevel@tonic-gate * Initialize the Kerberos context and error tables. 2647*0Sstevel@tonic-gate */ 2648*0Sstevel@tonic-gate if ((kret = krb5_init_context(&kcontext))) { 2649*0Sstevel@tonic-gate fprintf(stderr, gettext(ctx_err_fmt), programname); 2650*0Sstevel@tonic-gate free(dbname_tmp); 2651*0Sstevel@tonic-gate exit_status++; 2652*0Sstevel@tonic-gate return; 2653*0Sstevel@tonic-gate } 2654*0Sstevel@tonic-gate 2655*0Sstevel@tonic-gate if (log_ctx && log_ctx->iproprole) 2656*0Sstevel@tonic-gate kcontext->kdblog_context = (void *)log_ctx; 2657*0Sstevel@tonic-gate 2658*0Sstevel@tonic-gate /* 2659*0Sstevel@tonic-gate * Open the dumpfile 2660*0Sstevel@tonic-gate */ 2661*0Sstevel@tonic-gate if (dumpfile) { 2662*0Sstevel@tonic-gate if ((f = fopen(dumpfile, "r+")) == NULL) { 2663*0Sstevel@tonic-gate fprintf(stderr, gettext(dfile_err_fmt), 2664*0Sstevel@tonic-gate programname, dumpfile, 2665*0Sstevel@tonic-gate error_message(errno)); 2666*0Sstevel@tonic-gate exit_status++; 2667*0Sstevel@tonic-gate return; 2668*0Sstevel@tonic-gate } 2669*0Sstevel@tonic-gate if ((kret = krb5_lock_file(kcontext, fileno(f), 2670*0Sstevel@tonic-gate KRB5_LOCKMODE_SHARED))) { 2671*0Sstevel@tonic-gate fprintf(stderr, gettext("%s: Cannot lock %s: %s\n"), programname, 2672*0Sstevel@tonic-gate dumpfile, error_message(errno)); 2673*0Sstevel@tonic-gate exit_status++; 2674*0Sstevel@tonic-gate return; 2675*0Sstevel@tonic-gate } 2676*0Sstevel@tonic-gate } else 2677*0Sstevel@tonic-gate f = stdin; 2678*0Sstevel@tonic-gate 2679*0Sstevel@tonic-gate /* 2680*0Sstevel@tonic-gate * Auto-detect dump version if we weren't told, verify if we were 2681*0Sstevel@tonic-gate * told. 2682*0Sstevel@tonic-gate */ 2683*0Sstevel@tonic-gate fgets(buf, sizeof(buf), f); 2684*0Sstevel@tonic-gate if (load) { 2685*0Sstevel@tonic-gate /* 2686*0Sstevel@tonic-gate * only check what we know; some headers only contain a 2687*0Sstevel@tonic-gate * prefix 2688*0Sstevel@tonic-gate */ 2689*0Sstevel@tonic-gate if (strncmp(buf, load->header, strlen(load->header)) != 0) { 2690*0Sstevel@tonic-gate fprintf(stderr, gettext(head_bad_fmt), 2691*0Sstevel@tonic-gate programname, dumpfile); 2692*0Sstevel@tonic-gate exit_status++; 2693*0Sstevel@tonic-gate if (dumpfile) 2694*0Sstevel@tonic-gate fclose(f); 2695*0Sstevel@tonic-gate return; 2696*0Sstevel@tonic-gate } 2697*0Sstevel@tonic-gate } else { 2698*0Sstevel@tonic-gate /* perhaps this should be in an array, but so what? */ 2699*0Sstevel@tonic-gate if (strcmp(buf, old_version.header) == 0) 2700*0Sstevel@tonic-gate load = &old_version; 2701*0Sstevel@tonic-gate else if (strcmp(buf, beta6_version.header) == 0) 2702*0Sstevel@tonic-gate load = &beta6_version; 2703*0Sstevel@tonic-gate else if (strcmp(buf, beta7_version.header) == 0) 2704*0Sstevel@tonic-gate load = &beta7_version; 2705*0Sstevel@tonic-gate else if (strncmp(buf, ov_version.header, 2706*0Sstevel@tonic-gate strlen(ov_version.header)) == 0) 2707*0Sstevel@tonic-gate load = &ov_version; 2708*0Sstevel@tonic-gate else { 2709*0Sstevel@tonic-gate fprintf(stderr, gettext(head_bad_fmt), 2710*0Sstevel@tonic-gate programname, dumpfile); 2711*0Sstevel@tonic-gate exit_status++; 2712*0Sstevel@tonic-gate if (dumpfile) 2713*0Sstevel@tonic-gate fclose(f); 2714*0Sstevel@tonic-gate return; 2715*0Sstevel@tonic-gate } 2716*0Sstevel@tonic-gate } 2717*0Sstevel@tonic-gate if (load->updateonly && !update) { 2718*0Sstevel@tonic-gate fprintf(stderr, 2719*0Sstevel@tonic-gate gettext("%s: dump version %s can only " 2720*0Sstevel@tonic-gate "be loaded with the -update flag\n"), 2721*0Sstevel@tonic-gate programname, load->name); 2722*0Sstevel@tonic-gate exit_status++; 2723*0Sstevel@tonic-gate return; 2724*0Sstevel@tonic-gate } 2725*0Sstevel@tonic-gate /* 2726*0Sstevel@tonic-gate * Cons up params for the new databases. If we are not in update 2727*0Sstevel@tonic-gate * mode use a temp name that we'll rename later. 2728*0Sstevel@tonic-gate */ 2729*0Sstevel@tonic-gate newparams = global_params; 2730*0Sstevel@tonic-gate if (! update) { 2731*0Sstevel@tonic-gate newparams.mask |= KADM5_CONFIG_DBNAME; 2732*0Sstevel@tonic-gate newparams.dbname = dbname_tmp; 2733*0Sstevel@tonic-gate 2734*0Sstevel@tonic-gate if ((kret = kadm5_get_config_params(kcontext, NULL, NULL, 2735*0Sstevel@tonic-gate &newparams, &newparams))) { 2736*0Sstevel@tonic-gate com_err(argv[0], kret, 2737*0Sstevel@tonic-gate gettext("while retreiving new " 2738*0Sstevel@tonic-gate "configuration parameters")); 2739*0Sstevel@tonic-gate exit_status++; 2740*0Sstevel@tonic-gate return; 2741*0Sstevel@tonic-gate } 2742*0Sstevel@tonic-gate } 2743*0Sstevel@tonic-gate /* 2744*0Sstevel@tonic-gate * If not an update restoration, create the temp database. Always 2745*0Sstevel@tonic-gate * create a temp policy db, even if we are not loading a dump file 2746*0Sstevel@tonic-gate * with policy info, because they may be loading an old dump 2747*0Sstevel@tonic-gate * intending to use it with the new kadm5 system. 2748*0Sstevel@tonic-gate */ 2749*0Sstevel@tonic-gate if (!update && ((kret = krb5_db_create(kcontext, dbname_tmp, crflags)))) { 2750*0Sstevel@tonic-gate fprintf(stderr, gettext(dbcreaterr_fmt), 2751*0Sstevel@tonic-gate programname, dbname_tmp, error_message(kret)); 2752*0Sstevel@tonic-gate exit_status++; 2753*0Sstevel@tonic-gate kadm5_free_config_params(kcontext, &newparams); 2754*0Sstevel@tonic-gate if (dumpfile) fclose(f); 2755*0Sstevel@tonic-gate return; 2756*0Sstevel@tonic-gate } 2757*0Sstevel@tonic-gate if (!update && (kret = osa_adb_create_policy_db(&newparams))) { 2758*0Sstevel@tonic-gate fprintf(stderr, 2759*0Sstevel@tonic-gate gettext("%s: %s while creating policy database\n"), 2760*0Sstevel@tonic-gate programname, error_message(kret)); 2761*0Sstevel@tonic-gate exit_status++; 2762*0Sstevel@tonic-gate kadm5_free_config_params(kcontext, &newparams); 2763*0Sstevel@tonic-gate if (dumpfile) 2764*0Sstevel@tonic-gate fclose(f); 2765*0Sstevel@tonic-gate return; 2766*0Sstevel@tonic-gate } 2767*0Sstevel@tonic-gate /* 2768*0Sstevel@tonic-gate * Point ourselves at the new databases. 2769*0Sstevel@tonic-gate */ 2770*0Sstevel@tonic-gate if ((kret = krb5_db_set_name(kcontext, 2771*0Sstevel@tonic-gate (update) ? dbname : dbname_tmp))) { 2772*0Sstevel@tonic-gate fprintf(stderr, gettext(dbname_err_fmt), 2773*0Sstevel@tonic-gate programname, 2774*0Sstevel@tonic-gate (update) ? dbname : dbname_tmp, error_message(kret)); 2775*0Sstevel@tonic-gate exit_status++; 2776*0Sstevel@tonic-gate goto error; 2777*0Sstevel@tonic-gate } 2778*0Sstevel@tonic-gate if ((kret = osa_adb_open_policy(&tmppol_db, &newparams))) { 2779*0Sstevel@tonic-gate fprintf(stderr, 2780*0Sstevel@tonic-gate gettext("%s: %s while opening policy database\n"), 2781*0Sstevel@tonic-gate programname, error_message(kret)); 2782*0Sstevel@tonic-gate exit_status++; 2783*0Sstevel@tonic-gate goto error; 2784*0Sstevel@tonic-gate } 2785*0Sstevel@tonic-gate /* 2786*0Sstevel@tonic-gate * If an update restoration, make sure the db is left unusable if 2787*0Sstevel@tonic-gate * the update fails. 2788*0Sstevel@tonic-gate */ 2789*0Sstevel@tonic-gate if (update) { 2790*0Sstevel@tonic-gate if ((kret = osa_adb_get_lock(tmppol_db, OSA_ADB_PERMANENT))) { 2791*0Sstevel@tonic-gate fprintf(stderr, 2792*0Sstevel@tonic-gate gettext("%s: %s while " 2793*0Sstevel@tonic-gate "permanently locking database\n"), 2794*0Sstevel@tonic-gate programname, error_message(kret)); 2795*0Sstevel@tonic-gate exit_status++; 2796*0Sstevel@tonic-gate goto error; 2797*0Sstevel@tonic-gate } 2798*0Sstevel@tonic-gate } 2799*0Sstevel@tonic-gate 2800*0Sstevel@tonic-gate /* 2801*0Sstevel@tonic-gate * Initialize the database. 2802*0Sstevel@tonic-gate */ 2803*0Sstevel@tonic-gate if ((kret = krb5_db_init(kcontext))) { 2804*0Sstevel@tonic-gate fprintf(stderr, gettext(dbinit_err_fmt), 2805*0Sstevel@tonic-gate programname, error_message(kret)); 2806*0Sstevel@tonic-gate exit_status++; 2807*0Sstevel@tonic-gate goto error; 2808*0Sstevel@tonic-gate } 2809*0Sstevel@tonic-gate /* 2810*0Sstevel@tonic-gate * grab an extra lock, since there are no other users 2811*0Sstevel@tonic-gate */ 2812*0Sstevel@tonic-gate if (!update) { 2813*0Sstevel@tonic-gate kret = krb5_db_lock(kcontext, KRB5_LOCKMODE_EXCLUSIVE); 2814*0Sstevel@tonic-gate if (kret) { 2815*0Sstevel@tonic-gate fprintf(stderr, gettext(dblock_err_fmt), 2816*0Sstevel@tonic-gate programname, error_message(kret)); 2817*0Sstevel@tonic-gate exit_status++; 2818*0Sstevel@tonic-gate goto error; 2819*0Sstevel@tonic-gate } 2820*0Sstevel@tonic-gate } 2821*0Sstevel@tonic-gate 2822*0Sstevel@tonic-gate if (log_ctx && log_ctx->iproprole) { 2823*0Sstevel@tonic-gate if (add_update) 2824*0Sstevel@tonic-gate caller = FKCOMMAND; 2825*0Sstevel@tonic-gate else 2826*0Sstevel@tonic-gate caller = FKPROPD; 2827*0Sstevel@tonic-gate 2828*0Sstevel@tonic-gate if (ulog_map(kcontext, &global_params, caller)) { 2829*0Sstevel@tonic-gate fprintf(stderr, 2830*0Sstevel@tonic-gate gettext("%s: Could not map log\n"), 2831*0Sstevel@tonic-gate programname); 2832*0Sstevel@tonic-gate exit_status++; 2833*0Sstevel@tonic-gate goto error; 2834*0Sstevel@tonic-gate } 2835*0Sstevel@tonic-gate 2836*0Sstevel@tonic-gate /* 2837*0Sstevel@tonic-gate * We don't want to take out the ulog out from underneath 2838*0Sstevel@tonic-gate * kadmind so we reinit the header log. 2839*0Sstevel@tonic-gate * 2840*0Sstevel@tonic-gate * We also don't want to add to the update log since we 2841*0Sstevel@tonic-gate * are doing a whole sale replace of the db, because: 2842*0Sstevel@tonic-gate * we could easily exceed # of update entries 2843*0Sstevel@tonic-gate * we could implicity delete db entries during a replace 2844*0Sstevel@tonic-gate * no advantage in incr updates when entire db is replaced 2845*0Sstevel@tonic-gate */ 2846*0Sstevel@tonic-gate if (!update) { 2847*0Sstevel@tonic-gate memset(log_ctx->ulog, 0, sizeof (kdb_hlog_t)); 2848*0Sstevel@tonic-gate 2849*0Sstevel@tonic-gate log_ctx->ulog->kdb_hmagic = KDB_HMAGIC; 2850*0Sstevel@tonic-gate log_ctx->ulog->db_version_num = KDB_VERSION; 2851*0Sstevel@tonic-gate log_ctx->ulog->kdb_state = KDB_STABLE; 2852*0Sstevel@tonic-gate log_ctx->ulog->kdb_block = ULOG_BLOCK; 2853*0Sstevel@tonic-gate 2854*0Sstevel@tonic-gate log_ctx->iproprole = IPROP_NULL; 2855*0Sstevel@tonic-gate 2856*0Sstevel@tonic-gate if (!add_update) { 2857*0Sstevel@tonic-gate sscanf(buf, "%s %u %u %u", iheader, &last_sno, 2858*0Sstevel@tonic-gate &last_seconds, &last_useconds); 2859*0Sstevel@tonic-gate 2860*0Sstevel@tonic-gate log_ctx->ulog->kdb_last_sno = last_sno; 2861*0Sstevel@tonic-gate log_ctx->ulog->kdb_last_time.seconds = 2862*0Sstevel@tonic-gate last_seconds; 2863*0Sstevel@tonic-gate log_ctx->ulog->kdb_last_time.useconds = 2864*0Sstevel@tonic-gate last_useconds; 2865*0Sstevel@tonic-gate } 2866*0Sstevel@tonic-gate } 2867*0Sstevel@tonic-gate } 2868*0Sstevel@tonic-gate 2869*0Sstevel@tonic-gate if (restore_dump(programname, kcontext, 2870*0Sstevel@tonic-gate (dumpfile) ? dumpfile : stdin_name, 2871*0Sstevel@tonic-gate f, verbose, load, tmppol_db)) { 2872*0Sstevel@tonic-gate fprintf(stderr, gettext(restfail_fmt), 2873*0Sstevel@tonic-gate programname, load->name); 2874*0Sstevel@tonic-gate exit_status++; 2875*0Sstevel@tonic-gate } 2876*0Sstevel@tonic-gate if (!update && (kret = krb5_db_unlock(kcontext))) { 2877*0Sstevel@tonic-gate /* change this error? */ 2878*0Sstevel@tonic-gate fprintf(stderr, gettext(dbunlockerr_fmt), 2879*0Sstevel@tonic-gate programname, dbname_tmp, error_message(kret)); 2880*0Sstevel@tonic-gate exit_status++; 2881*0Sstevel@tonic-gate } 2882*0Sstevel@tonic-gate if ((kret = krb5_db_fini(kcontext))) { 2883*0Sstevel@tonic-gate fprintf(stderr, gettext(close_err_fmt), 2884*0Sstevel@tonic-gate programname, error_message(kret)); 2885*0Sstevel@tonic-gate exit_status++; 2886*0Sstevel@tonic-gate } 2887*0Sstevel@tonic-gate 2888*0Sstevel@tonic-gate if (!update && load->create_kadm5 && 2889*0Sstevel@tonic-gate ((kret = kadm5_create_magic_princs(&newparams, kcontext)))) { 2890*0Sstevel@tonic-gate /* error message printed by create_magic_princs */ 2891*0Sstevel@tonic-gate exit_status++; 2892*0Sstevel@tonic-gate } 2893*0Sstevel@tonic-gate 2894*0Sstevel@tonic-gate /* close policy db below */ 2895*0Sstevel@tonic-gate 2896*0Sstevel@tonic-gate error: 2897*0Sstevel@tonic-gate /* 2898*0Sstevel@tonic-gate * If not an update: if there was an error, destroy the temp 2899*0Sstevel@tonic-gate * database, otherwise rename it into place. 2900*0Sstevel@tonic-gate * 2901*0Sstevel@tonic-gate * If an update: if there was no error, unlock the database. 2902*0Sstevel@tonic-gate */ 2903*0Sstevel@tonic-gate if (!update) { 2904*0Sstevel@tonic-gate if (exit_status) { 2905*0Sstevel@tonic-gate if ((kret = 2906*0Sstevel@tonic-gate krb5_db_destroy(kcontext, dbname_tmp))) { 2907*0Sstevel@tonic-gate fprintf(stderr, gettext(dbdelerr_fmt), 2908*0Sstevel@tonic-gate programname, dbname_tmp, 2909*0Sstevel@tonic-gate error_message(kret)); 2910*0Sstevel@tonic-gate exit_status++; 2911*0Sstevel@tonic-gate } 2912*0Sstevel@tonic-gate if ((kret = osa_adb_destroy_policy_db(&newparams))) { 2913*0Sstevel@tonic-gate fprintf(stderr, 2914*0Sstevel@tonic-gate gettext("%s: %s while destroying " 2915*0Sstevel@tonic-gate "policy database\n"), 2916*0Sstevel@tonic-gate programname, error_message(kret)); 2917*0Sstevel@tonic-gate exit_status++; 2918*0Sstevel@tonic-gate } 2919*0Sstevel@tonic-gate } else { 2920*0Sstevel@tonic-gate if ((kret = krb5_db_rename(kcontext, 2921*0Sstevel@tonic-gate dbname_tmp, 2922*0Sstevel@tonic-gate dbname))) { 2923*0Sstevel@tonic-gate fprintf(stderr, gettext(dbrenerr_fmt), 2924*0Sstevel@tonic-gate programname, dbname_tmp, dbname, 2925*0Sstevel@tonic-gate error_message(kret)); 2926*0Sstevel@tonic-gate exit_status++; 2927*0Sstevel@tonic-gate } 2928*0Sstevel@tonic-gate if ((kret = osa_adb_close_policy(tmppol_db))) { 2929*0Sstevel@tonic-gate fprintf(stderr, gettext(close_err_fmt), 2930*0Sstevel@tonic-gate programname, error_message(kret)); 2931*0Sstevel@tonic-gate exit_status++; 2932*0Sstevel@tonic-gate } 2933*0Sstevel@tonic-gate if ((kret = osa_adb_rename_policy_db(&newparams, 2934*0Sstevel@tonic-gate &global_params))) { 2935*0Sstevel@tonic-gate fprintf(stderr, 2936*0Sstevel@tonic-gate gettext("%s: %s while renaming " 2937*0Sstevel@tonic-gate "policy db %s to %s\n"), 2938*0Sstevel@tonic-gate programname, error_message(kret), 2939*0Sstevel@tonic-gate newparams.admin_dbname, 2940*0Sstevel@tonic-gate global_params.admin_dbname); 2941*0Sstevel@tonic-gate exit_status++; 2942*0Sstevel@tonic-gate } 2943*0Sstevel@tonic-gate } 2944*0Sstevel@tonic-gate } else { /* update */ 2945*0Sstevel@tonic-gate if (!exit_status && ((kret = osa_adb_release_lock(tmppol_db)))) { 2946*0Sstevel@tonic-gate fprintf(stderr, 2947*0Sstevel@tonic-gate gettext("%s: %s while releasing permanent lock\n"), 2948*0Sstevel@tonic-gate programname, error_message(kret)); 2949*0Sstevel@tonic-gate exit_status++; 2950*0Sstevel@tonic-gate } 2951*0Sstevel@tonic-gate if (tmppol_db && ((kret = osa_adb_close_policy(tmppol_db)))) { 2952*0Sstevel@tonic-gate fprintf(stderr, gettext(close_err_fmt), 2953*0Sstevel@tonic-gate programname, error_message(kret)); 2954*0Sstevel@tonic-gate exit_status++; 2955*0Sstevel@tonic-gate } 2956*0Sstevel@tonic-gate } 2957*0Sstevel@tonic-gate 2958*0Sstevel@tonic-gate if (dumpfile) { 2959*0Sstevel@tonic-gate (void) krb5_lock_file(kcontext, 2960*0Sstevel@tonic-gate fileno(f), KRB5_LOCKMODE_UNLOCK); 2961*0Sstevel@tonic-gate fclose(f); 2962*0Sstevel@tonic-gate } 2963*0Sstevel@tonic-gate if (dbname_tmp) 2964*0Sstevel@tonic-gate free(dbname_tmp); 2965*0Sstevel@tonic-gate krb5_free_context(kcontext); 2966*0Sstevel@tonic-gate } 2967