2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
7 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
9 * Openvision retains the copyright to derivative works of
10 * this source code. Do *NOT* create a derivative of this
11 * source code before consulting with your legal department.
12 * Do *NOT* integrate *ANY* of this source code into another
13 * product before consulting with your legal department.
15 * For further information, read the top-level Openvision
16 * copyright which is contained in the top-level MIT Kerberos
19 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
27 * Copyright 1990,1991 by the Massachusetts Institute of Technology.
28 * All Rights Reserved.
30 * Export of this software from the United States of America may
31 * require a specific license from the United States Government.
32 * It is the responsibility of any person or organization contemplating
33 * export to obtain such a license before exporting.
35 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
36 * distribute this software and its documentation for any purpose and
37 * without fee is hereby granted, provided that the above copyright
38 * notice appear in all copies and that both that copyright notice and
39 * this permission notice appear in supporting documentation, and that
40 * the name of M.I.T. not be used in advertising or publicity pertaining
41 * to distribution of the software without specific, written prior
42 * permission. Furthermore if you modify this software you must label
43 * your software as modified software and not distribute it in such a
44 * fashion that it might be confused with the original M.I.T. software.
45 * M.I.T. makes no representations about the suitability of
46 * this software for any purpose. It is provided "as is" without express
47 * or implied warranty.
55 #include <kadm5/admin.h>
56 #include <kadm5/server_internal.h>
60 #include "kdb5_util.h"
61 #if defined(HAVE_REGEX_H) && defined(HAVE_REGCOMP)
63 #endif /* HAVE_REGEX_H */
66 * Needed for master key conversion.
68 extern krb5_keyblock master_key
;
69 extern krb5_principal master_princ
;
70 static int mkey_convert
;
71 static krb5_keyblock new_master_key
;
77 * Use compile(3) if no regcomp present.
79 #if !defined(HAVE_REGCOMP) && defined(HAVE_REGEXP_H)
80 #define INIT char *sp = instring;
81 #define GETC() (*sp++)
83 #define UNGETC(c) (--sp)
84 #define RETURN(c) return(c)
86 #define RE_BUF_SIZE 1024
88 #endif /* !HAVE_REGCOMP && HAVE_REGEXP_H */
93 krb5_context kcontext
;
99 static krb5_error_code
dump_k5beta_iterator (krb5_pointer
,
101 static krb5_error_code
dump_k5beta6_iterator (krb5_pointer
,
103 static krb5_error_code
dump_k5beta6_iterator_ext (krb5_pointer
,
106 static krb5_error_code
dump_iprop_iterator (krb5_pointer
,
108 static krb5_error_code
dump_k5beta7_princ (krb5_pointer
,
110 static krb5_error_code
dump_k5beta7_princ_ext (krb5_pointer
,
113 static krb5_error_code dump_k5beta7_princ_withpolicy
114 (krb5_pointer
, krb5_db_entry
*);
115 static krb5_error_code
dump_iprop_princ (krb5_pointer
,
117 static krb5_error_code
dump_ov_princ (krb5_pointer
,
119 static void dump_k5beta7_policy (void *, osa_policy_ent_t
);
121 typedef krb5_error_code (*dump_func
)(krb5_pointer
,
124 static int process_k5beta_record (char *, krb5_context
,
126 static int process_k5beta6_record (char *, krb5_context
,
128 static int process_k5beta7_record (char *, krb5_context
,
130 static int process_ov_record (char *, krb5_context
,
132 typedef krb5_error_code (*load_func
)(char *, krb5_context
,
135 typedef struct _dump_version
{
140 dump_func dump_princ
;
141 osa_adb_iter_policy_func dump_policy
;
142 load_func load_record
;
145 dump_version old_version
= {
146 "Kerberos version 5 old format",
147 "kdb5_edit load_dump version 2.0\n",
150 dump_k5beta_iterator
,
152 process_k5beta_record
154 dump_version beta6_version
= {
155 "Kerberos version 5 beta 6 format",
156 "kdb5_edit load_dump version 3.0\n",
159 dump_k5beta6_iterator
,
161 process_k5beta6_record
163 dump_version beta7_version
= {
164 "Kerberos version 5",
165 "kdb5_util load_dump version 4\n",
170 process_k5beta7_record
172 dump_version iprop_version
= {
173 "Kerberos iprop version",
179 process_k5beta7_record
181 dump_version ov_version
= {
183 "OpenV*Secure V1.0\t",
191 dump_version r1_3_version
= {
192 "Kerberos version 5 release 1.3",
193 "kdb5_util load_dump version 5\n",
196 dump_k5beta7_princ_withpolicy
,
198 process_k5beta7_record
,
202 extern char *current_dbname
;
203 extern krb5_boolean dbactive
;
204 extern int exit_status
;
205 extern krb5_context util_context
;
206 extern kadm5_config_params global_params
;
210 #define k5beta_dump_header "kdb5_edit load_dump version 2.0\n"
212 static const char null_mprinc_name
[] = "kdb5_dump@MISSING";
215 * We define gettext(s) to be s here, so that xgettext will extract the
216 * strings to the .po file. At the end of the message section we will
217 * undef gettext so that we can use it as a funtion.
222 /* Message strings */
223 static const char regex_err
[] =
224 gettext("%s: regular expression error - %s\n");
225 static const char regex_merr
[] =
226 gettext("%s: regular expression match error - %s\n");
227 static const char pname_unp_err
[] =
228 gettext("%s: cannot unparse principal name (%s)\n");
229 static const char mname_unp_err
[] =
230 gettext("%s: cannot unparse modifier name (%s)\n");
231 static const char nokeys_err
[] =
232 gettext("%s: cannot find any standard key for %s\n");
233 static const char sdump_tl_inc_err
[] =
234 gettext("%s: tagged data list inconsistency for %s "
235 "(counted %d, stored %d)\n");
236 static const char stand_fmt_name
[] =
237 gettext("Kerberos version 5");
238 static const char old_fmt_name
[] =
239 gettext("Kerberos version 5 old format");
240 static const char b6_fmt_name
[] =
241 gettext("Kerberos version 5 beta 6 format");
242 static const char ofopen_error
[] =
243 gettext("%s: cannot open %s for writing (%s)\n");
244 static const char oflock_error
[] =
245 gettext("%s: cannot lock %s (%s)\n");
246 static const char dumprec_err
[] =
247 gettext("%s: error performing %s dump (%s)\n");
248 static const char dumphdr_err
[] =
249 gettext("%s: error dumping %s header (%s)\n");
250 static const char trash_end_fmt
[] =
251 gettext("%s(%d): ignoring trash at end of line: ");
252 static const char read_name_string
[] =
253 gettext("name string");
254 static const char read_key_type
[] =
256 static const char read_key_data
[] =
258 static const char read_pr_data1
[] =
259 gettext("first set of principal attributes");
260 static const char read_mod_name
[] =
261 gettext("modifier name");
262 static const char read_pr_data2
[] =
263 gettext("second set of principal attributes");
264 static const char read_salt_data
[] =
265 gettext("salt data");
266 static const char read_akey_type
[] =
267 gettext("alternate key type");
268 static const char read_akey_data
[] =
269 gettext("alternate key data");
270 static const char read_asalt_type
[] =
271 gettext("alternate salt type");
272 static const char read_asalt_data
[] =
273 gettext("alternate salt data");
274 static const char read_exp_data
[] =
275 gettext("expansion data");
276 static const char store_err_fmt
[] =
277 gettext("%s(%d): cannot store %s(%s)\n");
278 static const char add_princ_fmt
[] =
280 static const char parse_err_fmt
[] =
281 gettext("%s(%d): cannot parse %s (%s)\n");
282 static const char read_err_fmt
[] =
283 gettext("%s(%d): cannot read %s\n");
284 static const char no_mem_fmt
[] =
285 gettext("%s(%d): no memory for buffers\n");
286 static const char rhead_err_fmt
[] =
287 gettext("%s(%d): cannot match size tokens\n");
288 static const char err_line_fmt
[] =
289 gettext("%s: error processing line %d of %s\n");
290 static const char head_bad_fmt
[] =
291 gettext("%s: dump header bad in %s\n");
292 static const char read_bytecnt
[] =
293 gettext("record byte count");
294 static const char read_encdata
[] =
295 gettext("encoded data");
296 static const char n_name_unp_fmt
[] =
297 gettext("%s(%s): cannot unparse name\n");
298 static const char n_dec_cont_fmt
[] =
299 gettext("%s(%s): cannot decode contents\n");
300 static const char read_nint_data
[] =
301 gettext("principal static attributes");
302 static const char read_tcontents
[] =
303 gettext("tagged data contents");
304 static const char read_ttypelen
[] =
305 gettext("tagged data type and length");
306 static const char read_kcontents
[] =
307 gettext("key data contents");
308 static const char read_ktypelen
[] =
309 gettext("key data type and length");
310 static const char read_econtents
[] =
311 gettext("extra data contents");
312 static const char k5beta_fmt_name
[] =
313 gettext("Kerberos version 5 old format");
314 static const char standard_fmt_name
[] =
315 gettext("Kerberos version 5 format");
316 static const char no_name_mem_fmt
[] =
317 gettext("%s: cannot get memory for temporary name\n");
318 static const char ctx_err_fmt
[] =
319 gettext("%s: cannot initialize Kerberos context\n");
320 static const char stdin_name
[] =
321 gettext("standard input");
322 static const char remaster_err_fmt
[] =
323 gettext("while re-encoding keys for principal %s with new master key");
324 static const char restfail_fmt
[] =
325 gettext("%s: %s restore failed\n");
326 static const char close_err_fmt
[] =
327 gettext("%s: cannot close database (%s)\n");
328 static const char dbinit_err_fmt
[] =
329 gettext("%s: cannot initialize database (%s)\n");
330 static const char dblock_err_fmt
[] =
331 gettext("%s: cannot initialize database lock (%s)\n");
332 static const char dbname_err_fmt
[] =
333 gettext("%s: cannot set database name to %s (%s)\n");
334 static const char dbdelerr_fmt
[] =
335 gettext("%s: cannot delete bad database %s (%s)\n");
336 static const char dbunlockerr_fmt
[] =
337 gettext("%s: cannot unlock database %s (%s)\n");
338 static const char dbrenerr_fmt
[] =
339 gettext("%s: cannot rename database %s to %s (%s)\n");
340 static const char dbcreaterr_fmt
[] =
341 gettext("%s: cannot create database %s (%s)\n");
342 static const char dfile_err_fmt
[] =
343 gettext("%s: cannot open %s (%s)\n");
346 * We now return you to your regularly scheduled program.
350 static const char oldoption
[] = "-old";
351 static const char b6option
[] = "-b6";
352 static const char b7option
[] = "-b7";
353 static const char ipropoption
[] = "-i";
354 static const char verboseoption
[] = "-verbose";
355 static const char updateoption
[] = "-update";
356 static const char hashoption
[] = "-hash";
357 static const char ovoption
[] = "-ov";
358 static const char dump_tmptrail
[] = "~";
361 * Re-encrypt the key_data with the new master key...
363 static krb5_error_code
master_key_convert(context
, db_entry
)
364 krb5_context context
;
365 krb5_db_entry
* db_entry
;
367 krb5_error_code retval
;
368 krb5_keyblock v5plainkey
, *key_ptr
;
369 krb5_keysalt keysalt
;
371 krb5_key_data new_key_data
, *key_data
;
372 krb5_boolean is_mkey
;
374 is_mkey
= krb5_principal_compare(context
, master_princ
, db_entry
->princ
);
376 if (is_mkey
&& db_entry
->n_key_data
!= 1)
379 "Master key db entry has %d keys, expecting only 1!\n"),
380 db_entry
->n_key_data
);
381 for (i
=0; i
< db_entry
->n_key_data
; i
++) {
382 key_data
= &db_entry
->key_data
[i
];
383 if (key_data
->key_data_length
== 0)
385 retval
= krb5_dbekd_decrypt_key_data(context
, &master_key
,
386 key_data
, &v5plainkey
,
391 memset(&new_key_data
, 0, sizeof(new_key_data
));
392 key_ptr
= is_mkey
? &new_master_key
: &v5plainkey
;
393 retval
= krb5_dbekd_encrypt_key_data(context
, &new_master_key
,
395 key_data
->key_data_kvno
,
399 krb5_free_keyblock_contents(context
, &v5plainkey
);
400 for (j
= 0; j
< key_data
->key_data_ver
; j
++) {
401 if (key_data
->key_data_length
[j
]) {
402 free(key_data
->key_data_contents
[j
]);
405 *key_data
= new_key_data
;
411 * Update the "ok" file.
413 void update_ok_file (file_name
)
416 /* handle slave locking/failure stuff */
419 static char ok
[]=".dump_ok";
421 if ((file_ok
= (char *)malloc(strlen(file_name
) + strlen(ok
) + 1))
423 com_err(progname
, ENOMEM
,
424 gettext("while allocating filename "
425 "for update_ok_file"));
429 strcpy(file_ok
, file_name
);
431 if ((fd
= open(file_ok
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0600)) < 0) {
432 com_err(progname
, errno
,
433 gettext("while creating 'ok' file, '%s'"),
439 if (write(fd
, "", 1) != 1) {
440 com_err(progname
, errno
,
441 gettext("while writing to 'ok' file, '%s'"),
454 * name_matches() - See if a principal name matches a regular expression
458 name_matches(name
, arglist
)
460 struct dump_args
*arglist
;
464 regmatch_t match_match
;
466 char match_errmsg
[BUFSIZ
];
469 char regexp_buffer
[RE_BUF_SIZE
];
471 extern char *re_comp();
473 #endif /* HAVE_RE_COMP */
477 * Plow, brute force, through the list of names/regular expressions.
479 match
= (arglist
->nnames
) ? 0 : 1;
480 for (i
=0; i
<arglist
->nnames
; i
++) {
483 * Compile the regular expression.
485 match_error
= regcomp(&match_exp
, arglist
->names
[i
], REG_EXTENDED
);
487 errmsg_size
= regerror(match_error
,
490 sizeof(match_errmsg
));
491 fprintf(stderr
, gettext(regex_err
),
492 arglist
->programname
, match_errmsg
);
496 * See if we have a match.
498 match_error
= regexec(&match_exp
, name
, 1, &match_match
, 0);
500 if (match_error
!= REG_NOMATCH
) {
501 errmsg_size
= regerror(match_error
,
504 sizeof(match_errmsg
));
505 fprintf(stderr
, gettext(regex_merr
),
506 arglist
->programname
, match_errmsg
);
512 * We have a match. See if it matches the whole
515 if ((match_match
.rm_so
== 0) &&
516 (match_match
.rm_eo
== strlen(name
)))
522 * Compile the regular expression.
524 compile(arglist
->names
[i
],
526 ®exp_buffer
[RE_BUF_SIZE
],
528 if (step(name
, regexp_buffer
)) {
529 if ((loc1
== name
) &&
530 (loc2
== &name
[strlen(name
)]))
535 * Compile the regular expression.
537 if (re_result
= re_comp(arglist
->names
[i
])) {
538 fprintf(stderr
, gettext(regex_err
), arglist
->programname
, re_result
);
543 #else /* HAVE_RE_COMP */
545 * If no regular expression support, then just compare the strings.
547 if (!strcmp(arglist
->names
[i
], name
))
549 #endif /* HAVE_REGCOMP */
556 static krb5_error_code
557 find_enctype(dbentp
, enctype
, salttype
, kentp
)
558 krb5_db_entry
*dbentp
;
559 krb5_enctype enctype
;
561 krb5_key_data
**kentp
;
565 krb5_key_data
*datap
;
568 datap
= (krb5_key_data
*) NULL
;
569 for (i
=0; i
<dbentp
->n_key_data
; i
++) {
570 if (( (krb5_enctype
)dbentp
->key_data
[i
].key_data_type
[0] == enctype
) &&
571 ((dbentp
->key_data
[i
].key_data_type
[1] == salttype
) ||
573 maxkvno
= dbentp
->key_data
[i
].key_data_kvno
;
574 datap
= &dbentp
->key_data
[i
];
586 * dump_k5beta_header() - Make a dump header that is recognizable by Kerberos
587 * Version 5 Beta 5 and previous releases.
589 static krb5_error_code
590 dump_k5beta_header(arglist
)
591 struct dump_args
*arglist
;
593 /* The old header consists of the leading string */
594 fprintf(arglist
->ofile
, k5beta_dump_header
);
600 * dump_k5beta_iterator() - Dump an entry in a format that is usable
601 * by Kerberos Version 5 Beta 5 and previous
604 static krb5_error_code
605 dump_k5beta_iterator(ptr
, entry
)
607 krb5_db_entry
*entry
;
609 krb5_error_code retval
;
610 struct dump_args
*arg
;
611 char *name
, *mod_name
;
612 krb5_principal mod_princ
;
613 krb5_key_data
*pkey
, *akey
, nullkey
;
614 krb5_timestamp mod_date
, last_pwd_change
;
618 arg
= (struct dump_args
*) ptr
;
619 name
= (char *) NULL
;
620 mod_name
= (char *) NULL
;
621 memset(&nullkey
, 0, sizeof(nullkey
));
624 * Flatten the principal name.
626 if ((retval
= krb5_unparse_name(arg
->kcontext
,
629 fprintf(stderr
, gettext(pname_unp_err
),
630 arg
->programname
, error_message(retval
));
635 * Re-encode the keys in the new master key, if necessary.
638 retval
= master_key_convert(arg
->kcontext
, entry
);
640 com_err(arg
->programname
, retval
, remaster_err_fmt
, name
);
646 * If we don't have any match strings, or if our name matches, then
647 * proceed with the dump, otherwise, just forget about it.
649 if (!arg
->nnames
|| name_matches(name
, arg
)) {
651 * Deserialize the modifier record.
653 mod_name
= (char *) NULL
;
655 last_pwd_change
= mod_date
= 0;
656 pkey
= akey
= (krb5_key_data
*) NULL
;
657 if (!(retval
= krb5_dbe_lookup_mod_princ_data(arg
->kcontext
,
663 * Flatten the modifier name.
665 if ((retval
= krb5_unparse_name(arg
->kcontext
,
668 fprintf(stderr
, gettext(mname_unp_err
),
670 error_message(retval
));
671 krb5_free_principal(arg
->kcontext
, mod_princ
);
675 mod_name
= strdup(null_mprinc_name
);
678 * Find the last password change record and set it straight.
681 krb5_dbe_lookup_last_pwd_change(arg
->kcontext
, entry
,
682 &last_pwd_change
))) {
683 fprintf(stderr
, gettext(nokeys_err
),
684 arg
->programname
, name
);
685 krb5_xfree(mod_name
);
691 * Find the 'primary' key and the 'alternate' key.
693 if ((retval
= find_enctype(entry
,
695 KRB5_KDB_SALTTYPE_NORMAL
,
697 (retval
= find_enctype(entry
,
699 KRB5_KDB_SALTTYPE_V4
,
701 fprintf(stderr
, gettext(nokeys_err
),
702 arg
->programname
, name
);
703 krb5_xfree(mod_name
);
708 /* If we only have one type, then ship it out as the primary. */
719 * First put out strings representing the length of the variable
720 * length data in this record, then the name and the primary key type.
722 fprintf(arg
->ofile
, "%d\t%d\t%d\t%d\t%d\t%d\t%s\t%d\t", strlen(name
),
724 (krb5_int32
) pkey
->key_data_length
[0],
725 (krb5_int32
) akey
->key_data_length
[0],
726 (krb5_int32
) pkey
->key_data_length
[1],
727 (krb5_int32
) akey
->key_data_length
[1],
729 (krb5_int32
) pkey
->key_data_type
[0]);
730 for (i
=0; i
<pkey
->key_data_length
[0]; i
++) {
731 fprintf(arg
->ofile
, "%02x", pkey
->key_data_contents
[0][i
]);
734 * Second, print out strings representing the standard integer
735 * data in this record.
738 "\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",
739 (krb5_int32
) pkey
->key_data_kvno
,
740 entry
->max_life
, entry
->max_renewable_life
,
741 1 /* Fake mkvno */, entry
->expiration
, entry
->pw_expiration
,
742 last_pwd_change
, entry
->last_success
, entry
->last_failed
,
743 entry
->fail_auth_count
, mod_name
, mod_date
,
744 entry
->attributes
, pkey
->key_data_type
[1]);
746 /* Pound out the salt data, if present. */
747 for (i
=0; i
<pkey
->key_data_length
[1]; i
++) {
748 fprintf(arg
->ofile
, "%02x", pkey
->key_data_contents
[1][i
]);
750 /* Pound out the alternate key type and contents */
751 fprintf(arg
->ofile
, "\t%u\t", akey
->key_data_type
[0]);
752 for (i
=0; i
<akey
->key_data_length
[0]; i
++) {
753 fprintf(arg
->ofile
, "%02x", akey
->key_data_contents
[0][i
]);
755 /* Pound out the alternate salt type and contents */
756 fprintf(arg
->ofile
, "\t%u\t", akey
->key_data_type
[1]);
757 for (i
=0; i
<akey
->key_data_length
[1]; i
++) {
758 fprintf(arg
->ofile
, "%02x", akey
->key_data_contents
[1][i
]);
760 /* Pound out the expansion data. (is null) */
761 for (i
=0; i
< 8; i
++) {
762 fprintf(arg
->ofile
, "\t%u", 0);
764 fprintf(arg
->ofile
, ";\n");
765 /* If we're blabbing, do it */
767 fprintf(stderr
, "%s\n", name
);
768 krb5_xfree(mod_name
);
775 * dump_k5beta6_iterator() - Output a dump record in krb5b6 format.
777 static krb5_error_code
778 dump_k5beta6_iterator(ptr
, entry
)
780 krb5_db_entry
*entry
;
782 return dump_k5beta6_iterator_ext(ptr
, entry
, 0);
785 static krb5_error_code
786 dump_k5beta6_iterator_ext(ptr
, entry
, kadm
)
788 krb5_db_entry
*entry
;
791 krb5_error_code retval
;
792 struct dump_args
*arg
;
795 krb5_key_data
*kdata
;
796 int counter
, skip
, i
, j
;
799 arg
= (struct dump_args
*) ptr
;
800 name
= (char *) NULL
;
803 * Flatten the principal name.
805 if ((retval
= krb5_unparse_name(arg
->kcontext
,
808 fprintf(stderr
, gettext(pname_unp_err
),
809 arg
->programname
, error_message(retval
));
814 * Re-encode the keys in the new master key, if necessary.
817 retval
= master_key_convert(arg
->kcontext
, entry
);
819 com_err(arg
->programname
, retval
, remaster_err_fmt
, name
);
825 * If we don't have any match strings, or if our name matches, then
826 * proceed with the dump, otherwise, just forget about it.
828 if (!arg
->nnames
|| name_matches(name
, arg
)) {
830 * We'd like to just blast out the contents as they would appear in
831 * the database so that we can just suck it back in, but it doesn't
832 * lend itself to easy editing.
836 * The dump format is as follows:
837 * len strlen(name) n_tl_data n_key_data e_length
839 * attributes max_life max_renewable_life expiration
840 * pw_expiration last_success last_failed fail_auth_count
841 * n_tl_data*[type length <contents>]
842 * n_key_data*[ver kvno ver*(type length <contents>)]
844 * Fields which are not encapsulated by angle-brackets are to appear
845 * verbatim. A bracketed field's absence is indicated by a -1 in its
850 * Make sure that the tagged list is reasonably correct.
853 for (tlp
= entry
->tl_data
; tlp
; tlp
= tlp
->tl_data_next
) {
855 * don't dump tl data types we know aren't understood by
856 * earlier revisions [krb5-admin/89]
858 switch (tlp
->tl_data_type
) {
859 case KRB5_TL_KADM_DATA
:
871 if (counter
+ skip
== entry
->n_tl_data
) {
872 /* Pound out header */
873 fprintf(arg
->ofile
, "%d\t%d\t%d\t%d\t%d\t%s\t",
877 (int) entry
->n_key_data
,
878 (int) entry
->e_length
,
880 fprintf(arg
->ofile
, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t",
883 entry
->max_renewable_life
,
885 entry
->pw_expiration
,
888 entry
->fail_auth_count
);
889 /* Pound out tagged data. */
890 for (tlp
= entry
->tl_data
; tlp
; tlp
= tlp
->tl_data_next
) {
891 if (tlp
->tl_data_type
== KRB5_TL_KADM_DATA
&& !kadm
)
892 continue; /* see above, [krb5-admin/89] */
894 fprintf(arg
->ofile
, "%d\t%d\t",
895 (int) tlp
->tl_data_type
,
896 (int) tlp
->tl_data_length
);
897 if (tlp
->tl_data_length
)
898 for (i
=0; i
<tlp
->tl_data_length
; i
++)
899 fprintf(arg
->ofile
, "%02x", tlp
->tl_data_contents
[i
]);
901 fprintf(arg
->ofile
, "%d", -1);
902 fprintf(arg
->ofile
, "\t");
905 /* Pound out key data */
906 for (counter
=0; counter
<entry
->n_key_data
; counter
++) {
907 kdata
= &entry
->key_data
[counter
];
908 fprintf(arg
->ofile
, "%d\t%d\t",
909 (int) kdata
->key_data_ver
,
910 (int) kdata
->key_data_kvno
);
911 for (i
=0; i
<kdata
->key_data_ver
; i
++) {
912 fprintf(arg
->ofile
, "%d\t%d\t",
913 kdata
->key_data_type
[i
],
914 kdata
->key_data_length
[i
]);
915 if (kdata
->key_data_length
[i
])
916 for (j
=0; j
<kdata
->key_data_length
[i
]; j
++)
917 fprintf(arg
->ofile
, "%02x",
918 kdata
->key_data_contents
[i
][j
]);
920 fprintf(arg
->ofile
, "%d", -1);
921 fprintf(arg
->ofile
, "\t");
925 /* Pound out extra data */
927 for (i
=0; i
<entry
->e_length
; i
++)
928 fprintf(arg
->ofile
, "%02x", entry
->e_data
[i
]);
930 fprintf(arg
->ofile
, "%d", -1);
933 fprintf(arg
->ofile
, ";\n");
936 fprintf(stderr
, "%s\n", name
);
939 fprintf(stderr
, gettext(sdump_tl_inc_err
),
940 arg
->programname
, name
, counter
+skip
,
941 (int) entry
->n_tl_data
);
950 * dump_iprop_iterator() - Output a dump record in iprop format.
952 static krb5_error_code
953 dump_iprop_iterator(ptr
, entry
)
955 krb5_db_entry
*entry
;
957 krb5_error_code retval
;
958 struct dump_args
*arg
;
961 krb5_key_data
*kdata
;
965 arg
= (struct dump_args
*) ptr
;
966 name
= (char *) NULL
;
969 * Flatten the principal name.
971 if ((retval
= krb5_unparse_name(arg
->kcontext
,
974 fprintf(stderr
, gettext(pname_unp_err
),
975 arg
->programname
, error_message(retval
));
980 * Re-encode the keys in the new master key, if necessary.
983 retval
= master_key_convert(arg
->kcontext
, entry
);
985 com_err(arg
->programname
, retval
, remaster_err_fmt
, name
);
991 * If we don't have any match strings, or if our name matches, then
992 * proceed with the dump, otherwise, just forget about it.
994 if (!arg
->nnames
|| name_matches(name
, arg
)) {
996 * We'd like to just blast out the contents as they would
997 * appear in the database so that we can just suck it back
998 * in, but it doesn't lend itself to easy editing.
1002 * The dump format is as follows: len strlen(name)
1003 * n_tl_data n_key_data e_length name attributes max_life
1004 * max_renewable_life expiration pw_expiration last_success
1005 * last_failed fail_auth_count n_tl_data*[type length
1006 * <contents>] n_key_data*[ver kvno ver*(type length
1007 * <contents>)] <e_data> Fields which are not encapsulated
1008 * by angle-brackets are to appear verbatim. Bracketed
1009 * fields absence is indicated by a -1 in its place
1013 * Make sure that the tagged list is reasonably correct.
1016 for (tlp
= entry
->tl_data
; tlp
; tlp
= tlp
->tl_data_next
)
1019 if (counter
== entry
->n_tl_data
) {
1020 /* Pound out header */
1021 fprintf(arg
->ofile
, "%d\t%d\t%d\t%d\t%d\t%s\t",
1024 (int) entry
->n_tl_data
,
1025 (int) entry
->n_key_data
,
1026 (int) entry
->e_length
,
1028 fprintf(arg
->ofile
, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t",
1031 entry
->max_renewable_life
,
1033 entry
->pw_expiration
,
1034 entry
->last_success
,
1036 entry
->fail_auth_count
);
1037 /* Pound out tagged data. */
1038 for (tlp
= entry
->tl_data
; tlp
;
1039 tlp
= tlp
->tl_data_next
) {
1040 fprintf(arg
->ofile
, "%d\t%d\t",
1041 (int) tlp
->tl_data_type
,
1042 (int) tlp
->tl_data_length
);
1043 if (tlp
->tl_data_length
)
1045 i
< tlp
->tl_data_length
;
1047 fprintf(arg
->ofile
, "%02x",
1049 tl_data_contents
[i
]);
1051 fprintf(arg
->ofile
, "%d", -1);
1052 fprintf(arg
->ofile
, "\t");
1055 /* Pound out key data */
1057 counter
< entry
->n_key_data
; counter
++) {
1058 kdata
= &entry
->key_data
[counter
];
1059 fprintf(arg
->ofile
, "%d\t%d\t",
1060 (int) kdata
->key_data_ver
,
1061 (int) kdata
->key_data_kvno
);
1062 for (i
=0; i
<kdata
->key_data_ver
; i
++) {
1063 fprintf(arg
->ofile
, "%d\t%d\t",
1064 kdata
->key_data_type
[i
],
1065 kdata
->key_data_length
[i
]);
1066 if (kdata
->key_data_length
[i
])
1077 fprintf(arg
->ofile
, "%d", -1);
1078 fprintf(arg
->ofile
, "\t");
1082 /* Pound out extra data */
1083 if (entry
->e_length
)
1084 for (i
=0; i
<entry
->e_length
; i
++)
1085 fprintf(arg
->ofile
, "%02x",
1088 fprintf(arg
->ofile
, "%d", -1);
1091 fprintf(arg
->ofile
, ";\n");
1094 fprintf(stderr
, "%s\n", name
);
1096 fprintf(stderr
, gettext(sdump_tl_inc_err
),
1097 arg
->programname
, name
, counter
,
1098 (int) entry
->n_tl_data
);
1107 * dump_k5beta7_iterator() - Output a dump record in krb5b7 format.
1109 static krb5_error_code
1110 dump_k5beta7_princ(ptr
, entry
)
1112 krb5_db_entry
*entry
;
1114 return dump_k5beta7_princ_ext(ptr
, entry
, 0);
1117 static krb5_error_code
1118 dump_k5beta7_princ_ext(ptr
, entry
, kadm
)
1120 krb5_db_entry
*entry
;
1123 krb5_error_code retval
;
1124 struct dump_args
*arg
;
1129 arg
= (struct dump_args
*) ptr
;
1130 name
= (char *) NULL
;
1133 * Flatten the principal name.
1135 if ((retval
= krb5_unparse_name(arg
->kcontext
,
1138 fprintf(stderr
, gettext(pname_unp_err
),
1139 arg
->programname
, error_message(retval
));
1143 * If we don't have any match strings, or if our name matches, then
1144 * proceed with the dump, otherwise, just forget about it.
1146 if (!arg
->nnames
|| name_matches(name
, arg
)) {
1147 fprintf(arg
->ofile
, "princ\t");
1149 /* save the callee from matching the name again */
1150 tmp_nnames
= arg
->nnames
;
1152 retval
= dump_k5beta6_iterator_ext(ptr
, entry
, kadm
);
1153 arg
->nnames
= tmp_nnames
;
1161 * dump_iprop_princ() - Output a dump record in iprop format.
1162 * This was created in order to dump more data, such as kadm5 tl
1164 static krb5_error_code
1165 dump_iprop_princ(ptr
, entry
)
1167 krb5_db_entry
*entry
;
1169 krb5_error_code retval
;
1170 struct dump_args
*arg
;
1175 arg
= (struct dump_args
*) ptr
;
1176 name
= (char *) NULL
;
1179 * Flatten the principal name.
1181 if ((retval
= krb5_unparse_name(arg
->kcontext
,
1184 fprintf(stderr
, gettext(pname_unp_err
),
1185 arg
->programname
, error_message(retval
));
1189 * If we don't have any match strings, or if our name matches, then
1190 * proceed with the dump, otherwise, just forget about it.
1192 if (!arg
->nnames
|| name_matches(name
, arg
)) {
1193 fprintf(arg
->ofile
, "princ\t");
1195 /* save the callee from matching the name again */
1196 tmp_nnames
= arg
->nnames
;
1198 retval
= dump_iprop_iterator(ptr
, entry
);
1199 arg
->nnames
= tmp_nnames
;
1205 static krb5_error_code
1206 dump_k5beta7_princ_withpolicy(ptr
, entry
)
1208 krb5_db_entry
*entry
;
1210 return dump_k5beta7_princ_ext(ptr
, entry
, 1);
1213 void dump_k5beta7_policy(void *data
, osa_policy_ent_t entry
)
1215 struct dump_args
*arg
;
1217 arg
= (struct dump_args
*) data
;
1218 fprintf(arg
->ofile
, "policy\t%s\t%d\t%d\t%d\t%d\t%d\t%d\n", entry
->name
,
1219 entry
->pw_min_life
, entry
->pw_max_life
, entry
->pw_min_length
,
1220 entry
->pw_min_classes
, entry
->pw_history_num
,
1221 entry
->policy_refcnt
);
1224 static void print_key_data(FILE *f
, krb5_key_data
*key_data
)
1228 fprintf(f
, "%d\t%d\t", key_data
->key_data_type
[0],
1229 key_data
->key_data_length
[0]);
1230 for(c
= 0; c
< key_data
->key_data_length
[0]; c
++)
1232 key_data
->key_data_contents
[0][c
]);
1236 * Function: print_princ
1238 * Purpose: output osa_adb_princ_ent data in a human
1239 * readable format (which is a format suitable for
1240 * ovsec_adm_import consumption)
1243 * data (input) pointer to a structure containing a FILE *
1244 * and a record counter.
1245 * entry (input) entry to get dumped.
1246 * <return value> void
1252 * writes data to the specified file pointerp.
1258 static krb5_error_code
dump_ov_princ(krb5_pointer ptr
, krb5_db_entry
*kdb
)
1262 struct dump_args
*arg
;
1263 krb5_tl_data tl_data
;
1264 osa_princ_ent_rec adb
;
1267 arg
= (struct dump_args
*) ptr
;
1269 * XXX Currently, lookup_tl_data always returns zero; it sets
1270 * tl_data->tl_data_length to zero if the type isn't found.
1271 * This should be fixed...
1274 * XXX Should this function do nothing for a principal with no
1275 * admin data, or print a record of "default" values? See
1276 * comment in server_kdb.c to help decide.
1278 tl_data
.tl_data_type
= KRB5_TL_KADM_DATA
;
1279 if (krb5_dbe_lookup_tl_data(arg
->kcontext
, kdb
, &tl_data
)
1280 || (tl_data
.tl_data_length
== 0))
1283 memset(&adb
, 0, sizeof(adb
));
1284 xdrmem_create(&xdrs
, (const caddr_t
) tl_data
.tl_data_contents
,
1285 tl_data
.tl_data_length
, XDR_DECODE
);
1286 if (! xdr_osa_princ_ent_rec(&xdrs
, &adb
)) {
1288 return(KADM5_XDR_FAILURE
);
1292 krb5_unparse_name(arg
->kcontext
, kdb
->princ
, &princstr
);
1293 fprintf(arg
->ofile
, "princ\t%s\t", princstr
);
1294 if(adb
.policy
== NULL
)
1295 fputc('\t', arg
->ofile
);
1297 fprintf(arg
->ofile
, "%s\t", adb
.policy
);
1298 fprintf(arg
->ofile
, "%lx\t%d\t%d\t%d", adb
.aux_attributes
,
1299 adb
.old_key_len
,adb
.old_key_next
, adb
.admin_history_kvno
);
1301 for (x
= 0; x
< adb
.old_key_len
; x
++) {
1303 for (y
= 0; y
< adb
.old_keys
[x
].n_key_data
; y
++) {
1304 krb5_key_data
*key_data
= &adb
.old_keys
[x
].key_data
[y
];
1306 if (key_data
->key_data_type
[0] != ENCTYPE_DES_CBC_CRC
)
1310 gettext("Warning! Multiple DES-CBC-CRC "
1311 "keys for principal %s; skipping "
1318 fputc('\t', arg
->ofile
);
1319 print_key_data(arg
->ofile
, key_data
);
1323 gettext("Warning! No DES-CBC-CRC key "
1324 "for principal %s, cannot generate "
1325 "OV-compatible record; skipping\n"),
1329 fputc('\n', arg
->ofile
);
1336 * dump_db [-i] [-old] [-b6] [-b7] [-ov] [-verbose] [-mkey_convert]
1337 * [-new_mkey_file mkey_file] [-rev] [-recurse]
1338 * [filename [principals...]]
1346 struct dump_args arglist
;
1347 /* Solaris Kerberos */
1352 krb5_error_code kret
, retval
;
1355 krb5_boolean locked
;
1356 char *new_mkey_file
= 0;
1357 bool_t dump_sno
= FALSE
;
1358 kdb_log_context
*log_ctx
;
1359 /* Solaris Kerberos: adding support for -rev/recurse flags */
1360 int db_arg_index
= 0;
1361 char *db_args
[3] = {NULL
, NULL
, NULL
};
1364 * Parse the arguments.
1366 /* Solaris Kerberos */
1368 programname
= argv
[0];
1369 if (strrchr(programname
, (int) '/'))
1370 programname
= strrchr(argv
[0], (int) '/') + 1;
1372 ofile
= (char *) NULL
;
1373 dump
= &r1_3_version
;
1374 arglist
.verbose
= 0;
1379 log_ctx
= util_context
->kdblog_context
;
1382 * Parse the qualifiers.
1384 for (aindex
= 1; aindex
< argc
; aindex
++) {
1385 if (!strcmp(argv
[aindex
], oldoption
))
1386 dump
= &old_version
;
1387 else if (!strcmp(argv
[aindex
], b6option
))
1388 dump
= &beta6_version
;
1389 else if (!strcmp(argv
[aindex
], b7option
))
1390 dump
= &beta7_version
;
1391 else if (!strcmp(argv
[aindex
], ovoption
))
1393 else if (!strcmp(argv
[aindex
], ipropoption
)) {
1394 if (log_ctx
&& log_ctx
->iproprole
) {
1395 dump
= &iprop_version
;
1397 * dump_sno is used to indicate if the serial
1398 * # should be populated in the output
1399 * file to be used later by iprop for updating
1400 * the slave's update log when loading
1404 fprintf(stderr
, gettext("Iprop not enabled\n"));
1409 else if (!strcmp(argv
[aindex
], verboseoption
))
1411 else if (!strcmp(argv
[aindex
], "-mkey_convert"))
1413 else if (!strcmp(argv
[aindex
], "-new_mkey_file")) {
1414 new_mkey_file
= argv
[++aindex
];
1416 } else if (!strcmp(argv
[aindex
], "-rev")) {
1417 /* Solaris Kerberos: adding support for -rev/recurse flags */
1418 /* hack to pass args to db specific plugin */
1419 db_args
[db_arg_index
++] = "rev";
1420 } else if (!strcmp(argv
[aindex
], "-recurse")) {
1421 /* hack to pass args to db specific plugin */
1422 db_args
[db_arg_index
++] = "recurse";
1427 arglist
.names
= (char **) NULL
;
1429 if (aindex
< argc
) {
1430 ofile
= argv
[aindex
];
1432 if (aindex
< argc
) {
1433 arglist
.names
= &argv
[aindex
];
1434 arglist
.nnames
= argc
- aindex
;
1439 * Make sure the database is open. The policy database only has
1440 * to be opened if we try a dump that uses it.
1443 /* Solaris Kerberos */
1444 com_err(progname
, 0, Err_no_database
); /* Solaris Kerberos */
1450 * If we're doing a master key conversion, set up for it.
1453 if (!valid_master_key
) {
1454 /* TRUE here means read the keyboard, but only once */
1455 retval
= krb5_db_fetch_mkey(util_context
,
1457 global_params
.enctype
,
1462 /* Solaris Kerberos */
1463 com_err(progname
, retval
,
1464 gettext("while reading master key"));
1467 retval
= krb5_db_verify_master_key(util_context
,
1471 /* Solaris Kerberos */
1472 com_err(progname
, retval
,
1473 gettext("while verifying master key"));
1478 printf(gettext("Please enter new master key....\n"));
1479 if ((retval
= krb5_db_fetch_mkey(util_context
, master_princ
,
1480 global_params
.enctype
,
1481 (new_mkey_file
== 0) ?
1482 (krb5_boolean
) 1 : 0,
1485 &new_master_key
))) {
1486 /* Solaris Kerberos */
1487 com_err(progname
, retval
,
1488 gettext("while reading new master key"));
1495 if (ofile
&& strcmp(ofile
, "-")) {
1497 * Discourage accidental dumping to filenames beginning with '-'.
1499 if (ofile
[0] == '-')
1502 * Make sure that we don't open and truncate on the fopen,
1503 * since that may hose an on-going kprop process.
1505 * We could also control this by opening for read and
1506 * write, doing an flock with LOCK_EX, and then
1507 * truncating the file once we have gotten the lock,
1508 * but that would involve more OS dependencies than I
1512 if (!(f
= fopen(ofile
, "w"))) {
1513 /* Solaris Kerberos */
1514 fprintf(stderr
, gettext(ofopen_error
),
1515 progname
, ofile
, error_message(errno
));
1519 if ((kret
= krb5_lock_file(util_context
,
1521 KRB5_LOCKMODE_EXCLUSIVE
))) {
1522 /* Solaris Kerberos */
1523 fprintf(stderr
, gettext(oflock_error
),
1524 progname
, ofile
, error_message(kret
));
1533 /* Solaris Kerberos */
1534 arglist
.programname
= progname
;
1536 arglist
.kcontext
= util_context
;
1537 fprintf(arglist
.ofile
, "%s", dump
->header
);
1540 if (ulog_map(util_context
, &global_params
, FKCOMMAND
)) {
1541 /* Solaris Kerberos */
1543 gettext("%s: Could not map log\n"), progname
);
1549 * We grab the lock twice (once again in the iterator call),
1550 * but that's ok since the lock func handles incr locks held.
1552 if (krb5_db_lock(util_context
, KRB5_LOCKMODE_SHARED
)) {
1553 /* Solaris Kerberos */
1555 gettext("%s: Couldn't grab lock\n"), progname
);
1560 fprintf(f
, " %u", log_ctx
->ulog
->kdb_last_sno
);
1561 fprintf(f
, " %u", log_ctx
->ulog
->kdb_last_time
.seconds
);
1562 fprintf(f
, " %u", log_ctx
->ulog
->kdb_last_time
.useconds
);
1565 if (dump
->header
[strlen(dump
->header
)-1] != '\n')
1566 fputc('\n', arglist
.ofile
);
1568 /* Solaris Kerberos: adding support for -rev/recurse flags */
1569 /* don't pass in db_args if there aren't any */
1570 if ((kret
= krb5_db_iterate(util_context
,
1573 (krb5_pointer
) &arglist
,
1574 db_arg_index
> 0 ? (char **)&db_args
: NULL
))) {
1575 /* Solaris Kerberos */
1576 fprintf(stderr
, dumprec_err
,
1577 progname
, dump
->name
, error_message(kret
));
1580 (void) krb5_db_unlock(util_context
);
1582 if (dump
->dump_policy
&&
1583 (kret
= krb5_db_iter_policy( util_context
, "*", dump
->dump_policy
,
1585 /* Solaris Kerberos */
1586 fprintf(stderr
, gettext(dumprec_err
),
1587 progname
, dump
->name
,
1588 error_message(kret
));
1593 if (ofile
&& f
!= stdout
&& !exit_status
) {
1595 (void) krb5_lock_file(util_context
, fileno(f
), KRB5_LOCKMODE_UNLOCK
);
1599 update_ok_file(ofile
);
1603 (void) krb5_lock_file(util_context
, fileno(f
), KRB5_LOCKMODE_UNLOCK
);
1607 * Read a string of bytes while counting the number of lines passed.
1610 read_string(f
, buf
, len
, lp
)
1620 for (i
=0; i
<len
; i
++) {
1635 * Read a string of two character representations of bytes.
1638 read_octet_string(f
, buf
, len
)
1647 for (i
=0; i
<len
; i
++) {
1648 if (fscanf(f
, "%02x", &c
) != 1) {
1652 buf
[i
] = (krb5_octet
) c
;
1658 * Find the end of an old format record.
1661 find_record_end(f
, fn
, lineno
)
1668 if (((ch
= fgetc(f
)) != ';') || ((ch
= fgetc(f
)) != '\n')) {
1669 fprintf(stderr
, gettext(trash_end_fmt
), fn
, lineno
);
1670 while (ch
!= '\n') {
1680 * update_tl_data() - Generate the tl_data entries.
1682 static krb5_error_code
1683 update_tl_data(kcontext
, dbentp
, mod_name
, mod_date
, last_pwd_change
)
1684 krb5_context kcontext
;
1685 krb5_db_entry
*dbentp
;
1686 krb5_principal mod_name
;
1687 krb5_timestamp mod_date
;
1688 krb5_timestamp last_pwd_change
;
1690 krb5_error_code kret
;
1695 * Handle modification principal.
1698 krb5_tl_mod_princ mprinc
;
1700 memset(&mprinc
, 0, sizeof(mprinc
));
1701 if (!(kret
= krb5_copy_principal(kcontext
,
1703 &mprinc
.mod_princ
))) {
1704 mprinc
.mod_date
= mod_date
;
1705 kret
= krb5_dbe_encode_mod_princ_data(kcontext
,
1709 if (mprinc
.mod_princ
)
1710 krb5_free_principal(kcontext
, mprinc
.mod_princ
);
1714 * Handle last password change.
1717 krb5_tl_data
*pwchg
;
1718 krb5_boolean linked
;
1720 /* Find a previously existing entry */
1721 for (pwchg
= dbentp
->tl_data
;
1722 (pwchg
) && (pwchg
->tl_data_type
!= KRB5_TL_LAST_PWD_CHANGE
);
1723 pwchg
= pwchg
->tl_data_next
);
1725 /* Check to see if we found one. */
1728 /* No, allocate a new one */
1729 if ((pwchg
= (krb5_tl_data
*) malloc(sizeof(krb5_tl_data
)))) {
1730 memset(pwchg
, 0, sizeof(krb5_tl_data
));
1731 if (!(pwchg
->tl_data_contents
=
1732 (krb5_octet
*) malloc(sizeof(krb5_timestamp
)))) {
1734 pwchg
= (krb5_tl_data
*) NULL
;
1737 pwchg
->tl_data_type
= KRB5_TL_LAST_PWD_CHANGE
;
1738 pwchg
->tl_data_length
=
1739 (krb5_int16
) sizeof(krb5_timestamp
);
1746 /* Do we have an entry? */
1747 if (pwchg
&& pwchg
->tl_data_contents
) {
1749 krb5_kdb_encode_int32(last_pwd_change
, pwchg
->tl_data_contents
);
1750 /* Link it in if necessary */
1752 pwchg
->tl_data_next
= dbentp
->tl_data
;
1753 dbentp
->tl_data
= pwchg
;
1754 dbentp
->n_tl_data
++;
1766 * process_k5beta_record() - Handle a dump record in old format.
1768 * Returns -1 for end of file, 0 for success and 1 for failure.
1771 process_k5beta_record(fname
, kcontext
, filep
, verbose
, linenop
)
1773 krb5_context kcontext
;
1780 krb5_db_entry dbent
;
1781 int name_len
, mod_name_len
, key_len
;
1782 int alt_key_len
, salt_len
, alt_salt_len
;
1785 int tmpint1
, tmpint2
, tmpint3
;
1787 const char *try2read
;
1789 krb5_key_data
*pkey
, *akey
;
1790 krb5_timestamp last_pwd_change
, mod_date
;
1791 krb5_principal mod_princ
;
1792 krb5_error_code kret
;
1793 krb5_octet
*shortcopy1
= NULL
; /* SUNWresync121 memleak fix */
1794 krb5_octet
*shortcopy2
= NULL
;
1796 try2read
= (char *) NULL
;
1799 memset((char *)&dbent
, 0, sizeof(dbent
));
1801 /* Make sure we've got key_data entries */
1802 if (krb5_dbe_create_key_data(kcontext
, &dbent
) ||
1803 krb5_dbe_create_key_data(kcontext
, &dbent
)) {
1804 krb5_db_free_principal(kcontext
, &dbent
, 1);
1807 pkey
= &dbent
.key_data
[0];
1808 akey
= &dbent
.key_data
[1];
1811 * Match the sizes. 6 tokens to match.
1813 nmatched
= fscanf(filep
, "%d\t%d\t%d\t%d\t%d\t%d\t",
1814 &name_len
, &mod_name_len
, &key_len
,
1815 &alt_key_len
, &salt_len
, &alt_salt_len
);
1816 if (nmatched
== 6) {
1817 pkey
->key_data_length
[0] = key_len
;
1818 akey
->key_data_length
[0] = alt_key_len
;
1819 pkey
->key_data_length
[1] = salt_len
;
1820 akey
->key_data_length
[1] = alt_salt_len
;
1821 name
= (char *) NULL
;
1822 mod_name
= (char *) NULL
;
1824 * Get the memory for the variable length fields.
1826 if ((name
= (char *) malloc((size_t) (name_len
+ 1))) &&
1827 (mod_name
= (char *) malloc((size_t) (mod_name_len
+ 1))) &&
1829 (pkey
->key_data_contents
[0] =
1830 (krb5_octet
*) malloc((size_t) (key_len
+ 1)))) &&
1832 (akey
->key_data_contents
[0] =
1833 (krb5_octet
*) malloc((size_t) (alt_key_len
+ 1)))) &&
1835 (pkey
->key_data_contents
[1] =
1836 (krb5_octet
*) malloc((size_t) (salt_len
+ 1)))) &&
1838 (akey
->key_data_contents
[1] =
1839 (krb5_octet
*) malloc((size_t) (alt_salt_len
+ 1))))
1843 /* Read the principal name */
1844 if (read_string(filep
, name
, name_len
, linenop
)) {
1845 try2read
= read_name_string
;
1848 /* Read the key type */
1849 if (!error
&& (fscanf(filep
, "\t%d\t", &tmpint1
) != 1)) {
1850 try2read
= read_key_type
;
1853 pkey
->key_data_type
[0] = tmpint1
;
1854 /* Read the old format key */
1855 if (!error
&& read_octet_string(filep
,
1856 pkey
->key_data_contents
[0],
1857 pkey
->key_data_length
[0])) {
1858 try2read
= read_key_data
;
1861 /* convert to a new format key */
1862 /* the encrypted version is stored as the unencrypted key length
1863 (4 bytes, MSB first) followed by the encrypted key. */
1864 if ((pkey
->key_data_length
[0] > 4)
1865 && (pkey
->key_data_contents
[0][0] == 0)
1866 && (pkey
->key_data_contents
[0][1] == 0)) {
1867 /* this really does look like an old key, so drop and swap */
1868 /* the *new* length is 2 bytes, LSB first, sigh. */
1869 size_t shortlen
= pkey
->key_data_length
[0]-4+2;
1870 krb5_octet
*origdata
= pkey
->key_data_contents
[0];
1872 shortcopy1
= (krb5_octet
*) malloc(shortlen
);
1874 shortcopy1
[0] = origdata
[3];
1875 shortcopy1
[1] = origdata
[2];
1876 memcpy(shortcopy1
+ 2, origdata
+ 4, shortlen
- 2);
1878 pkey
->key_data_length
[0] = shortlen
;
1879 pkey
->key_data_contents
[0] = shortcopy1
;
1881 fprintf(stderr
, gettext(no_mem_fmt
), fname
, *linenop
);
1886 /* Read principal attributes */
1887 if (!error
&& (fscanf(filep
,
1888 "\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t",
1889 &tmpint1
, &dbent
.max_life
,
1890 &dbent
.max_renewable_life
,
1891 &tmpint2
, &dbent
.expiration
,
1892 &dbent
.pw_expiration
, &last_pwd_change
,
1893 &dbent
.last_success
, &dbent
.last_failed
,
1895 try2read
= read_pr_data1
;
1898 pkey
->key_data_kvno
= tmpint1
;
1899 dbent
.fail_auth_count
= tmpint3
;
1900 /* Read modifier name */
1901 if (!error
&& read_string(filep
,
1905 try2read
= read_mod_name
;
1908 /* Read second set of attributes */
1909 if (!error
&& (fscanf(filep
, "\t%u\t%u\t%u\t",
1910 &mod_date
, &dbent
.attributes
,
1912 try2read
= read_pr_data2
;
1915 pkey
->key_data_type
[1] = tmpint1
;
1916 /* Read salt data */
1917 if (!error
&& read_octet_string(filep
,
1918 pkey
->key_data_contents
[1],
1919 pkey
->key_data_length
[1])) {
1920 try2read
= read_salt_data
;
1923 /* Read alternate key type */
1924 if (!error
&& (fscanf(filep
, "\t%u\t", &tmpint1
) != 1)) {
1925 try2read
= read_akey_type
;
1928 akey
->key_data_type
[0] = tmpint1
;
1929 /* Read alternate key */
1930 if (!error
&& read_octet_string(filep
,
1931 akey
->key_data_contents
[0],
1932 akey
->key_data_length
[0])) {
1933 try2read
= read_akey_data
;
1937 /* convert to a new format key */
1938 /* the encrypted version is stored as the unencrypted key length
1939 (4 bytes, MSB first) followed by the encrypted key. */
1940 if ((akey
->key_data_length
[0] > 4)
1941 && (akey
->key_data_contents
[0][0] == 0)
1942 && (akey
->key_data_contents
[0][1] == 0)) {
1943 /* this really does look like an old key, so drop and swap */
1944 /* the *new* length is 2 bytes, LSB first, sigh. */
1945 size_t shortlen
= akey
->key_data_length
[0]-4+2;
1947 krb5_octet
*origdata
= akey
->key_data_contents
[0];
1949 shortcopy2
= (krb5_octet
*) malloc(shortlen
);
1951 shortcopy2
[0] = origdata
[3];
1952 shortcopy2
[1] = origdata
[2];
1953 memcpy(shortcopy2
+ 2,
1954 origdata
+ 4, shortlen
- 2);
1956 akey
->key_data_length
[0] = shortlen
;
1957 akey
->key_data_contents
[0] = shortcopy2
;
1959 fprintf(stderr
, gettext(no_mem_fmt
), fname
, *linenop
);
1964 /* Read alternate salt type */
1965 if (!error
&& (fscanf(filep
, "\t%u\t", &tmpint1
) != 1)) {
1966 try2read
= read_asalt_type
;
1969 akey
->key_data_type
[1] = tmpint1
;
1970 /* Read alternate salt data */
1971 if (!error
&& read_octet_string(filep
,
1972 akey
->key_data_contents
[1],
1973 akey
->key_data_length
[1])) {
1974 try2read
= read_asalt_data
;
1977 /* Read expansion data - discard it */
1979 for (i
=0; i
<8; i
++) {
1980 if (fscanf(filep
, "\t%u", &tmpint1
) != 1) {
1981 try2read
= read_exp_data
;
1987 find_record_end(filep
, fname
, *linenop
);
1991 * If no error, then we're done reading. Now parse the names
1992 * and store the database dbent.
1995 if (!(kret
= krb5_parse_name(kcontext
,
1998 if (!(kret
= krb5_parse_name(kcontext
,
2002 krb5_dbe_update_mod_princ_data(kcontext
,
2007 krb5_dbe_update_last_pwd_change(kcontext
,
2009 last_pwd_change
))) {
2012 dbent
.len
= KRB5_KDB_V1_BASE_LENGTH
;
2013 pkey
->key_data_ver
= (pkey
->key_data_type
[1] || pkey
->key_data_length
[1]) ?
2015 akey
->key_data_ver
= (akey
->key_data_type
[1] || akey
->key_data_length
[1]) ?
2017 if ((pkey
->key_data_type
[0] ==
2018 akey
->key_data_type
[0]) &&
2019 (pkey
->key_data_type
[1] ==
2020 akey
->key_data_type
[1]))
2022 else if ((akey
->key_data_type
[0] == 0)
2023 && (akey
->key_data_length
[0] == 0)
2024 && (akey
->key_data_type
[1] == 0)
2025 && (akey
->key_data_length
[1] == 0))
2028 dbent
.mask
= KADM5_LOAD
| KADM5_PRINCIPAL
| KADM5_ATTRIBUTES
|
2029 KADM5_MAX_LIFE
| KADM5_MAX_RLIFE
| KADM5_KEY_DATA
|
2030 KADM5_PRINC_EXPIRE_TIME
| KADM5_LAST_SUCCESS
|
2031 KADM5_LAST_FAILED
| KADM5_FAIL_AUTH_COUNT
;
2033 if ((kret
= krb5_db_put_principal(kcontext
,
2037 fprintf(stderr
, gettext(store_err_fmt
),
2038 fname
, *linenop
, name
,
2039 error_message(kret
));
2045 gettext(add_princ_fmt
),
2049 dbent
.n_key_data
= 2;
2051 krb5_free_principal(kcontext
, mod_princ
);
2055 gettext(parse_err_fmt
),
2056 fname
, *linenop
, mod_name
,
2057 error_message(kret
));
2062 fprintf(stderr
, gettext(parse_err_fmt
),
2063 fname
, *linenop
, name
, error_message(kret
));
2068 fprintf(stderr
, gettext(no_mem_fmt
), fname
, *linenop
, try2read
);
2072 fprintf(stderr
, gettext(read_err_fmt
), fname
, *linenop
);
2075 krb5_db_free_principal(kcontext
, &dbent
, 1);
2080 if (nmatched
!= EOF
)
2081 fprintf(stderr
, gettext(rhead_err_fmt
),
2094 * process_k5beta6_record() - Handle a dump record in krb5b6 format.
2096 * Returns -1 for end of file, 0 for success and 1 for failure.
2099 process_k5beta6_record(fname
, kcontext
, filep
, verbose
, linenop
)
2101 krb5_context kcontext
;
2107 krb5_db_entry dbentry
;
2108 krb5_int32 t1
, t2
, t3
, t4
, t5
, t6
, t7
, t8
, t9
;
2113 krb5_key_data
*kp
, *kdatap
;
2114 krb5_tl_data
**tlp
, *tl
;
2116 krb5_error_code kret
;
2117 const char *try2read
;
2119 try2read
= (char *) NULL
;
2120 memset((char *) &dbentry
, 0, sizeof(dbentry
));
2123 name
= (char *) NULL
;
2124 kp
= (krb5_key_data
*) NULL
;
2125 op
= (krb5_octet
*) NULL
;
2128 nread
= fscanf(filep
, "%d\t%d\t%d\t%d\t%d\t", &t1
, &t2
, &t3
, &t4
, &t5
);
2130 /* Get memory for flattened principal name */
2131 if (!(name
= (char *) malloc((size_t) t2
+ 1)))
2134 /* Get memory for and form tagged data linked list */
2135 tlp
= &dbentry
.tl_data
;
2136 for (i
=0; i
<t3
; i
++) {
2137 if ((*tlp
= (krb5_tl_data
*) malloc(sizeof(krb5_tl_data
)))) {
2138 memset(*tlp
, 0, sizeof(krb5_tl_data
));
2139 tlp
= &((*tlp
)->tl_data_next
);
2140 dbentry
.n_tl_data
++;
2148 /* Get memory for key list */
2149 if (t4
&& !(kp
= (krb5_key_data
*) malloc((size_t)
2150 (t4
*sizeof(krb5_key_data
)))))
2153 /* Get memory for extra data */
2154 if (t5
&& !(op
= (krb5_octet
*) malloc((size_t) t5
)))
2159 dbentry
.n_key_data
= t4
;
2160 dbentry
.e_length
= t5
;
2162 memset(kp
, 0, (size_t) (t4
*sizeof(krb5_key_data
)));
2163 dbentry
.key_data
= kp
;
2164 kp
= (krb5_key_data
*) NULL
;
2167 memset(op
, 0, (size_t) t5
);
2168 dbentry
.e_data
= op
;
2169 op
= (krb5_octet
*) NULL
;
2172 /* Read in and parse the principal name */
2173 if (!read_string(filep
, name
, t2
, linenop
) &&
2174 !(kret
= krb5_parse_name(kcontext
, name
, &dbentry
.princ
))) {
2176 /* Get the fixed principal attributes */
2177 nread
= fscanf(filep
, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t",
2178 &t2
, &t3
, &t4
, &t5
, &t6
, &t7
, &t8
, &t9
);
2180 dbentry
.attributes
= (krb5_flags
) t2
;
2181 dbentry
.max_life
= (krb5_deltat
) t3
;
2182 dbentry
.max_renewable_life
= (krb5_deltat
) t4
;
2183 dbentry
.expiration
= (krb5_timestamp
) t5
;
2184 dbentry
.pw_expiration
= (krb5_timestamp
) t6
;
2185 dbentry
.last_success
= (krb5_timestamp
) t7
;
2186 dbentry
.last_failed
= (krb5_timestamp
) t8
;
2187 dbentry
.fail_auth_count
= (krb5_kvno
) t9
;
2188 dbentry
.mask
= KADM5_LOAD
| KADM5_PRINCIPAL
| KADM5_ATTRIBUTES
|
2189 KADM5_MAX_LIFE
| KADM5_MAX_RLIFE
|
2190 KADM5_PRINC_EXPIRE_TIME
| KADM5_LAST_SUCCESS
|
2191 KADM5_LAST_FAILED
| KADM5_FAIL_AUTH_COUNT
;
2193 try2read
= read_nint_data
;
2198 * Get the tagged data.
2200 * Really, this code ought to discard tl data types
2201 * that it knows are special to the current version
2202 * and were not supported in the previous version.
2203 * But it's a pain to implement that here, and doing
2204 * it at dump time has almost as good an effect, so
2205 * that's what I did. [krb5-admin/89]
2207 if (!error
&& dbentry
.n_tl_data
) {
2208 for (tl
= dbentry
.tl_data
; tl
; tl
= tl
->tl_data_next
) {
2209 nread
= fscanf(filep
, "%d\t%d\t", &t1
, &t2
);
2211 tl
->tl_data_type
= (krb5_int16
) t1
;
2212 tl
->tl_data_length
= (krb5_int16
) t2
;
2213 if (tl
->tl_data_length
) {
2214 if (!(tl
->tl_data_contents
=
2215 (krb5_octet
*) malloc((size_t) t2
+1)) ||
2216 read_octet_string(filep
,
2217 tl
->tl_data_contents
,
2219 try2read
= read_tcontents
;
2223 /* test to set mask fields */
2224 if (t1
== KRB5_TL_KADM_DATA
) {
2226 osa_princ_ent_rec osa_princ_ent
;
2229 * Assuming aux_attributes will always be
2232 dbentry
.mask
|= KADM5_AUX_ATTRIBUTES
;
2234 /* test for an actual policy reference */
2235 memset(&osa_princ_ent
, 0, sizeof(osa_princ_ent
));
2236 xdrmem_create(&xdrs
, (char *)tl
->tl_data_contents
,
2237 tl
->tl_data_length
, XDR_DECODE
);
2238 if (xdr_osa_princ_ent_rec(&xdrs
, &osa_princ_ent
) &&
2239 (osa_princ_ent
.aux_attributes
& KADM5_POLICY
) &&
2240 osa_princ_ent
.policy
!= NULL
) {
2242 dbentry
.mask
|= KADM5_POLICY
;
2243 kdb_free_entry(NULL
, NULL
, &osa_princ_ent
);
2249 /* Should be a null field */
2250 nread
= fscanf(filep
, "%d", &t9
);
2251 if ((nread
!= 1) || (t9
!= -1)) {
2253 try2read
= read_tcontents
;
2259 try2read
= read_ttypelen
;
2265 dbentry
.mask
|= KADM5_TL_DATA
;
2268 /* Get the key data */
2269 if (!error
&& dbentry
.n_key_data
) {
2270 for (i
=0; !error
&& (i
<dbentry
.n_key_data
); i
++) {
2271 kdatap
= &dbentry
.key_data
[i
];
2272 nread
= fscanf(filep
, "%d\t%d\t", &t1
, &t2
);
2274 kdatap
->key_data_ver
= (krb5_int16
) t1
;
2275 kdatap
->key_data_kvno
= (krb5_int16
) t2
;
2277 for (j
=0; j
<t1
; j
++) {
2278 nread
= fscanf(filep
, "%d\t%d\t", &t3
, &t4
);
2280 kdatap
->key_data_type
[j
] = t3
;
2281 kdatap
->key_data_length
[j
] = t4
;
2283 if (!(kdatap
->key_data_contents
[j
] =
2285 malloc((size_t) t4
+1)) ||
2286 read_octet_string(filep
,
2287 kdatap
->key_data_contents
[j
],
2289 try2read
= read_kcontents
;
2295 /* Should be a null field */
2296 nread
= fscanf(filep
, "%d", &t9
);
2297 if ((nread
!= 1) || (t9
!= -1)) {
2299 try2read
= read_kcontents
;
2305 try2read
= read_ktypelen
;
2313 dbentry
.mask
|= KADM5_KEY_DATA
;
2316 /* Get the extra data */
2317 if (!error
&& dbentry
.e_length
) {
2318 if (read_octet_string(filep
,
2320 (int) dbentry
.e_length
)) {
2321 try2read
= read_econtents
;
2326 nread
= fscanf(filep
, "%d", &t9
);
2327 if ((nread
!= 1) || (t9
!= -1)) {
2329 try2read
= read_econtents
;
2333 /* Finally, find the end of the record. */
2335 find_record_end(filep
, fname
, *linenop
);
2338 * We have either read in all the data or choked.
2342 if ((kret
= krb5_db_put_principal(kcontext
,
2346 gettext(store_err_fmt
),
2348 name
, error_message(kret
));
2360 fprintf(stderr
, gettext(read_err_fmt
),
2361 fname
, *linenop
, try2read
);
2366 fprintf(stderr
, gettext(parse_err_fmt
),
2367 fname
, *linenop
, name
, error_message(kret
));
2369 fprintf(stderr
, gettext(no_mem_fmt
),
2375 gettext(rhead_err_fmt
), fname
, *linenop
);
2381 krb5_db_free_principal(kcontext
, &dbentry
, 1);
2391 process_k5beta7_policy(fname
, kcontext
, filep
, verbose
, linenop
, pol_db
)
2393 krb5_context kcontext
;
2399 osa_policy_ent_rec rec
;
2406 nread
= fscanf(filep
, "%1024s\t%d\t%d\t%d\t%d\t%d\t%d", rec
.name
,
2407 &rec
.pw_min_life
, &rec
.pw_max_life
,
2408 &rec
.pw_min_length
, &rec
.pw_min_classes
,
2409 &rec
.pw_history_num
, &rec
.policy_refcnt
);
2412 else if (nread
!= 7) {
2414 gettext("cannot parse policy on line %d (%d read)\n"),
2419 if ((ret
= krb5_db_create_policy(kcontext
, &rec
))) {
2421 ((ret
= krb5_db_put_policy(kcontext
, &rec
)))) {
2422 fprintf(stderr
, gettext("cannot create policy on line %d: %s\n"),
2423 *linenop
, error_message(ret
));
2428 fprintf(stderr
, gettext("created policy %s\n"), rec
.name
);
2434 * process_k5beta7_record() - Handle a dump record in krb5b7 format.
2436 * Returns -1 for end of file, 0 for success and 1 for failure.
2439 process_k5beta7_record(fname
, kcontext
, filep
, verbose
, linenop
)
2441 krb5_context kcontext
;
2449 nread
= fscanf(filep
, "%100s\t", rectype
);
2452 else if (nread
!= 1)
2454 if (strcmp(rectype
, "princ") == 0)
2455 process_k5beta6_record(fname
, kcontext
, filep
, verbose
,
2457 else if (strcmp(rectype
, "policy") == 0)
2458 process_k5beta7_policy(fname
, kcontext
, filep
, verbose
,
2462 gettext("unknown record type \"%s\" on line %d\n"),
2471 * process_ov_record() - Handle a dump record in OpenV*Secure 1.0 format.
2473 * Returns -1 for end of file, 0 for success and 1 for failure.
2476 process_ov_record(fname
, kcontext
, filep
, verbose
, linenop
)
2478 krb5_context kcontext
;
2486 nread
= fscanf(filep
, "%100s\t", rectype
);
2489 else if (nread
!= 1)
2491 if (strcmp(rectype
, "princ") == 0)
2492 process_ov_principal(fname
, kcontext
, filep
, verbose
,
2494 else if (strcmp(rectype
, "policy") == 0)
2495 process_k5beta7_policy(fname
, kcontext
, filep
, verbose
,
2497 else if (strcmp(rectype
, "End") == 0)
2501 gettext("unknown record type \"%s\" on line %d\n"),
2510 * restore_dump() - Restore the database from any version dump file.
2513 restore_dump(programname
, kcontext
, dumpfile
, f
, verbose
, dump
)
2515 krb5_context kcontext
;
2528 * Process the records.
2530 while (!(error
= (*dump
->load_record
)(dumpfile
,
2537 fprintf(stderr
, gettext(err_line_fmt
),
2538 programname
, lineno
, dumpfile
);
2546 * Usage: load_db [-i] [-old] [-ov] [-b6] [-b7] [-verbose] [-update] [-hash]
2554 kadm5_config_params newparams
;
2555 krb5_error_code kret
;
2556 krb5_context kcontext
;
2558 extern char *optarg
;
2560 /* Solaris Kerberos */
2569 int update
, verbose
;
2572 bool_t add_update
= TRUE
;
2573 char iheader
[MAX_HEADER
];
2574 uint32_t caller
, last_sno
, last_seconds
, last_useconds
;
2575 kdb_log_context
*log_ctx
;
2579 * Parse the arguments.
2581 /* Solaris Kerberos */
2583 programname
= argv
[0];
2584 if (strrchr(programname
, (int) '/'))
2585 programname
= strrchr(argv
[0], (int) '/') + 1;
2587 dumpfile
= (char *) NULL
;
2588 dbname
= global_params
.dbname
;
2592 crflags
= KRB5_KDB_CREATE_BTREE
;
2594 dbname_tmp
= (char *) NULL
;
2595 log_ctx
= util_context
->kdblog_context
;
2597 for (aindex
= 1; aindex
< argc
; aindex
++) {
2598 if (!strcmp(argv
[aindex
], oldoption
))
2599 load
= &old_version
;
2600 else if (!strcmp(argv
[aindex
], b6option
))
2601 load
= &beta6_version
;
2602 else if (!strcmp(argv
[aindex
], b7option
))
2603 load
= &beta7_version
;
2604 else if (!strcmp(argv
[aindex
], ovoption
))
2606 else if (!strcmp(argv
[aindex
], ipropoption
)) {
2607 if (log_ctx
&& log_ctx
->iproprole
) {
2608 load
= &iprop_version
;
2611 fprintf(stderr
, gettext("Iprop not enabled\n"));
2616 else if (!strcmp(argv
[aindex
], verboseoption
))
2618 else if (!strcmp(argv
[aindex
], updateoption
))
2620 else if (!strcmp(argv
[aindex
], hashoption
)) {
2621 if (!add_db_arg("hash=true")) {
2622 com_err(progname
, ENOMEM
, "while parsing command arguments\n");
2628 if ((argc
- aindex
) != 1) {
2632 dumpfile
= argv
[aindex
];
2634 if (!(dbname_tmp
= (char *) malloc(strlen(dbname
)+
2635 strlen(dump_tmptrail
)+1))) {
2636 /* Solaris Kerberos */
2637 fprintf(stderr
, gettext(no_name_mem_fmt
), progname
);
2641 strcpy(dbname_tmp
, dbname
);
2642 strcat(dbname_tmp
, dump_tmptrail
);
2645 * Initialize the Kerberos context and error tables.
2647 if ((kret
= kadm5_init_krb5_context(&kcontext
))) {
2648 /* Solaris Kerberos */
2649 fprintf(stderr
, gettext(ctx_err_fmt
), progname
);
2655 if( (kret
= krb5_set_default_realm(kcontext
, util_context
->default_realm
)) )
2657 /* Solaris Kerberos */
2658 fprintf(stderr
, gettext("%s: Unable to set the default realm\n"), progname
);
2663 if (log_ctx
&& log_ctx
->iproprole
)
2664 kcontext
->kdblog_context
= (void *)log_ctx
;
2669 if ((f
= fopen(dumpfile
, "r")) == NULL
) {
2670 /* Solaris Kerberos */
2671 fprintf(stderr
, gettext(dfile_err_fmt
),
2673 error_message(errno
));
2677 if ((kret
= krb5_lock_file(kcontext
, fileno(f
),
2678 KRB5_LOCKMODE_SHARED
))) {
2679 /* Solaris Kerberos */
2680 fprintf(stderr
, gettext("%s: Cannot lock %s: %s\n"), progname
,
2681 dumpfile
, error_message(errno
));
2689 * Auto-detect dump version if we weren't told, verify if we
2692 fgets(buf
, sizeof(buf
), f
);
2694 /* only check what we know; some headers only contain a prefix */
2695 if (strncmp(buf
, load
->header
, strlen(load
->header
)) != 0) {
2696 /* Solaris Kerberos */
2697 fprintf(stderr
, gettext(head_bad_fmt
), progname
, dumpfile
);
2699 if (dumpfile
) fclose(f
);
2703 /* perhaps this should be in an array, but so what? */
2704 if (strcmp(buf
, old_version
.header
) == 0)
2705 load
= &old_version
;
2706 else if (strcmp(buf
, beta6_version
.header
) == 0)
2707 load
= &beta6_version
;
2708 else if (strcmp(buf
, beta7_version
.header
) == 0)
2709 load
= &beta7_version
;
2710 else if (strcmp(buf
, r1_3_version
.header
) == 0)
2711 load
= &r1_3_version
;
2712 else if (strncmp(buf
, ov_version
.header
,
2713 strlen(ov_version
.header
)) == 0)
2716 /* Solaris Kerberos */
2717 fprintf(stderr
, gettext(head_bad_fmt
),
2718 progname
, dumpfile
);
2720 if (dumpfile
) fclose(f
);
2724 if (load
->updateonly
&& !update
) {
2725 /* Solaris Kerberos */
2727 gettext("%s: dump version %s can only "
2728 "be loaded with the -update flag\n"),
2729 progname
, load
->name
);
2735 * Cons up params for the new databases. If we are not in update
2736 * mode, we create an alternate database and then promote it to
2739 newparams
= global_params
;
2741 newparams
.mask
|= KADM5_CONFIG_DBNAME
;
2742 newparams
.dbname
= dbname_tmp
;
2744 if ((kret
= kadm5_get_config_params(kcontext
, 1,
2745 &newparams
, &newparams
))) {
2746 /* Solaris Kerberos */
2747 com_err(progname
, kret
,
2748 gettext("while retreiving new "
2749 "configuration parameters"));
2754 if (!add_db_arg("temporary")) {
2755 com_err(progname
, ENOMEM
, "computing parameters for database");
2761 * If not an update restoration, create the database. otherwise open
2764 if((kret
= krb5_db_create(kcontext
, db5util_db_args
))) {
2765 const char *emsg
= krb5_get_error_message(kcontext
, kret
);
2767 * See if something (like DAL KDB plugin) has set a specific error
2768 * message and use that otherwise use default.
2772 /* Solaris Kerberos */
2773 fprintf(stderr
, "%s: %s\n", progname
, emsg
);
2774 krb5_free_error_message (kcontext
, emsg
);
2776 /* Solaris Kerberos */
2777 fprintf(stderr
, dbcreaterr_fmt
,
2778 progname
, dbname
, error_message(kret
));
2781 kadm5_free_config_params(kcontext
, &newparams
);
2782 if (dumpfile
) fclose(f
);
2788 * Initialize the database.
2790 if ((kret
= krb5_db_open(kcontext
, db5util_db_args
,
2791 KRB5_KDB_OPEN_RW
| KRB5_KDB_SRV_TYPE_ADMIN
))) {
2792 const char *emsg
= krb5_get_error_message(kcontext
, kret
);
2794 * See if something (like DAL KDB plugin) has set a specific
2795 * error message and use that otherwise use default.
2799 /* Solaris Kerberos */
2800 fprintf(stderr
, "%s: %s\n", progname
, emsg
);
2801 krb5_free_error_message (kcontext
, emsg
);
2803 /* Solaris Kerberos */
2804 fprintf(stderr
, dbinit_err_fmt
,
2805 progname
, error_message(kret
));
2814 * If an update restoration, make sure the db is left unusable if
2817 if ((kret
= krb5_db_lock(kcontext
, update
?KRB5_DB_LOCKMODE_PERMANENT
: KRB5_DB_LOCKMODE_EXCLUSIVE
))) {
2819 * Ignore a not supported error since there is nothing to do about it
2822 if (kret
!= KRB5_PLUGIN_OP_NOTSUPP
) {
2823 /* Solaris Kerberos */
2824 fprintf(stderr
, gettext("%s: %s while permanently locking database\n"),
2825 progname
, error_message(kret
));
2833 if (log_ctx
&& log_ctx
->iproprole
) {
2839 if (ulog_map(kcontext
, &global_params
, caller
)) {
2840 /* Solaris Kerberos */
2842 gettext("%s: Could not map log\n"),
2849 * We don't want to take out the ulog out from underneath
2850 * kadmind so we reinit the header log.
2852 * We also don't want to add to the update log since we
2853 * are doing a whole sale replace of the db, because:
2854 * we could easily exceed # of update entries
2855 * we could implicity delete db entries during a replace
2856 * no advantage in incr updates when entire db is replaced
2859 memset(log_ctx
->ulog
, 0, sizeof (kdb_hlog_t
));
2861 log_ctx
->ulog
->kdb_hmagic
= KDB_HMAGIC
;
2862 log_ctx
->ulog
->db_version_num
= KDB_VERSION
;
2863 log_ctx
->ulog
->kdb_state
= KDB_STABLE
;
2864 log_ctx
->ulog
->kdb_block
= ULOG_BLOCK
;
2866 log_ctx
->iproprole
= IPROP_NULL
;
2869 sscanf(buf
, "%s %u %u %u", iheader
, &last_sno
,
2870 &last_seconds
, &last_useconds
);
2872 log_ctx
->ulog
->kdb_last_sno
= last_sno
;
2873 log_ctx
->ulog
->kdb_last_time
.seconds
=
2875 log_ctx
->ulog
->kdb_last_time
.useconds
=
2881 /* Solaris Kerberos */
2882 if (restore_dump(progname
, kcontext
, (dumpfile
) ? dumpfile
: stdin_name
,
2883 f
, verbose
, load
)) {
2884 /* Solaris Kerberos */
2885 fprintf(stderr
, gettext(restfail_fmt
),
2886 progname
, load
->name
);
2890 if (!update
&& load
->create_kadm5
&&
2891 ((kret
= kadm5_create_magic_princs(&newparams
, kcontext
)))) {
2892 /* error message printed by create_magic_princs */
2896 if (db_locked
&& (kret
= krb5_db_unlock(kcontext
))) {
2897 /* change this error? */
2898 /* Solaris Kerberos */
2899 fprintf(stderr
, gettext(dbunlockerr_fmt
),
2900 progname
, dbname
, error_message(kret
));
2905 if ((kret
= krb5_db_fini(kcontext
))) {
2906 /* Solaris Kerberos */
2907 fprintf(stderr
, gettext(close_err_fmt
),
2908 progname
, error_message(kret
));
2913 /* close policy db below */
2915 if (exit_status
== 0 && !update
) {
2916 kret
= krb5_db_promote(kcontext
, db5util_db_args
);
2918 * Ignore a not supported error since there is nothing to do about it
2921 if (kret
!= 0 && kret
!= KRB5_PLUGIN_OP_NOTSUPP
) {
2922 /* Solaris Kerberos */
2923 fprintf(stderr
, gettext("%s: cannot make newly loaded database live (%s)\n"),
2924 progname
, error_message(kret
));
2931 * If not an update: if there was an error, destroy the temp database,
2932 * otherwise rename it into place.
2934 * If an update: if there was no error, unlock the database.
2938 kret
= krb5_db_destroy(kcontext
, db5util_db_args
);
2940 * Ignore a not supported error since there is nothing to do about
2943 if (kret
!= 0 && kret
!= KRB5_PLUGIN_OP_NOTSUPP
) {
2944 /* Solaris Kerberos */
2945 fprintf(stderr
, gettext(dbdelerr_fmt
),
2946 progname
, dbname
, error_message(kret
));
2953 (void) krb5_lock_file(kcontext
, fileno(f
), KRB5_LOCKMODE_UNLOCK
);
2958 krb5_free_context(kcontext
);