4 * Copyright 1990,1991,2001 by the Massachusetts Institute of Technology.
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
32 #include <kadm5/admin.h>
33 #include <kadm5/server_internal.h>
36 #include "kdb5_util.h"
37 #if defined(HAVE_REGEX_H) && defined(HAVE_REGCOMP)
39 #endif /* HAVE_REGEX_H */
42 * Needed for master key conversion.
44 static int mkey_convert;
45 static krb5_keyblock new_master_keyblock;
51 * Use compile(3) if no regcomp present.
53 #if !defined(HAVE_REGCOMP) && defined(HAVE_REGEXP_H)
54 #define INIT char *sp = instring;
55 #define GETC() (*sp++)
57 #define UNGETC(c) (--sp)
58 #define RETURN(c) return(c)
60 #define RE_BUF_SIZE 1024
62 #endif /* !HAVE_REGCOMP && HAVE_REGEXP_H */
67 krb5_context kcontext;
73 static krb5_error_code dump_k5beta_iterator (krb5_pointer,
75 static krb5_error_code dump_k5beta6_iterator (krb5_pointer,
77 static krb5_error_code dump_k5beta6_iterator_ext (krb5_pointer,
80 static krb5_error_code dump_k5beta7_princ (krb5_pointer,
82 static krb5_error_code dump_k5beta7_princ_ext (krb5_pointer,
85 static krb5_error_code dump_k5beta7_princ_withpolicy
86 (krb5_pointer, krb5_db_entry *);
87 static krb5_error_code dump_ov_princ (krb5_pointer,
89 static void dump_k5beta7_policy (void *, osa_policy_ent_t);
91 typedef krb5_error_code (*dump_func)(krb5_pointer,
94 static int process_k5beta_record (char *, krb5_context,
96 static int process_k5beta6_record (char *, krb5_context,
98 static int process_k5beta7_record (char *, krb5_context,
100 static int process_ov_record (char *, krb5_context,
102 typedef krb5_error_code (*load_func)(char *, krb5_context,
105 typedef struct _dump_version {
110 dump_func dump_princ;
111 osa_adb_iter_policy_func dump_policy;
112 load_func load_record;
115 dump_version old_version = {
116 "Kerberos version 5 old format",
117 "kdb5_edit load_dump version 2.0\n",
120 dump_k5beta_iterator,
122 process_k5beta_record,
124 dump_version beta6_version = {
125 "Kerberos version 5 beta 6 format",
126 "kdb5_edit load_dump version 3.0\n",
129 dump_k5beta6_iterator,
131 process_k5beta6_record,
133 dump_version beta7_version = {
134 "Kerberos version 5",
135 "kdb5_util load_dump version 4\n",
140 process_k5beta7_record,
142 dump_version ov_version = {
144 "OpenV*Secure V1.0\t",
152 dump_version r1_3_version = {
153 "Kerberos version 5 release 1.3",
154 "kdb5_util load_dump version 5\n",
157 dump_k5beta7_princ_withpolicy,
159 process_k5beta7_record,
163 extern char *current_dbname;
164 extern krb5_boolean dbactive;
165 extern int exit_status;
166 extern krb5_context util_context;
167 extern kadm5_config_params global_params;
171 #define k5beta_dump_header "kdb5_edit load_dump version 2.0\n"
173 static const char null_mprinc_name[] = "kdb5_dump@MISSING";
175 /* Message strings */
176 #define regex_err "%s: regular expression error - %s\n"
177 #define regex_merr "%s: regular expression match error - %s\n"
178 #define pname_unp_err "%s: cannot unparse principal name (%s)\n"
179 #define mname_unp_err "%s: cannot unparse modifier name (%s)\n"
180 #define nokeys_err "%s: cannot find any standard key for %s\n"
181 #define sdump_tl_inc_err "%s: tagged data list inconsistency for %s (counted %d, stored %d)\n"
182 #define stand_fmt_name "Kerberos version 5"
183 #define old_fmt_name "Kerberos version 5 old format"
184 #define b6_fmt_name "Kerberos version 5 beta 6 format"
185 #define ofopen_error "%s: cannot open %s for writing (%s)\n"
186 #define oflock_error "%s: cannot lock %s (%s)\n"
187 #define dumprec_err "%s: error performing %s dump (%s)\n"
188 #define dumphdr_err "%s: error dumping %s header (%s)\n"
189 #define trash_end_fmt "%s(%d): ignoring trash at end of line: "
190 #define read_name_string "name string"
191 #define read_key_type "key type"
192 #define read_key_data "key data"
193 #define read_pr_data1 "first set of principal attributes"
194 #define read_mod_name "modifier name"
195 #define read_pr_data2 "second set of principal attributes"
196 #define read_salt_data "salt data"
197 #define read_akey_type "alternate key type"
198 #define read_akey_data "alternate key data"
199 #define read_asalt_type "alternate salt type"
200 #define read_asalt_data "alternate salt data"
201 #define read_exp_data "expansion data"
202 #define store_err_fmt "%s(%d): cannot store %s(%s)\n"
203 #define add_princ_fmt "%s\n"
204 #define parse_err_fmt "%s(%d): cannot parse %s (%s)\n"
205 #define read_err_fmt "%s(%d): cannot read %s\n"
206 #define no_mem_fmt "%s(%d): no memory for buffers\n"
207 #define rhead_err_fmt "%s(%d): cannot match size tokens\n"
208 #define err_line_fmt "%s: error processing line %d of %s\n"
209 #define head_bad_fmt "%s: dump header bad in %s\n"
210 #define read_bytecnt "record byte count"
211 #define read_encdata "encoded data"
212 #define n_name_unp_fmt "%s(%s): cannot unparse name\n"
213 #define n_dec_cont_fmt "%s(%s): cannot decode contents\n"
214 #define read_nint_data "principal static attributes"
215 #define read_tcontents "tagged data contents"
216 #define read_ttypelen "tagged data type and length"
217 #define read_kcontents "key data contents"
218 #define read_ktypelen "key data type and length"
219 #define read_econtents "extra data contents"
220 #define k5beta_fmt_name "Kerberos version 5 old format"
221 #define standard_fmt_name "Kerberos version 5 format"
222 #define no_name_mem_fmt "%s: cannot get memory for temporary name\n"
223 #define ctx_err_fmt "%s: cannot initialize Kerberos context\n"
224 #define stdin_name "standard input"
225 #define remaster_err_fmt "while re-encoding keys for principal %s with new master key"
226 #define restfail_fmt "%s: %s restore failed\n"
227 #define close_err_fmt "%s: cannot close database (%s)\n"
228 #define dbinit_err_fmt "%s: cannot initialize database (%s)\n"
229 #define dblock_err_fmt "%s: cannot initialize database lock (%s)\n"
230 #define dbname_err_fmt "%s: cannot set database name to %s (%s)\n"
231 #define dbdelerr_fmt "%s: cannot delete bad database %s (%s)\n"
232 #define dbunlockerr_fmt "%s: cannot unlock database %s (%s)\n"
233 #define dbrenerr_fmt "%s: cannot rename database %s to %s (%s)\n"
234 #define dbcreaterr_fmt "%s: cannot create database %s (%s)\n"
235 #define dfile_err_fmt "%s: cannot open %s (%s)\n"
237 static const char oldoption[] = "-old";
238 static const char b6option[] = "-b6";
239 static const char b7option[] = "-b7";
240 static const char verboseoption[] = "-verbose";
241 static const char updateoption[] = "-update";
242 static const char hashoption[] = "-hash";
243 static const char ovoption[] = "-ov";
244 static const char dump_tmptrail[] = "~";
247 * Re-encrypt the key_data with the new master key...
249 static krb5_error_code master_key_convert(context, db_entry)
250 krb5_context context;
251 krb5_db_entry * db_entry;
253 krb5_error_code retval;
254 krb5_keyblock v5plainkey, *key_ptr;
255 krb5_keysalt keysalt;
257 krb5_key_data new_key_data, *key_data;
258 krb5_boolean is_mkey;
260 is_mkey = krb5_principal_compare(context, master_princ, db_entry->princ);
262 if (is_mkey && db_entry->n_key_data != 1)
264 "Master key db entry has %d keys, expecting only 1!\n",
265 db_entry->n_key_data);
266 for (i=0; i < db_entry->n_key_data; i++) {
267 key_data = &db_entry->key_data[i];
268 if (key_data->key_data_length == 0)
270 retval = krb5_dbekd_decrypt_key_data(context, &master_keyblock,
271 key_data, &v5plainkey,
276 memset(&new_key_data, 0, sizeof(new_key_data));
277 key_ptr = is_mkey ? &new_master_keyblock : &v5plainkey;
278 retval = krb5_dbekd_encrypt_key_data(context, &new_master_keyblock,
280 key_data->key_data_kvno,
284 krb5_free_keyblock_contents(context, &v5plainkey);
285 for (j = 0; j < key_data->key_data_ver; j++) {
286 if (key_data->key_data_length[j]) {
287 free(key_data->key_data_contents[j]);
290 *key_data = new_key_data;
296 * Update the "ok" file.
298 void update_ok_file (file_name)
301 /* handle slave locking/failure stuff */
304 static char ok[]=".dump_ok";
306 if ((file_ok = (char *)malloc(strlen(file_name) + strlen(ok) + 1))
308 com_err(progname, ENOMEM,
309 "while allocating filename for update_ok_file");
313 strcpy(file_ok, file_name);
315 if ((fd = open(file_ok, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) {
316 com_err(progname, errno, "while creating 'ok' file, '%s'",
322 if (write(fd, "", 1) != 1) {
323 com_err(progname, errno, "while writing to 'ok' file, '%s'",
336 * name_matches() - See if a principal name matches a regular expression
340 name_matches(name, arglist)
342 struct dump_args *arglist;
346 regmatch_t match_match;
348 char match_errmsg[BUFSIZ];
351 char regexp_buffer[RE_BUF_SIZE];
353 extern char *re_comp();
355 #endif /* HAVE_RE_COMP */
359 * Plow, brute force, through the list of names/regular expressions.
361 match = (arglist->nnames) ? 0 : 1;
362 for (i=0; i<arglist->nnames; i++) {
365 * Compile the regular expression.
367 match_error = regcomp(&match_exp, arglist->names[i], REG_EXTENDED);
369 errmsg_size = regerror(match_error,
372 sizeof(match_errmsg));
373 fprintf(stderr, regex_err, arglist->programname, match_errmsg);
377 * See if we have a match.
379 match_error = regexec(&match_exp, name, 1, &match_match, 0);
381 if (match_error != REG_NOMATCH) {
382 errmsg_size = regerror(match_error,
385 sizeof(match_errmsg));
386 fprintf(stderr, regex_merr,
387 arglist->programname, match_errmsg);
393 * We have a match. See if it matches the whole
396 if ((match_match.rm_so == 0) &&
397 (match_match.rm_eo == strlen(name)))
403 * Compile the regular expression.
405 compile(arglist->names[i],
407 ®exp_buffer[RE_BUF_SIZE],
409 if (step(name, regexp_buffer)) {
410 if ((loc1 == name) &&
411 (loc2 == &name[strlen(name)]))
416 * Compile the regular expression.
418 if (re_result = re_comp(arglist->names[i])) {
419 fprintf(stderr, regex_err, arglist->programname, re_result);
424 #else /* HAVE_RE_COMP */
426 * If no regular expression support, then just compare the strings.
428 if (!strcmp(arglist->names[i], name))
430 #endif /* HAVE_REGCOMP */
437 static krb5_error_code
438 find_enctype(dbentp, enctype, salttype, kentp)
439 krb5_db_entry *dbentp;
440 krb5_enctype enctype;
442 krb5_key_data **kentp;
446 krb5_key_data *datap;
449 datap = (krb5_key_data *) NULL;
450 for (i=0; i<dbentp->n_key_data; i++) {
451 if (( (krb5_enctype)dbentp->key_data[i].key_data_type[0] == enctype) &&
452 ((dbentp->key_data[i].key_data_type[1] == salttype) ||
454 maxkvno = dbentp->key_data[i].key_data_kvno;
455 datap = &dbentp->key_data[i];
467 * dump_k5beta_header() - Make a dump header that is recognizable by Kerberos
468 * Version 5 Beta 5 and previous releases.
470 static krb5_error_code
471 dump_k5beta_header(arglist)
472 struct dump_args *arglist;
474 /* The old header consists of the leading string */
475 fprintf(arglist->ofile, k5beta_dump_header);
481 * dump_k5beta_iterator() - Dump an entry in a format that is usable
482 * by Kerberos Version 5 Beta 5 and previous
485 static krb5_error_code
486 dump_k5beta_iterator(ptr, entry)
488 krb5_db_entry *entry;
490 krb5_error_code retval;
491 struct dump_args *arg;
492 char *name, *mod_name;
493 krb5_principal mod_princ;
494 krb5_key_data *pkey, *akey, nullkey;
495 krb5_timestamp mod_date, last_pwd_change;
499 arg = (struct dump_args *) ptr;
500 name = (char *) NULL;
501 mod_name = (char *) NULL;
502 memset(&nullkey, 0, sizeof(nullkey));
505 * Flatten the principal name.
507 if ((retval = krb5_unparse_name(arg->kcontext,
510 fprintf(stderr, pname_unp_err,
511 arg->programname, error_message(retval));
516 * Re-encode the keys in the new master key, if necessary.
519 retval = master_key_convert(arg->kcontext, entry);
521 com_err(arg->programname, retval, remaster_err_fmt, name);
527 * If we don't have any match strings, or if our name matches, then
528 * proceed with the dump, otherwise, just forget about it.
530 if (!arg->nnames || name_matches(name, arg)) {
532 * Deserialize the modifier record.
534 mod_name = (char *) NULL;
536 last_pwd_change = mod_date = 0;
537 pkey = akey = (krb5_key_data *) NULL;
538 if (!(retval = krb5_dbe_lookup_mod_princ_data(arg->kcontext,
544 * Flatten the modifier name.
546 if ((retval = krb5_unparse_name(arg->kcontext,
549 fprintf(stderr, mname_unp_err, arg->programname,
550 error_message(retval));
551 krb5_free_principal(arg->kcontext, mod_princ);
555 mod_name = strdup(null_mprinc_name);
558 * Find the last password change record and set it straight.
561 krb5_dbe_lookup_last_pwd_change(arg->kcontext, entry,
562 &last_pwd_change))) {
563 fprintf(stderr, nokeys_err, arg->programname, name);
564 krb5_xfree(mod_name);
570 * Find the 'primary' key and the 'alternate' key.
572 if ((retval = find_enctype(entry,
574 KRB5_KDB_SALTTYPE_NORMAL,
576 (retval = find_enctype(entry,
578 KRB5_KDB_SALTTYPE_V4,
580 fprintf(stderr, nokeys_err, arg->programname, name);
581 krb5_xfree(mod_name);
586 /* If we only have one type, then ship it out as the primary. */
597 * First put out strings representing the length of the variable
598 * length data in this record, then the name and the primary key type.
600 fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%d\t%s\t%d\t", strlen(name),
602 (krb5_int32) pkey->key_data_length[0],
603 (krb5_int32) akey->key_data_length[0],
604 (krb5_int32) pkey->key_data_length[1],
605 (krb5_int32) akey->key_data_length[1],
607 (krb5_int32) pkey->key_data_type[0]);
608 for (i=0; i<pkey->key_data_length[0]; i++) {
609 fprintf(arg->ofile, "%02x", pkey->key_data_contents[0][i]);
612 * Second, print out strings representing the standard integer
613 * data in this record.
616 "\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%s\t%u\t%u\t%u\t",
617 (krb5_int32) pkey->key_data_kvno,
618 entry->max_life, entry->max_renewable_life,
619 1 /* Fake mkvno */, entry->expiration, entry->pw_expiration,
620 last_pwd_change, entry->last_success, entry->last_failed,
621 entry->fail_auth_count, mod_name, mod_date,
622 entry->attributes, pkey->key_data_type[1]);
624 /* Pound out the salt data, if present. */
625 for (i=0; i<pkey->key_data_length[1]; i++) {
626 fprintf(arg->ofile, "%02x", pkey->key_data_contents[1][i]);
628 /* Pound out the alternate key type and contents */
629 fprintf(arg->ofile, "\t%u\t", akey->key_data_type[0]);
630 for (i=0; i<akey->key_data_length[0]; i++) {
631 fprintf(arg->ofile, "%02x", akey->key_data_contents[0][i]);
633 /* Pound out the alternate salt type and contents */
634 fprintf(arg->ofile, "\t%u\t", akey->key_data_type[1]);
635 for (i=0; i<akey->key_data_length[1]; i++) {
636 fprintf(arg->ofile, "%02x", akey->key_data_contents[1][i]);
638 /* Pound out the expansion data. (is null) */
639 for (i=0; i < 8; i++) {
640 fprintf(arg->ofile, "\t%u", 0);
642 fprintf(arg->ofile, ";\n");
643 /* If we're blabbing, do it */
645 fprintf(stderr, "%s\n", name);
646 krb5_xfree(mod_name);
653 * dump_k5beta6_iterator() - Output a dump record in krb5b6 format.
655 static krb5_error_code
656 dump_k5beta6_iterator(ptr, entry)
658 krb5_db_entry *entry;
660 return dump_k5beta6_iterator_ext(ptr, entry, 0);
663 static krb5_error_code
664 dump_k5beta6_iterator_ext(ptr, entry, kadm)
666 krb5_db_entry *entry;
669 krb5_error_code retval;
670 struct dump_args *arg;
673 krb5_key_data *kdata;
674 int counter, skip, i, j;
677 arg = (struct dump_args *) ptr;
678 name = (char *) NULL;
681 * Flatten the principal name.
683 if ((retval = krb5_unparse_name(arg->kcontext,
686 fprintf(stderr, pname_unp_err,
687 arg->programname, error_message(retval));
692 * Re-encode the keys in the new master key, if necessary.
695 retval = master_key_convert(arg->kcontext, entry);
697 com_err(arg->programname, retval, remaster_err_fmt, name);
703 * If we don't have any match strings, or if our name matches, then
704 * proceed with the dump, otherwise, just forget about it.
706 if (!arg->nnames || name_matches(name, arg)) {
708 * We'd like to just blast out the contents as they would appear in
709 * the database so that we can just suck it back in, but it doesn't
710 * lend itself to easy editing.
714 * The dump format is as follows:
715 * len strlen(name) n_tl_data n_key_data e_length
717 * attributes max_life max_renewable_life expiration
718 * pw_expiration last_success last_failed fail_auth_count
719 * n_tl_data*[type length <contents>]
720 * n_key_data*[ver kvno ver*(type length <contents>)]
722 * Fields which are not encapsulated by angle-brackets are to appear
723 * verbatim. A bracketed field's absence is indicated by a -1 in its
728 * Make sure that the tagged list is reasonably correct.
731 for (tlp = entry->tl_data; tlp; tlp = tlp->tl_data_next) {
733 * don't dump tl data types we know aren't understood by
734 * earlier revisions [krb5-admin/89]
736 switch (tlp->tl_data_type) {
737 case KRB5_TL_KADM_DATA:
749 if (counter + skip == entry->n_tl_data) {
750 /* Pound out header */
751 fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%s\t",
755 (int) entry->n_key_data,
756 (int) entry->e_length,
758 fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t",
761 entry->max_renewable_life,
763 entry->pw_expiration,
766 entry->fail_auth_count);
767 /* Pound out tagged data. */
768 for (tlp = entry->tl_data; tlp; tlp = tlp->tl_data_next) {
769 if (tlp->tl_data_type == KRB5_TL_KADM_DATA && !kadm)
770 continue; /* see above, [krb5-admin/89] */
772 fprintf(arg->ofile, "%d\t%d\t",
773 (int) tlp->tl_data_type,
774 (int) tlp->tl_data_length);
775 if (tlp->tl_data_length)
776 for (i=0; i<tlp->tl_data_length; i++)
777 fprintf(arg->ofile, "%02x", tlp->tl_data_contents[i]);
779 fprintf(arg->ofile, "%d", -1);
780 fprintf(arg->ofile, "\t");
783 /* Pound out key data */
784 for (counter=0; counter<entry->n_key_data; counter++) {
785 kdata = &entry->key_data[counter];
786 fprintf(arg->ofile, "%d\t%d\t",
787 (int) kdata->key_data_ver,
788 (int) kdata->key_data_kvno);
789 for (i=0; i<kdata->key_data_ver; i++) {
790 fprintf(arg->ofile, "%d\t%d\t",
791 kdata->key_data_type[i],
792 kdata->key_data_length[i]);
793 if (kdata->key_data_length[i])
794 for (j=0; j<kdata->key_data_length[i]; j++)
795 fprintf(arg->ofile, "%02x",
796 kdata->key_data_contents[i][j]);
798 fprintf(arg->ofile, "%d", -1);
799 fprintf(arg->ofile, "\t");
803 /* Pound out extra data */
805 for (i=0; i<entry->e_length; i++)
806 fprintf(arg->ofile, "%02x", entry->e_data[i]);
808 fprintf(arg->ofile, "%d", -1);
811 fprintf(arg->ofile, ";\n");
814 fprintf(stderr, "%s\n", name);
817 fprintf(stderr, sdump_tl_inc_err,
818 arg->programname, name, counter+skip,
819 (int) entry->n_tl_data);
828 * dump_k5beta7_iterator() - Output a dump record in krb5b7 format.
830 static krb5_error_code
831 dump_k5beta7_princ(ptr, entry)
833 krb5_db_entry *entry;
835 return dump_k5beta7_princ_ext(ptr, entry, 0);
838 static krb5_error_code
839 dump_k5beta7_princ_ext(ptr, entry, kadm)
841 krb5_db_entry *entry;
844 krb5_error_code retval;
845 struct dump_args *arg;
850 arg = (struct dump_args *) ptr;
851 name = (char *) NULL;
854 * Flatten the principal name.
856 if ((retval = krb5_unparse_name(arg->kcontext,
859 fprintf(stderr, pname_unp_err,
860 arg->programname, error_message(retval));
864 * If we don't have any match strings, or if our name matches, then
865 * proceed with the dump, otherwise, just forget about it.
867 if (!arg->nnames || name_matches(name, arg)) {
868 fprintf(arg->ofile, "princ\t");
870 /* save the callee from matching the name again */
871 tmp_nnames = arg->nnames;
873 retval = dump_k5beta6_iterator_ext(ptr, entry, kadm);
874 arg->nnames = tmp_nnames;
881 static krb5_error_code
882 dump_k5beta7_princ_withpolicy(ptr, entry)
884 krb5_db_entry *entry;
886 return dump_k5beta7_princ_ext(ptr, entry, 1);
889 void dump_k5beta7_policy(void *data, osa_policy_ent_t entry)
891 struct dump_args *arg;
893 arg = (struct dump_args *) data;
894 fprintf(arg->ofile, "policy\t%s\t%d\t%d\t%d\t%d\t%d\t%d\n", entry->name,
895 entry->pw_min_life, entry->pw_max_life, entry->pw_min_length,
896 entry->pw_min_classes, entry->pw_history_num,
897 entry->policy_refcnt);
900 static void print_key_data(FILE *f, krb5_key_data *key_data)
904 fprintf(f, "%d\t%d\t", key_data->key_data_type[0],
905 key_data->key_data_length[0]);
906 for(c = 0; c < key_data->key_data_length[0]; c++)
908 key_data->key_data_contents[0][c]);
912 * Function: print_princ
914 * Purpose: output osa_adb_princ_ent data in a human
915 * readable format (which is a format suitable for
916 * ovsec_adm_import consumption)
919 * data (input) pointer to a structure containing a FILE *
920 * and a record counter.
921 * entry (input) entry to get dumped.
922 * <return value> void
928 * writes data to the specified file pointerp.
934 static krb5_error_code dump_ov_princ(krb5_pointer ptr, krb5_db_entry *kdb)
938 struct dump_args *arg;
939 krb5_tl_data tl_data;
940 osa_princ_ent_rec adb;
943 arg = (struct dump_args *) ptr;
945 * XXX Currently, lookup_tl_data always returns zero; it sets
946 * tl_data->tl_data_length to zero if the type isn't found.
947 * This should be fixed...
950 * XXX Should this function do nothing for a principal with no
951 * admin data, or print a record of "default" values? See
952 * comment in server_kdb.c to help decide.
954 tl_data.tl_data_type = KRB5_TL_KADM_DATA;
955 if (krb5_dbe_lookup_tl_data(arg->kcontext, kdb, &tl_data)
956 || (tl_data.tl_data_length == 0))
959 memset(&adb, 0, sizeof(adb));
960 xdrmem_create(&xdrs, tl_data.tl_data_contents,
961 tl_data.tl_data_length, XDR_DECODE);
962 if (! xdr_osa_princ_ent_rec(&xdrs, &adb)) {
964 return(KADM5_XDR_FAILURE);
968 krb5_unparse_name(arg->kcontext, kdb->princ, &princstr);
969 fprintf(arg->ofile, "princ\t%s\t", princstr);
970 if(adb.policy == NULL)
971 fputc('\t', arg->ofile);
973 fprintf(arg->ofile, "%s\t", adb.policy);
974 fprintf(arg->ofile, "%lx\t%d\t%d\t%d", adb.aux_attributes,
975 adb.old_key_len,adb.old_key_next, adb.admin_history_kvno);
977 for (x = 0; x < adb.old_key_len; x++) {
979 for (y = 0; y < adb.old_keys[x].n_key_data; y++) {
980 krb5_key_data *key_data = &adb.old_keys[x].key_data[y];
982 if (key_data->key_data_type[0] != ENCTYPE_DES_CBC_CRC)
985 fprintf(stderr, "Warning! Multiple DES-CBC-CRC keys "
986 "for principal %s; skipping duplicates.\n",
992 fputc('\t', arg->ofile);
993 print_key_data(arg->ofile, key_data);
996 fprintf(stderr, "Warning! No DES-CBC-CRC key for principal "
997 "%s, cannot generate OV-compatible record; skipping\n",
1001 fputc('\n', arg->ofile);
1008 * dump_db [-old] [-b6] [-b7] [-ov] [-verbose] [-mkey_convert]
1009 * [-new_mkey_file mkey_file] [-rev] [-recurse]
1010 * [filename [principals...]]
1018 struct dump_args arglist;
1021 krb5_error_code kret, retval;
1024 krb5_boolean locked;
1025 char *new_mkey_file = 0;
1028 * Parse the arguments.
1030 programname = argv[0];
1031 if (strrchr(programname, (int) '/'))
1032 programname = strrchr(argv[0], (int) '/') + 1;
1033 ofile = (char *) NULL;
1034 dump = &r1_3_version;
1035 arglist.verbose = 0;
1042 * Parse the qualifiers.
1044 for (aindex = 1; aindex < argc; aindex++) {
1045 if (!strcmp(argv[aindex], oldoption))
1046 dump = &old_version;
1047 else if (!strcmp(argv[aindex], b6option))
1048 dump = &beta6_version;
1049 else if (!strcmp(argv[aindex], b7option))
1050 dump = &beta7_version;
1051 else if (!strcmp(argv[aindex], ovoption))
1053 else if (!strcmp(argv[aindex], verboseoption))
1055 else if (!strcmp(argv[aindex], "-mkey_convert"))
1057 else if (!strcmp(argv[aindex], "-new_mkey_file")) {
1058 new_mkey_file = argv[++aindex];
1060 } else if (!strcmp(argv[aindex], "-rev"))
1062 else if (!strcmp(argv[aindex], "-recurse"))
1068 arglist.names = (char **) NULL;
1070 if (aindex < argc) {
1071 ofile = argv[aindex];
1073 if (aindex < argc) {
1074 arglist.names = &argv[aindex];
1075 arglist.nnames = argc - aindex;
1080 * Make sure the database is open. The policy database only has
1081 * to be opened if we try a dump that uses it.
1084 com_err(argv[0], 0, Err_no_database);
1090 * If we're doing a master key conversion, set up for it.
1093 if (!valid_master_key) {
1094 /* TRUE here means read the keyboard, but only once */
1095 retval = krb5_db_fetch_mkey(util_context,
1097 master_keyblock.enctype,
1102 com_err(argv[0], retval,
1103 "while reading master key");
1106 retval = krb5_db_verify_master_key(util_context,
1110 com_err(argv[0], retval,
1111 "while verifying master key");
1115 new_master_keyblock.enctype = global_params.enctype;
1116 if (new_master_keyblock.enctype == ENCTYPE_UNKNOWN)
1117 new_master_keyblock.enctype = DEFAULT_KDC_ENCTYPE;
1119 printf("Please enter new master key....\n");
1120 if ((retval = krb5_db_fetch_mkey(util_context, master_princ,
1121 new_master_keyblock.enctype,
1122 (new_mkey_file == 0) ?
1123 (krb5_boolean) 1 : 0,
1126 &new_master_keyblock))) {
1127 com_err(argv[0], retval, "while reading new master key");
1134 if (ofile && strcmp(ofile, "-")) {
1136 * Discourage accidental dumping to filenames beginning with '-'.
1138 if (ofile[0] == '-')
1141 * Make sure that we don't open and truncate on the fopen,
1142 * since that may hose an on-going kprop process.
1144 * We could also control this by opening for read and
1145 * write, doing an flock with LOCK_EX, and then
1146 * truncating the file once we have gotten the lock,
1147 * but that would involve more OS dependencies than I
1151 if (!(f = fopen(ofile, "w"))) {
1152 fprintf(stderr, ofopen_error,
1153 programname, ofile, error_message(errno));
1157 if ((kret = krb5_lock_file(util_context,
1159 KRB5_LOCKMODE_EXCLUSIVE))) {
1160 fprintf(stderr, oflock_error,
1161 programname, ofile, error_message(kret));
1170 arglist.programname = programname;
1172 arglist.kcontext = util_context;
1173 fprintf(arglist.ofile, "%s", dump->header);
1174 if (dump->header[strlen(dump->header)-1] != '\n')
1175 fputc('\n', arglist.ofile);
1177 if ((kret = krb5_db_iterate(util_context,
1180 (krb5_pointer) &arglist))) { /* TBD: backwards and recursive not supported */
1181 fprintf(stderr, dumprec_err,
1182 programname, dump->name, error_message(kret));
1185 if (dump->dump_policy &&
1186 (kret = krb5_db_iter_policy( util_context, "*", dump->dump_policy,
1188 fprintf(stderr, dumprec_err, programname, dump->name,
1189 error_message(kret));
1192 if (ofile && f != stdout && !exit_status) {
1194 update_ok_file(ofile);
1198 (void) krb5_lock_file(util_context, fileno(f), KRB5_LOCKMODE_UNLOCK);
1202 * Read a string of bytes while counting the number of lines passed.
1205 read_string(f, buf, len, lp)
1215 for (i=0; i<len; i++) {
1230 * Read a string of two character representations of bytes.
1233 read_octet_string(f, buf, len)
1242 for (i=0; i<len; i++) {
1243 if (fscanf(f, "%02x", &c) != 1) {
1247 buf[i] = (krb5_octet) c;
1253 * Find the end of an old format record.
1256 find_record_end(f, fn, lineno)
1263 if (((ch = fgetc(f)) != ';') || ((ch = fgetc(f)) != '\n')) {
1264 fprintf(stderr, trash_end_fmt, fn, lineno);
1265 while (ch != '\n') {
1275 * update_tl_data() - Generate the tl_data entries.
1277 static krb5_error_code
1278 update_tl_data(kcontext, dbentp, mod_name, mod_date, last_pwd_change)
1279 krb5_context kcontext;
1280 krb5_db_entry *dbentp;
1281 krb5_principal mod_name;
1282 krb5_timestamp mod_date;
1283 krb5_timestamp last_pwd_change;
1285 krb5_error_code kret;
1290 * Handle modification principal.
1293 krb5_tl_mod_princ mprinc;
1295 memset(&mprinc, 0, sizeof(mprinc));
1296 if (!(kret = krb5_copy_principal(kcontext,
1298 &mprinc.mod_princ))) {
1299 mprinc.mod_date = mod_date;
1300 kret = krb5_dbe_encode_mod_princ_data(kcontext,
1304 if (mprinc.mod_princ)
1305 krb5_free_principal(kcontext, mprinc.mod_princ);
1309 * Handle last password change.
1312 krb5_tl_data *pwchg;
1313 krb5_boolean linked;
1315 /* Find a previously existing entry */
1316 for (pwchg = dbentp->tl_data;
1317 (pwchg) && (pwchg->tl_data_type != KRB5_TL_LAST_PWD_CHANGE);
1318 pwchg = pwchg->tl_data_next);
1320 /* Check to see if we found one. */
1323 /* No, allocate a new one */
1324 if ((pwchg = (krb5_tl_data *) malloc(sizeof(krb5_tl_data)))) {
1325 memset(pwchg, 0, sizeof(krb5_tl_data));
1326 if (!(pwchg->tl_data_contents =
1327 (krb5_octet *) malloc(sizeof(krb5_timestamp)))) {
1329 pwchg = (krb5_tl_data *) NULL;
1332 pwchg->tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
1333 pwchg->tl_data_length =
1334 (krb5_int16) sizeof(krb5_timestamp);
1341 /* Do we have an entry? */
1342 if (pwchg && pwchg->tl_data_contents) {
1344 krb5_kdb_encode_int32(last_pwd_change, pwchg->tl_data_contents);
1345 /* Link it in if necessary */
1347 pwchg->tl_data_next = dbentp->tl_data;
1348 dbentp->tl_data = pwchg;
1349 dbentp->n_tl_data++;
1361 * process_k5beta_record() - Handle a dump record in old format.
1363 * Returns -1 for end of file, 0 for success and 1 for failure.
1366 process_k5beta_record(fname, kcontext, filep, verbose, linenop)
1368 krb5_context kcontext;
1375 krb5_db_entry dbent;
1376 int name_len, mod_name_len, key_len;
1377 int alt_key_len, salt_len, alt_salt_len;
1380 int tmpint1, tmpint2, tmpint3;
1382 const char *try2read;
1384 krb5_key_data *pkey, *akey;
1385 krb5_timestamp last_pwd_change, mod_date;
1386 krb5_principal mod_princ;
1387 krb5_error_code kret;
1389 try2read = (char *) NULL;
1392 memset((char *)&dbent, 0, sizeof(dbent));
1394 /* Make sure we've got key_data entries */
1395 if (krb5_dbe_create_key_data(kcontext, &dbent) ||
1396 krb5_dbe_create_key_data(kcontext, &dbent)) {
1397 krb5_db_free_principal(kcontext, &dbent, 1);
1400 pkey = &dbent.key_data[0];
1401 akey = &dbent.key_data[1];
1404 * Match the sizes. 6 tokens to match.
1406 nmatched = fscanf(filep, "%d\t%d\t%d\t%d\t%d\t%d\t",
1407 &name_len, &mod_name_len, &key_len,
1408 &alt_key_len, &salt_len, &alt_salt_len);
1409 if (nmatched == 6) {
1410 pkey->key_data_length[0] = key_len;
1411 akey->key_data_length[0] = alt_key_len;
1412 pkey->key_data_length[1] = salt_len;
1413 akey->key_data_length[1] = alt_salt_len;
1414 name = (char *) NULL;
1415 mod_name = (char *) NULL;
1417 * Get the memory for the variable length fields.
1419 if ((name = (char *) malloc((size_t) (name_len + 1))) &&
1420 (mod_name = (char *) malloc((size_t) (mod_name_len + 1))) &&
1422 (pkey->key_data_contents[0] =
1423 (krb5_octet *) malloc((size_t) (key_len + 1)))) &&
1425 (akey->key_data_contents[0] =
1426 (krb5_octet *) malloc((size_t) (alt_key_len + 1)))) &&
1428 (pkey->key_data_contents[1] =
1429 (krb5_octet *) malloc((size_t) (salt_len + 1)))) &&
1431 (akey->key_data_contents[1] =
1432 (krb5_octet *) malloc((size_t) (alt_salt_len + 1))))
1436 /* Read the principal name */
1437 if (read_string(filep, name, name_len, linenop)) {
1438 try2read = read_name_string;
1441 /* Read the key type */
1442 if (!error && (fscanf(filep, "\t%d\t", &tmpint1) != 1)) {
1443 try2read = read_key_type;
1446 pkey->key_data_type[0] = tmpint1;
1447 /* Read the old format key */
1448 if (!error && read_octet_string(filep,
1449 pkey->key_data_contents[0],
1450 pkey->key_data_length[0])) {
1451 try2read = read_key_data;
1454 /* convert to a new format key */
1455 /* the encrypted version is stored as the unencrypted key length
1456 (4 bytes, MSB first) followed by the encrypted key. */
1457 if ((pkey->key_data_length[0] > 4)
1458 && (pkey->key_data_contents[0][0] == 0)
1459 && (pkey->key_data_contents[0][1] == 0)) {
1460 /* this really does look like an old key, so drop and swap */
1461 /* the *new* length is 2 bytes, LSB first, sigh. */
1462 size_t shortlen = pkey->key_data_length[0]-4+2;
1463 krb5_octet *shortcopy = (krb5_octet *) malloc(shortlen);
1464 krb5_octet *origdata = pkey->key_data_contents[0];
1465 shortcopy[0] = origdata[3];
1466 shortcopy[1] = origdata[2];
1467 memcpy(shortcopy+2,origdata+4,shortlen-2);
1469 pkey->key_data_length[0] = shortlen;
1470 pkey->key_data_contents[0] = shortcopy;
1473 /* Read principal attributes */
1474 if (!error && (fscanf(filep,
1475 "\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t",
1476 &tmpint1, &dbent.max_life,
1477 &dbent.max_renewable_life,
1478 &tmpint2, &dbent.expiration,
1479 &dbent.pw_expiration, &last_pwd_change,
1480 &dbent.last_success, &dbent.last_failed,
1482 try2read = read_pr_data1;
1485 pkey->key_data_kvno = tmpint1;
1486 dbent.fail_auth_count = tmpint3;
1487 /* Read modifier name */
1488 if (!error && read_string(filep,
1492 try2read = read_mod_name;
1495 /* Read second set of attributes */
1496 if (!error && (fscanf(filep, "\t%u\t%u\t%u\t",
1497 &mod_date, &dbent.attributes,
1499 try2read = read_pr_data2;
1502 pkey->key_data_type[1] = tmpint1;
1503 /* Read salt data */
1504 if (!error && read_octet_string(filep,
1505 pkey->key_data_contents[1],
1506 pkey->key_data_length[1])) {
1507 try2read = read_salt_data;
1510 /* Read alternate key type */
1511 if (!error && (fscanf(filep, "\t%u\t", &tmpint1) != 1)) {
1512 try2read = read_akey_type;
1515 akey->key_data_type[0] = tmpint1;
1516 /* Read alternate key */
1517 if (!error && read_octet_string(filep,
1518 akey->key_data_contents[0],
1519 akey->key_data_length[0])) {
1520 try2read = read_akey_data;
1524 /* convert to a new format key */
1525 /* the encrypted version is stored as the unencrypted key length
1526 (4 bytes, MSB first) followed by the encrypted key. */
1527 if ((akey->key_data_length[0] > 4)
1528 && (akey->key_data_contents[0][0] == 0)
1529 && (akey->key_data_contents[0][1] == 0)) {
1530 /* this really does look like an old key, so drop and swap */
1531 /* the *new* length is 2 bytes, LSB first, sigh. */
1532 size_t shortlen = akey->key_data_length[0]-4+2;
1533 krb5_octet *shortcopy = (krb5_octet *) malloc(shortlen);
1534 krb5_octet *origdata = akey->key_data_contents[0];
1535 shortcopy[0] = origdata[3];
1536 shortcopy[1] = origdata[2];
1537 memcpy(shortcopy+2,origdata+4,shortlen-2);
1539 akey->key_data_length[0] = shortlen;
1540 akey->key_data_contents[0] = shortcopy;
1543 /* Read alternate salt type */
1544 if (!error && (fscanf(filep, "\t%u\t", &tmpint1) != 1)) {
1545 try2read = read_asalt_type;
1548 akey->key_data_type[1] = tmpint1;
1549 /* Read alternate salt data */
1550 if (!error && read_octet_string(filep,
1551 akey->key_data_contents[1],
1552 akey->key_data_length[1])) {
1553 try2read = read_asalt_data;
1556 /* Read expansion data - discard it */
1558 for (i=0; i<8; i++) {
1559 if (fscanf(filep, "\t%u", &tmpint1) != 1) {
1560 try2read = read_exp_data;
1566 find_record_end(filep, fname, *linenop);
1570 * If no error, then we're done reading. Now parse the names
1571 * and store the database dbent.
1574 if (!(kret = krb5_parse_name(kcontext,
1577 if (!(kret = krb5_parse_name(kcontext,
1581 krb5_dbe_update_mod_princ_data(kcontext,
1586 krb5_dbe_update_last_pwd_change(kcontext,
1588 last_pwd_change))) {
1591 dbent.len = KRB5_KDB_V1_BASE_LENGTH;
1592 pkey->key_data_ver = (pkey->key_data_type[1] || pkey->key_data_length[1]) ?
1594 akey->key_data_ver = (akey->key_data_type[1] || akey->key_data_length[1]) ?
1596 if ((pkey->key_data_type[0] ==
1597 akey->key_data_type[0]) &&
1598 (pkey->key_data_type[1] ==
1599 akey->key_data_type[1]))
1601 else if ((akey->key_data_type[0] == 0)
1602 && (akey->key_data_length[0] == 0)
1603 && (akey->key_data_type[1] == 0)
1604 && (akey->key_data_length[1] == 0))
1606 if ((kret = krb5_db_put_principal(kcontext,
1610 fprintf(stderr, store_err_fmt,
1611 fname, *linenop, name,
1612 error_message(kret));
1617 fprintf(stderr, add_princ_fmt, name);
1620 dbent.n_key_data = 2;
1622 krb5_free_principal(kcontext, mod_princ);
1625 fprintf(stderr, parse_err_fmt,
1626 fname, *linenop, mod_name,
1627 error_message(kret));
1632 fprintf(stderr, parse_err_fmt,
1633 fname, *linenop, name, error_message(kret));
1638 fprintf(stderr, read_err_fmt, fname, *linenop, try2read);
1642 fprintf(stderr, no_mem_fmt, fname, *linenop);
1645 krb5_db_free_principal(kcontext, &dbent, 1);
1652 if (nmatched != EOF)
1653 fprintf(stderr, rhead_err_fmt, fname, *linenop);
1661 * process_k5beta6_record() - Handle a dump record in krb5b6 format.
1663 * Returns -1 for end of file, 0 for success and 1 for failure.
1666 process_k5beta6_record(fname, kcontext, filep, verbose, linenop)
1668 krb5_context kcontext;
1674 krb5_db_entry dbentry;
1675 krb5_int32 t1, t2, t3, t4, t5, t6, t7, t8, t9;
1680 krb5_key_data *kp, *kdatap;
1681 krb5_tl_data **tlp, *tl;
1683 krb5_error_code kret;
1684 const char *try2read;
1686 try2read = (char *) NULL;
1687 memset((char *) &dbentry, 0, sizeof(dbentry));
1690 name = (char *) NULL;
1691 kp = (krb5_key_data *) NULL;
1692 op = (krb5_octet *) NULL;
1695 nread = fscanf(filep, "%d\t%d\t%d\t%d\t%d\t", &t1, &t2, &t3, &t4, &t5);
1697 /* Get memory for flattened principal name */
1698 if (!(name = (char *) malloc((size_t) t2 + 1)))
1701 /* Get memory for and form tagged data linked list */
1702 tlp = &dbentry.tl_data;
1703 for (i=0; i<t3; i++) {
1704 if ((*tlp = (krb5_tl_data *) malloc(sizeof(krb5_tl_data)))) {
1705 memset(*tlp, 0, sizeof(krb5_tl_data));
1706 tlp = &((*tlp)->tl_data_next);
1707 dbentry.n_tl_data++;
1715 /* Get memory for key list */
1716 if (t4 && !(kp = (krb5_key_data *) malloc((size_t)
1717 (t4*sizeof(krb5_key_data)))))
1720 /* Get memory for extra data */
1721 if (t5 && !(op = (krb5_octet *) malloc((size_t) t5)))
1726 dbentry.n_key_data = t4;
1727 dbentry.e_length = t5;
1729 memset(kp, 0, (size_t) (t4*sizeof(krb5_key_data)));
1730 dbentry.key_data = kp;
1731 kp = (krb5_key_data *) NULL;
1734 memset(op, 0, (size_t) t5);
1735 dbentry.e_data = op;
1736 op = (krb5_octet *) NULL;
1739 /* Read in and parse the principal name */
1740 if (!read_string(filep, name, t2, linenop) &&
1741 !(kret = krb5_parse_name(kcontext, name, &dbentry.princ))) {
1743 /* Get the fixed principal attributes */
1744 nread = fscanf(filep, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t",
1745 &t2, &t3, &t4, &t5, &t6, &t7, &t8, &t9);
1747 dbentry.attributes = (krb5_flags) t2;
1748 dbentry.max_life = (krb5_deltat) t3;
1749 dbentry.max_renewable_life = (krb5_deltat) t4;
1750 dbentry.expiration = (krb5_timestamp) t5;
1751 dbentry.pw_expiration = (krb5_timestamp) t6;
1752 dbentry.last_success = (krb5_timestamp) t7;
1753 dbentry.last_failed = (krb5_timestamp) t8;
1754 dbentry.fail_auth_count = (krb5_kvno) t9;
1756 try2read = read_nint_data;
1761 * Get the tagged data.
1763 * Really, this code ought to discard tl data types
1764 * that it knows are special to the current version
1765 * and were not supported in the previous version.
1766 * But it's a pain to implement that here, and doing
1767 * it at dump time has almost as good an effect, so
1768 * that's what I did. [krb5-admin/89]
1770 if (!error && dbentry.n_tl_data) {
1771 for (tl = dbentry.tl_data; tl; tl = tl->tl_data_next) {
1772 nread = fscanf(filep, "%d\t%d\t", &t1, &t2);
1774 tl->tl_data_type = (krb5_int16) t1;
1775 tl->tl_data_length = (krb5_int16) t2;
1776 if (tl->tl_data_length) {
1777 if (!(tl->tl_data_contents =
1778 (krb5_octet *) malloc((size_t) t2+1)) ||
1779 read_octet_string(filep,
1780 tl->tl_data_contents,
1782 try2read = read_tcontents;
1788 /* Should be a null field */
1789 nread = fscanf(filep, "%d", &t9);
1790 if ((nread != 1) || (t9 != -1)) {
1792 try2read = read_tcontents;
1798 try2read = read_ttypelen;
1805 /* Get the key data */
1806 if (!error && dbentry.n_key_data) {
1807 for (i=0; !error && (i<dbentry.n_key_data); i++) {
1808 kdatap = &dbentry.key_data[i];
1809 nread = fscanf(filep, "%d\t%d\t", &t1, &t2);
1811 kdatap->key_data_ver = (krb5_int16) t1;
1812 kdatap->key_data_kvno = (krb5_int16) t2;
1814 for (j=0; j<t1; j++) {
1815 nread = fscanf(filep, "%d\t%d\t", &t3, &t4);
1817 kdatap->key_data_type[j] = t3;
1818 kdatap->key_data_length[j] = t4;
1820 if (!(kdatap->key_data_contents[j] =
1822 malloc((size_t) t4+1)) ||
1823 read_octet_string(filep,
1824 kdatap->key_data_contents[j],
1826 try2read = read_kcontents;
1832 /* Should be a null field */
1833 nread = fscanf(filep, "%d", &t9);
1834 if ((nread != 1) || (t9 != -1)) {
1836 try2read = read_kcontents;
1842 try2read = read_ktypelen;
1851 /* Get the extra data */
1852 if (!error && dbentry.e_length) {
1853 if (read_octet_string(filep,
1855 (int) dbentry.e_length)) {
1856 try2read = read_econtents;
1861 nread = fscanf(filep, "%d", &t9);
1862 if ((nread != 1) || (t9 != -1)) {
1864 try2read = read_econtents;
1868 /* Finally, find the end of the record. */
1870 find_record_end(filep, fname, *linenop);
1873 * We have either read in all the data or choked.
1877 if ((kret = krb5_db_put_principal(kcontext,
1880 fprintf(stderr, store_err_fmt,
1882 name, error_message(kret));
1886 fprintf(stderr, add_princ_fmt, name);
1891 fprintf(stderr, read_err_fmt, fname, *linenop, try2read);
1896 fprintf(stderr, parse_err_fmt,
1897 fname, *linenop, name, error_message(kret));
1899 fprintf(stderr, no_mem_fmt, fname, *linenop);
1903 fprintf(stderr, rhead_err_fmt, fname, *linenop);
1912 krb5_db_free_principal(kcontext, &dbentry, 1);
1922 process_k5beta7_policy(fname, kcontext, filep, verbose, linenop, pol_db)
1924 krb5_context kcontext;
1930 osa_policy_ent_rec rec;
1937 nread = fscanf(filep, "%1024s\t%d\t%d\t%d\t%d\t%d\t%d", rec.name,
1938 &rec.pw_min_life, &rec.pw_max_life,
1939 &rec.pw_min_length, &rec.pw_min_classes,
1940 &rec.pw_history_num, &rec.policy_refcnt);
1943 else if (nread != 7) {
1944 fprintf(stderr, "cannot parse policy on line %d (%d read)\n",
1949 if ((ret = krb5_db_create_policy(kcontext, &rec))) {
1951 ((ret = krb5_db_put_policy(kcontext, &rec)))) {
1952 fprintf(stderr, "cannot create policy on line %d: %s\n",
1953 *linenop, error_message(ret));
1958 fprintf(stderr, "created policy %s\n", rec.name);
1964 * process_k5beta7_record() - Handle a dump record in krb5b7 format.
1966 * Returns -1 for end of file, 0 for success and 1 for failure.
1969 process_k5beta7_record(fname, kcontext, filep, verbose, linenop)
1971 krb5_context kcontext;
1979 nread = fscanf(filep, "%100s\t", rectype);
1982 else if (nread != 1)
1984 if (strcmp(rectype, "princ") == 0)
1985 process_k5beta6_record(fname, kcontext, filep, verbose,
1987 else if (strcmp(rectype, "policy") == 0)
1988 process_k5beta7_policy(fname, kcontext, filep, verbose,
1991 fprintf(stderr, "unknown record type \"%s\" on line %d\n",
2000 * process_ov_record() - Handle a dump record in OpenV*Secure 1.0 format.
2002 * Returns -1 for end of file, 0 for success and 1 for failure.
2005 process_ov_record(fname, kcontext, filep, verbose, linenop)
2007 krb5_context kcontext;
2015 nread = fscanf(filep, "%100s\t", rectype);
2018 else if (nread != 1)
2020 if (strcmp(rectype, "princ") == 0)
2021 process_ov_principal(fname, kcontext, filep, verbose,
2023 else if (strcmp(rectype, "policy") == 0)
2024 process_k5beta7_policy(fname, kcontext, filep, verbose,
2026 else if (strcmp(rectype, "End") == 0)
2029 fprintf(stderr, "unknown record type \"%s\" on line %d\n",
2038 * restore_dump() - Restore the database from any version dump file.
2041 restore_dump(programname, kcontext, dumpfile, f, verbose, dump)
2043 krb5_context kcontext;
2056 * Process the records.
2058 while (!(error = (*dump->load_record)(dumpfile,
2065 fprintf(stderr, err_line_fmt, programname, lineno, dumpfile);
2073 * Usage: load_db [-old] [-ov] [-b6] [-b7] [-verbose] [-update] [-hash]
2081 kadm5_config_params newparams;
2082 krb5_error_code kret;
2083 krb5_context kcontext;
2085 extern char *optarg;
2093 int update, verbose;
2098 * Parse the arguments.
2100 programname = argv[0];
2101 if (strrchr(programname, (int) '/'))
2102 programname = strrchr(argv[0], (int) '/') + 1;
2103 dumpfile = (char *) NULL;
2104 dbname = global_params.dbname;
2108 crflags = KRB5_KDB_CREATE_BTREE;
2110 dbname_tmp = (char *) NULL;
2111 for (aindex = 1; aindex < argc; aindex++) {
2112 if (!strcmp(argv[aindex], oldoption))
2113 load = &old_version;
2114 else if (!strcmp(argv[aindex], b6option))
2115 load = &beta6_version;
2116 else if (!strcmp(argv[aindex], b7option))
2117 load = &beta7_version;
2118 else if (!strcmp(argv[aindex], ovoption))
2120 else if (!strcmp(argv[aindex], verboseoption))
2122 else if (!strcmp(argv[aindex], updateoption))
2124 else if (!strcmp(argv[aindex], hashoption))
2126 db5util_db_args_size++;
2128 char **temp = realloc( db5util_db_args, sizeof(char*) * (db5util_db_args_size+1)); /* one for NULL */
2131 com_err(progname, ENOMEM, "while parsing command arguments\n");
2135 db5util_db_args = temp;
2137 db5util_db_args[db5util_db_args_size-1] = "hash=true";
2138 db5util_db_args[db5util_db_args_size] = NULL;
2143 if ((argc - aindex) != 1) {
2147 dumpfile = argv[aindex];
2149 if (!(dbname_tmp = (char *) malloc(strlen(dbname)+
2150 strlen(dump_tmptrail)+1))) {
2151 fprintf(stderr, no_name_mem_fmt, argv[0]);
2155 strcpy(dbname_tmp, dbname);
2156 strcat(dbname_tmp, dump_tmptrail);
2159 * Initialize the Kerberos context and error tables.
2161 if ((kret = krb5_init_context(&kcontext))) {
2162 fprintf(stderr, ctx_err_fmt, programname);
2168 if( (kret = krb5_set_default_realm(kcontext, util_context->default_realm)) )
2170 fprintf(stderr, "%s: Unable to set the default realm\n", programname);
2180 if ((f = fopen(dumpfile, "r+")) == NULL) {
2181 fprintf(stderr, dfile_err_fmt, programname, dumpfile,
2182 error_message(errno));
2186 if ((kret = krb5_lock_file(kcontext, fileno(f),
2187 KRB5_LOCKMODE_SHARED))) {
2188 fprintf(stderr, "%s: Cannot lock %s: %s\n", programname,
2189 dumpfile, error_message(errno));
2197 * Auto-detect dump version if we weren't told, verify if we
2200 fgets(buf, sizeof(buf), f);
2202 /* only check what we know; some headers only contain a prefix */
2203 if (strncmp(buf, load->header, strlen(load->header)) != 0) {
2204 fprintf(stderr, head_bad_fmt, programname, dumpfile);
2206 if (dumpfile) fclose(f);
2210 /* perhaps this should be in an array, but so what? */
2211 if (strcmp(buf, old_version.header) == 0)
2212 load = &old_version;
2213 else if (strcmp(buf, beta6_version.header) == 0)
2214 load = &beta6_version;
2215 else if (strcmp(buf, beta7_version.header) == 0)
2216 load = &beta7_version;
2217 else if (strcmp(buf, r1_3_version.header) == 0)
2218 load = &r1_3_version;
2219 else if (strncmp(buf, ov_version.header,
2220 strlen(ov_version.header)) == 0)
2223 fprintf(stderr, head_bad_fmt, programname, dumpfile);
2225 if (dumpfile) fclose(f);
2229 if (load->updateonly && !update) {
2230 fprintf(stderr, "%s: dump version %s can only be loaded with the "
2231 "-update flag\n", programname, load->name);
2237 * Cons up params for the new databases. If we are not in update
2238 * mode, we dont create tmp file and then move it to final place. As it is dependent on DB type, this is not done
2240 newparams = global_params;
2242 newparams.mask |= KADM5_CONFIG_DBNAME;
2243 newparams.dbname = dbname_tmp;
2245 if ((kret = kadm5_get_config_params(kcontext, NULL, NULL,
2246 &newparams, &newparams))) {
2247 com_err(argv[0], kret,
2248 "while retreiving new configuration parameters");
2255 * If not an update restoration, create the database. otherwise open
2258 if((kret = krb5_db_create(kcontext, db5util_db_args))) {
2259 fprintf(stderr, dbcreaterr_fmt,
2260 programname, dbname, error_message(kret));
2262 kadm5_free_config_params(kcontext, &newparams);
2263 if (dumpfile) fclose(f);
2269 * Initialize the database.
2271 if ((kret = krb5_db_open(kcontext, db5util_db_args, KRB5_KDB_OPEN_RW))) {
2272 fprintf(stderr, dbinit_err_fmt,
2273 programname, error_message(kret));
2280 * If an update restoration, make sure the db is left unusable if
2283 if ((kret = krb5_db_lock(kcontext, update?KRB5_DB_LOCKMODE_PERMANENT: KRB5_DB_LOCKMODE_EXCLUSIVE))) {
2284 fprintf(stderr, "%s: %s while permanently locking database\n",
2285 programname, error_message(kret));
2290 if (restore_dump(programname, kcontext, (dumpfile) ? dumpfile : stdin_name,
2291 f, verbose, load)) {
2292 fprintf(stderr, restfail_fmt,
2293 programname, load->name);
2297 if (!update && load->create_kadm5 &&
2298 ((kret = kadm5_create_magic_princs(&newparams, kcontext)))) {
2299 /* error message printed by create_magic_princs */
2303 if ((kret = krb5_db_unlock(kcontext))) {
2304 /* change this error? */
2305 fprintf(stderr, dbunlockerr_fmt,
2306 programname, dbname, error_message(kret));
2310 if ((kret = krb5_db_fini(kcontext))) {
2311 fprintf(stderr, close_err_fmt,
2312 programname, error_message(kret));
2316 /* close policy db below */
2320 * If not an update: if there was an error, destroy the temp database,
2321 * otherwise rename it into place.
2323 * If an update: if there was no error, unlock the database.
2327 if ((kret = krb5_db_destroy(kcontext, db5util_db_args))) {
2328 fprintf(stderr, dbdelerr_fmt,
2329 programname, dbname, error_message(kret));
2336 (void) krb5_lock_file(kcontext, fileno(f), KRB5_LOCKMODE_UNLOCK);
2342 krb5_free_context(kcontext);