dump.c revision 2dd2efa5a06a9befe46075cf41e16f57533c9f98
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
* Openvision retains the copyright to derivative works of
* this source code. Do *NOT* create a derivative of this
* source code before consulting with your legal department.
* Do *NOT* integrate *ANY* of this source code into another
* product before consulting with your legal department.
*
* For further information, read the top-level Openvision
* copyright which is contained in the top-level MIT Kerberos
* copyright.
*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
*/
/*
*
* Copyright 1990,1991 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
*
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
* permission. Furthermore if you modify this software you must label
* your software as modified software and not distribute it in such a
* fashion that it might be confused with the original M.I.T. software.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*
*
* Dump a KDC database
*/
#include <stdio.h>
#include <k5-int.h>
#include <kadm5/server_internal.h>
#include <kdb.h>
#include <com_err.h>
#include <libintl.h>
#include "kdb5_util.h"
#if defined(HAVE_REGEX_H) && defined(HAVE_REGCOMP)
#include <regex.h>
#endif /* HAVE_REGEX_H */
/*
* Needed for master key conversion.
*/
extern krb5_keyblock master_key;
extern krb5_principal master_princ;
static int mkey_convert;
static krb5_keyblock new_master_key;
static int backwards;
static int recursive;
/*
* Use compile(3) if no regcomp present.
*/
#if !defined(HAVE_REGCOMP) && defined(HAVE_REGEXP_H)
#define RETURN(c) return(c)
#define ERROR(c)
#define RE_BUF_SIZE 1024
#include <regexp.h>
#endif /* !HAVE_REGCOMP && HAVE_REGEXP_H */
struct dump_args {
char *programname;
char **names;
int nnames;
int verbose;
};
krb5_db_entry *);
krb5_db_entry *);
int);
krb5_db_entry *);
krb5_db_entry *);
int);
(krb5_pointer, krb5_db_entry *);
krb5_db_entry *);
krb5_db_entry *);
static void dump_k5beta7_policy (void *, osa_policy_ent_t);
krb5_db_entry *);
static int process_k5beta_record (char *, krb5_context,
FILE *, int, int *);
static int process_k5beta6_record (char *, krb5_context,
FILE *, int, int *);
static int process_k5beta7_record (char *, krb5_context,
FILE *, int, int *);
static int process_ov_record (char *, krb5_context,
FILE *, int, int *);
FILE *, int, int *);
typedef struct _dump_version {
char *name;
char *header;
int updateonly;
int create_kadm5;
} dump_version;
"Kerberos version 5 old format",
"kdb5_edit load_dump version 2.0\n",
0,
1,
NULL,
};
"Kerberos version 5 beta 6 format",
"kdb5_edit load_dump version 3.0\n",
0,
1,
NULL,
};
"Kerberos version 5",
"kdb5_util load_dump version 4\n",
0,
0,
};
"Kerberos iprop version",
"iprop",
0,
0,
};
"OpenV*Secure V1.0",
"OpenV*Secure V1.0\t",
1,
1,
};
"Kerberos version 5 release 1.3",
"kdb5_util load_dump version 5\n",
0,
0,
};
/* External data */
extern char *current_dbname;
extern krb5_boolean dbactive;
extern int exit_status;
extern krb5_context util_context;
extern kadm5_config_params global_params;
/* Strings */
#define k5beta_dump_header "kdb5_edit load_dump version 2.0\n"
static const char null_mprinc_name[] = "kdb5_dump@MISSING";
/*
* We define gettext(s) to be s here, so that xgettext will extract the
* strings to the .po file. At the end of the message section we will
* undef gettext so that we can use it as a funtion.
*/
#define gettext(s) s
/* Message strings */
static const char regex_err[] =
gettext("%s: regular expression error - %s\n");
static const char regex_merr[] =
gettext("%s: regular expression match error - %s\n");
static const char pname_unp_err[] =
gettext("%s: cannot unparse principal name (%s)\n");
static const char mname_unp_err[] =
gettext("%s: cannot unparse modifier name (%s)\n");
static const char nokeys_err[] =
gettext("%s: cannot find any standard key for %s\n");
static const char sdump_tl_inc_err[] =
gettext("%s: tagged data list inconsistency for %s "
"(counted %d, stored %d)\n");
static const char stand_fmt_name[] =
gettext("Kerberos version 5");
static const char old_fmt_name[] =
gettext("Kerberos version 5 old format");
static const char b6_fmt_name[] =
gettext("Kerberos version 5 beta 6 format");
static const char ofopen_error[] =
gettext("%s: cannot open %s for writing (%s)\n");
static const char oflock_error[] =
gettext("%s: cannot lock %s (%s)\n");
static const char dumprec_err[] =
gettext("%s: error performing %s dump (%s)\n");
static const char dumphdr_err[] =
gettext("%s: error dumping %s header (%s)\n");
static const char trash_end_fmt[] =
gettext("%s(%d): ignoring trash at end of line: ");
static const char read_name_string[] =
gettext("name string");
static const char read_key_type[] =
gettext("key type");
static const char read_key_data[] =
gettext("key data");
static const char read_pr_data1[] =
gettext("first set of principal attributes");
static const char read_mod_name[] =
gettext("modifier name");
static const char read_pr_data2[] =
gettext("second set of principal attributes");
static const char read_salt_data[] =
gettext("salt data");
static const char read_akey_type[] =
gettext("alternate key type");
static const char read_akey_data[] =
gettext("alternate key data");
static const char read_asalt_type[] =
gettext("alternate salt type");
static const char read_asalt_data[] =
gettext("alternate salt data");
static const char read_exp_data[] =
gettext("expansion data");
static const char store_err_fmt[] =
gettext("%s(%d): cannot store %s(%s)\n");
static const char add_princ_fmt[] =
gettext("%s\n");
static const char parse_err_fmt[] =
gettext("%s(%d): cannot parse %s (%s)\n");
static const char read_err_fmt[] =
gettext("%s(%d): cannot read %s\n");
static const char no_mem_fmt[] =
gettext("%s(%d): no memory for buffers\n");
static const char rhead_err_fmt[] =
gettext("%s(%d): cannot match size tokens\n");
static const char err_line_fmt[] =
gettext("%s: error processing line %d of %s\n");
static const char head_bad_fmt[] =
gettext("%s: dump header bad in %s\n");
static const char read_bytecnt[] =
gettext("record byte count");
static const char read_encdata[] =
gettext("encoded data");
static const char n_name_unp_fmt[] =
gettext("%s(%s): cannot unparse name\n");
static const char n_dec_cont_fmt[] =
gettext("%s(%s): cannot decode contents\n");
static const char read_nint_data[] =
gettext("principal static attributes");
static const char read_tcontents[] =
gettext("tagged data contents");
static const char read_ttypelen[] =
gettext("tagged data type and length");
static const char read_kcontents[] =
gettext("key data contents");
static const char read_ktypelen[] =
gettext("key data type and length");
static const char read_econtents[] =
gettext("extra data contents");
static const char k5beta_fmt_name[] =
gettext("Kerberos version 5 old format");
static const char standard_fmt_name[] =
gettext("Kerberos version 5 format");
static const char no_name_mem_fmt[] =
gettext("%s: cannot get memory for temporary name\n");
static const char ctx_err_fmt[] =
gettext("%s: cannot initialize Kerberos context\n");
static const char stdin_name[] =
gettext("standard input");
static const char remaster_err_fmt[] =
gettext("while re-encoding keys for principal %s with new master key");
static const char restfail_fmt[] =
gettext("%s: %s restore failed\n");
static const char close_err_fmt[] =
gettext("%s: cannot close database (%s)\n");
static const char dbinit_err_fmt[] =
gettext("%s: cannot initialize database (%s)\n");
static const char dblock_err_fmt[] =
gettext("%s: cannot initialize database lock (%s)\n");
static const char dbname_err_fmt[] =
gettext("%s: cannot set database name to %s (%s)\n");
static const char dbdelerr_fmt[] =
gettext("%s: cannot delete bad database %s (%s)\n");
static const char dbunlockerr_fmt[] =
gettext("%s: cannot unlock database %s (%s)\n");
static const char dbrenerr_fmt[] =
gettext("%s: cannot rename database %s to %s (%s)\n");
static const char dbcreaterr_fmt[] =
gettext("%s: cannot create database %s (%s)\n");
static const char dfile_err_fmt[] =
gettext("%s: cannot open %s (%s)\n");
/*
* We now return you to your regularly scheduled program.
*/
static const char oldoption[] = "-old";
static const char b6option[] = "-b6";
static const char b7option[] = "-b7";
static const char ipropoption[] = "-i";
static const char verboseoption[] = "-verbose";
static const char updateoption[] = "-update";
static const char hashoption[] = "-hash";
static const char ovoption[] = "-ov";
static const char dump_tmptrail[] = "~";
/*
* Re-encrypt the key_data with the new master key...
*/
{
int i, j;
"Master key db entry has %d keys, expecting only 1!\n"),
for (i=0; i < db_entry->n_key_data; i++) {
if (key_data->key_data_length == 0)
continue;
&keysalt);
if (retval)
return retval;
&new_key_data);
if (retval)
return retval;
for (j = 0; j < key_data->key_data_ver; j++) {
if (key_data->key_data_length[j]) {
}
}
*key_data = new_key_data;
}
return 0;
}
/*
* Update the "ok" file.
*/
void update_ok_file (file_name)
char *file_name;
{
char *file_ok;
int fd;
static char ok[]=".dump_ok";
== NULL) {
gettext("while allocating filename "
"for update_ok_file"));
exit_status++;
return;
}
gettext("while creating 'ok' file, '%s'"),
file_ok);
exit_status++;
return;
}
gettext("while writing to 'ok' file, '%s'"),
file_ok);
exit_status++;
return;
}
return;
}
/*
* name_matches() - See if a principal name matches a regular expression
* or string.
*/
static int
char *name;
{
#if HAVE_REGCOMP
int match_error;
char match_errmsg[BUFSIZ];
char regexp_buffer[RE_BUF_SIZE];
extern char *re_comp();
char *re_result;
#endif /* HAVE_RE_COMP */
int i, match;
/*
*/
#if HAVE_REGCOMP
/*
* Compile the regular expression.
*/
if (match_error) {
sizeof(match_errmsg));
break;
}
/*
* See if we have a match.
*/
if (match_error) {
if (match_error != REG_NOMATCH) {
sizeof(match_errmsg));
break;
}
}
else {
/*
* We have a match. See if it matches the whole
* name.
*/
if ((match_match.rm_so == 0) &&
match = 1;
}
/*
* Compile the regular expression.
*/
'\0');
match = 1;
}
/*
* Compile the regular expression.
*/
break;
}
match = 1;
#else /* HAVE_RE_COMP */
/*
* If no regular expression support, then just compare the strings.
*/
match = 1;
#endif /* HAVE_REGCOMP */
if (match)
break;
}
return(match);
}
static krb5_error_code
{
int i;
int maxkvno;
maxkvno = -1;
for (i=0; i<dbentp->n_key_data; i++) {
(salttype < 0))) {
}
}
if (maxkvno >= 0) {
return(0);
}
return(ENOENT);
}
#if 0
/*
* dump_k5beta_header() - Make a dump header that is recognizable by Kerberos
* Version 5 Beta 5 and previous releases.
*/
static krb5_error_code
{
/* The old header consists of the leading string */
return(0);
}
#endif
/*
* dump_k5beta_iterator() - Dump an entry in a format that is usable
* by Kerberos Version 5 Beta 5 and previous
* releases.
*/
static krb5_error_code
{
int i;
/* Initialize */
/*
* Flatten the principal name.
*/
&name))) {
return(retval);
}
/*
* Re-encode the keys in the new master key, if necessary.
*/
if (mkey_convert) {
if (retval) {
return retval;
}
}
/*
* If we don't have any match strings, or if our name matches, then
* proceed with the dump, otherwise, just forget about it.
*/
/*
* Deserialize the modifier record.
*/
last_pwd_change = mod_date = 0;
&mod_date,
&mod_princ))) {
if (mod_princ) {
/*
* Flatten the modifier name.
*/
&mod_name)))
}
}
if (!mod_name)
/*
* Find the last password change record and set it straight.
*/
if ((retval =
&last_pwd_change))) {
return(retval);
}
/*
* Find the 'primary' key and the 'alternate' key.
*/
&pkey)) &&
&akey))) {
return(retval);
}
/* If we only have one type, then ship it out as the primary. */
}
else {
if (!akey)
}
/*
* First put out strings representing the length of the variable
* length data in this record, then the name and the primary key type.
*/
name,
for (i=0; i<pkey->key_data_length[0]; i++) {
}
/*
* Second, print out strings representing the standard integer
* data in this record.
*/
"\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",
/* Pound out the salt data, if present. */
}
/* Pound out the alternate key type and contents */
for (i=0; i<akey->key_data_length[0]; i++) {
}
/* Pound out the alternate salt type and contents */
}
/* Pound out the expansion data. (is null) */
for (i=0; i < 8; i++) {
}
/* If we're blabbing, do it */
}
return(0);
}
/*
* dump_k5beta6_iterator() - Output a dump record in krb5b6 format.
*/
static krb5_error_code
{
}
static krb5_error_code
int kadm;
{
char *name;
/* Initialize */
/*
* Flatten the principal name.
*/
&name))) {
return(retval);
}
/*
* Re-encode the keys in the new master key, if necessary.
*/
if (mkey_convert) {
if (retval) {
return retval;
}
}
/*
* If we don't have any match strings, or if our name matches, then
* proceed with the dump, otherwise, just forget about it.
*/
/*
* We'd like to just blast out the contents as they would appear in
* the database so that we can just suck it back in, but it doesn't
* lend itself to easy editing.
*/
/*
* The dump format is as follows:
* len strlen(name) n_tl_data n_key_data e_length
* name
* attributes max_life max_renewable_life expiration
* pw_expiration last_success last_failed fail_auth_count
* n_tl_data*[type length <contents>]
* n_key_data*[ver kvno ver*(type length <contents>)]
* <e_data>
* Fields which are not encapsulated by angle-brackets are to appear
* verbatim. A bracketed field's absence is indicated by a -1 in its
* place
*/
/*
* Make sure that the tagged list is reasonably correct.
*/
/*
* don't dump tl data types we know aren't understood by
* earlier revisions [krb5-admin/89]
*/
switch (tlp->tl_data_type) {
case KRB5_TL_KADM_DATA:
if (kadm)
counter++;
else
skip++;
break;
default:
counter++;
break;
}
}
/* Pound out header */
(int) entry->n_key_data,
name);
/* Pound out tagged data. */
continue; /* see above, [krb5-admin/89] */
(int) tlp->tl_data_type,
(int) tlp->tl_data_length);
if (tlp->tl_data_length)
for (i=0; i<tlp->tl_data_length; i++)
else
}
/* Pound out key data */
(int) kdata->key_data_ver,
(int) kdata->key_data_kvno);
for (i=0; i<kdata->key_data_ver; i++) {
kdata->key_data_type[i],
kdata->key_data_length[i]);
if (kdata->key_data_length[i])
for (j=0; j<kdata->key_data_length[i]; j++)
kdata->key_data_contents[i][j]);
else
}
}
/* Pound out extra data */
else
/* Print trailer */
}
else {
}
}
return(retval);
}
/*
* dump_iprop_iterator() - Output a dump record in iprop format.
*/
static krb5_error_code
{
char *name;
int counter, i, j;
/* Initialize */
/*
* Flatten the principal name.
*/
&name))) {
return(retval);
}
/*
* Re-encode the keys in the new master key, if necessary.
*/
if (mkey_convert) {
if (retval) {
return retval;
}
}
/*
* If we don't have any match strings, or if our name matches, then
* proceed with the dump, otherwise, just forget about it.
*/
/*
* We'd like to just blast out the contents as they would
* appear in the database so that we can just suck it back
* in, but it doesn't lend itself to easy editing.
*/
/*
* The dump format is as follows: len strlen(name)
* n_tl_data n_key_data e_length name attributes max_life
* max_renewable_life expiration pw_expiration last_success
* last_failed fail_auth_count n_tl_data*[type length
* <contents>] n_key_data*[ver kvno ver*(type length
* <contents>)] <e_data> Fields which are not encapsulated
* by angle-brackets are to appear verbatim. Bracketed
* fields absence is indicated by a -1 in its place
*/
/*
* Make sure that the tagged list is reasonably correct.
*/
counter = 0;
counter++;
/* Pound out header */
(int) entry->n_key_data,
name);
/* Pound out tagged data. */
(int) tlp->tl_data_type,
(int) tlp->tl_data_length);
if (tlp->tl_data_length)
for (i = 0;
i < tlp->tl_data_length;
i++)
tlp->
tl_data_contents[i]);
else
}
/* Pound out key data */
for (counter = 0;
(int) kdata->key_data_ver,
(int) kdata->key_data_kvno);
for (i=0; i<kdata->key_data_ver; i++) {
kdata->key_data_type[i],
kdata->key_data_length[i]);
if (kdata->key_data_length[i])
for (j = 0;
j < kdata->
key_data_length[i];
j++)
"%02x",
kdata->
[i][j]);
else
}
}
/* Pound out extra data */
else
/* Print trailer */
} else {
}
}
return(retval);
}
/*
* dump_k5beta7_iterator() - Output a dump record in krb5b7 format.
*/
static krb5_error_code
{
}
static krb5_error_code
int kadm;
{
char *name;
int tmp_nnames;
/* Initialize */
/*
* Flatten the principal name.
*/
&name))) {
return(retval);
}
/*
* If we don't have any match strings, or if our name matches, then
* proceed with the dump, otherwise, just forget about it.
*/
/* save the callee from matching the name again */
}
return retval;
}
/*
* dump_iprop_princ() - Output a dump record in iprop format.
* This was created in order to dump more data, such as kadm5 tl
*/
static krb5_error_code
{
char *name;
int tmp_nnames;
/* Initialize */
/*
* Flatten the principal name.
*/
&name))) {
return(retval);
}
/*
* If we don't have any match strings, or if our name matches, then
* proceed with the dump, otherwise, just forget about it.
*/
/* save the callee from matching the name again */
}
return (retval);
}
static krb5_error_code
{
}
{
}
{
int c;
key_data->key_data_length[0]);
for(c = 0; c < key_data->key_data_length[0]; c++)
fprintf(f, "%02x ",
key_data->key_data_contents[0][c]);
}
/*
* Function: print_princ
*
* Purpose: output osa_adb_princ_ent data in a human
* readable format (which is a format suitable for
* ovsec_adm_import consumption)
*
* Arguments:
* data (input) pointer to a structure containing a FILE *
* and a record counter.
* entry (input) entry to get dumped.
* <return value> void
*
* Requires:
* nuttin
*
* Effects:
* writes data to the specified file pointerp.
*
* Modifies:
* nuttin
*
*/
{
char *princstr;
int x, y, foundcrc;
/*
* XXX Currently, lookup_tl_data always returns zero; it sets
* tl_data->tl_data_length to zero if the type isn't found.
* This should be fixed...
*/
/*
* XXX Should this function do nothing for a principal with no
* admin data, or print a record of "default" values? See
* comment in server_kdb.c to help decide.
*/
|| (tl_data.tl_data_length == 0))
return 0;
xdr_destroy(&xdrs);
return(KADM5_XDR_FAILURE);
}
xdr_destroy(&xdrs);
else
for (x = 0; x < adb.old_key_len; x++) {
foundcrc = 0;
continue;
if (foundcrc) {
gettext("Warning! Multiple DES-CBC-CRC "
"keys for principal %s; skipping "
"duplicates.\n"),
princstr);
continue;
}
foundcrc++;
}
if (!foundcrc)
gettext("Warning! No DES-CBC-CRC key "
"for principal %s, cannot generate "
"OV-compatible record; skipping\n"),
princstr);
}
return 0;
}
/*
* usage is:
* dump_db [-i] [-old] [-b6] [-b7] [-ov] [-verbose] [-mkey_convert]
* [-new_mkey_file mkey_file] [-rev] [-recurse]
* [filename [principals...]]
*/
void
int argc;
char **argv;
{
FILE *f;
char *programname;
char *ofile;
int aindex;
char *new_mkey_file = 0;
int db_arg_index = 0;
/*
* Parse the arguments.
*/
programname = argv[0];
dump = &r1_3_version;
new_mkey_file = 0;
mkey_convert = 0;
backwards = 0;
recursive = 0;
/*
* Parse the qualifiers.
*/
dump = &old_version;
dump = &beta6_version;
dump = &beta7_version;
dump = &ov_version;
dump = &iprop_version;
/*
* dump_sno is used to indicate if the serial
* # should be populated in the output
* file to be used later by iprop for updating
* the slave's update log when loading
*/
} else {
exit_status++;
return;
}
}
mkey_convert = 1;
mkey_convert = 1;
/* hack to pass args to db specific plugin */
/* hack to pass args to db specific plugin */
} else
break;
}
aindex++;
}
}
/*
* Make sure the database is open. The policy database only has
* to be opened if we try a dump that uses it.
*/
if (!dbactive) {
exit_status++;
return;
}
/*
* If we're doing a master key conversion, set up for it.
*/
if (mkey_convert) {
if (!valid_master_key) {
/* TRUE here means read the keyboard, but only once */
(char *) NULL, 0,
&master_key);
if (retval) {
gettext("while reading master key"));
exit(1);
}
&master_key);
if (retval) {
gettext("while verifying master key"));
exit(1);
}
}
if (!new_mkey_file)
(new_mkey_file == 0) ?
(krb5_boolean) 1 : 0,
TRUE,
new_mkey_file, 0,
&new_master_key))) {
gettext("while reading new master key"));
exit(1);
}
}
kret = 0;
locked = 0;
/*
* Discourage accidental dumping to filenames beginning with '-'.
*/
if (ofile[0] == '-')
usage();
/*
* Make sure that we don't open and truncate on the fopen,
* since that may hose an on-going kprop process.
*
* We could also control this by opening for read and
* write, doing an flock with LOCK_EX, and then
* truncating the file once we have gotten the lock,
* but that would involve more OS dependencies than I
* want to get into.
*/
exit_status++;
return;
}
fileno(f),
exit_status++;
}
else
locked = 1;
} else {
f = stdout;
}
if (f && !(kret)) {
if (dump_sno) {
exit_status++;
goto error;
}
/*
* We grab the lock twice (once again in the iterator call),
* but that's ok since the lock func handles incr locks held.
*/
exit_status++;
goto error;
}
}
/* don't pass in db_args if there aren't any */
NULL,
(krb5_pointer) &arglist,
exit_status++;
if (dump_sno)
(void) krb5_db_unlock(util_context);
}
if (dump->dump_policy &&
&arglist))) {
exit_status++;
}
if (locked) {
locked = 0;
}
fclose(f);
}
}
if (locked)
}
/*
* Read a string of bytes while counting the number of lines passed.
*/
static int
FILE *f;
char *buf;
int len;
int *lp;
{
int c;
int i, retval;
retval = 0;
for (i=0; i<len; i++) {
c = fgetc(f);
if (c < 0) {
retval = 1;
break;
}
if (c == '\n')
(*lp)++;
buf[i] = (char) c;
}
return(retval);
}
/*
* Read a string of two character representations of bytes.
*/
static int
FILE *f;
int len;
{
int c;
int i, retval;
retval = 0;
for (i=0; i<len; i++) {
retval = 1;
break;
}
buf[i] = (krb5_octet) c;
}
return(retval);
}
/*
* Find the end of an old format record.
*/
static void
FILE *f;
char *fn;
int lineno;
{
int ch;
while (ch != '\n') {
}
}
}
#if 0
/*
* update_tl_data() - Generate the tl_data entries.
*/
static krb5_error_code
{
kret = 0 ;
/*
* Handle modification principal.
*/
if (mod_name) {
&mprinc,
dbentp);
}
}
/*
* Handle last password change.
*/
if (!kret) {
/* Find a previously existing entry */
/* Check to see if we found one. */
linked = 0;
if (!pwchg) {
/* No, allocate a new one */
if (!(pwchg->tl_data_contents =
}
else {
(krb5_int16) sizeof(krb5_timestamp);
}
}
}
else
linked = 1;
/* Do we have an entry? */
/* Encode it */
/* Link it in if necessary */
if (!linked) {
}
}
else
}
return(kret);
}
#endif
/*
* process_k5beta_record() - Handle a dump record in old format.
*
* Returns -1 for end of file, 0 for success and 1 for failure.
*/
static int
char *fname;
int verbose;
int *linenop;
{
int nmatched;
int retval;
char *name;
char *mod_name;
int error;
const char *try2read;
int i;
(*linenop)++;
retval = 1;
/* Make sure we've got key_data entries */
return(1);
}
/*
* Match the sizes. 6 tokens to match.
*/
if (nmatched == 6) {
/*
* Get the memory for the variable length fields.
*/
(!key_len ||
(pkey->key_data_contents[0] =
(!alt_key_len ||
(akey->key_data_contents[0] =
(!salt_len ||
(!alt_salt_len ||
) {
error = 0;
/* Read the principal name */
error++;
}
/* Read the key type */
error++;
}
/* Read the old format key */
pkey->key_data_contents[0],
pkey->key_data_length[0])) {
error++;
}
/* convert to a new format key */
/* the encrypted version is stored as the unencrypted key length
(4 bytes, MSB first) followed by the encrypted key. */
&& (pkey->key_data_contents[0][0] == 0)
/* this really does look like an old key, so drop and swap */
/* the *new* length is 2 bytes, LSB first, sigh. */
if (shortcopy1) {
} else {
error++;
}
}
/* Read principal attributes */
"\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t",
&tmpint3) != 10)) {
error++;
}
/* Read modifier name */
linenop)) {
error++;
}
/* Read second set of attributes */
&tmpint1) != 3)) {
error++;
}
/* Read salt data */
error++;
}
/* Read alternate key type */
error++;
}
/* Read alternate key */
akey->key_data_contents[0],
akey->key_data_length[0])) {
error++;
}
/* convert to a new format key */
/* the encrypted version is stored as the unencrypted key length
(4 bytes, MSB first) followed by the encrypted key. */
&& (akey->key_data_contents[0][0] == 0)
/* this really does look like an old key, so drop and swap */
/* the *new* length is 2 bytes, LSB first, sigh. */
if (shortcopy2) {
} else {
error++;
}
}
/* Read alternate salt type */
error++;
}
/* Read alternate salt data */
error++;
}
/* Read expansion data - discard it */
if (!error) {
for (i=0; i<8; i++) {
error++;
break;
}
}
if (!error)
}
/*
* If no error, then we're done reading. Now parse the names
* and store the database dbent.
*/
if (!error) {
name,
&mod_princ))) {
if (!(kret =
&dbent,
mod_princ)) &&
!(kret =
&dbent,
last_pwd_change))) {
int one = 1;
2 : 1;
2 : 1;
if ((pkey->key_data_type[0] ==
akey->key_data_type[0]) &&
dbent.n_key_data--;
else if ((akey->key_data_type[0] == 0)
&& (akey->key_data_length[0] == 0)
dbent.n_key_data--;
&dbent,
&one)) ||
(one != 1)) {
error++;
}
else {
if (verbose)
name);
retval = 0;
}
}
}
else {
error++;
}
}
else {
error++;
}
}
else {
}
}
else {
}
if (mod_name)
if (name)
}
else {
else
retval = -1;
}
if (shortcopy1)
if (shortcopy2)
return(retval);
}
/*
* process_k5beta6_record() - Handle a dump record in krb5b6 format.
*
* Returns -1 for end of file, 0 for success and 1 for failure.
*/
static int
char *fname;
int verbose;
int *linenop;
{
int retval;
int nread;
int error;
int i, j, one;
char *name;
krb5_octet *op;
const char *try2read;
(*linenop)++;
retval = 1;
error = 0;
kret = 0;
if (nread == 5) {
/* Get memory for flattened principal name */
error++;
/* Get memory for and form tagged data linked list */
for (i=0; i<t3; i++) {
}
else {
error++;
break;
}
}
/* Get memory for key list */
(t4*sizeof(krb5_key_data)))))
error++;
/* Get memory for extra data */
error++;
if (!error) {
if (kp) {
}
if (op) {
}
/* Read in and parse the principal name */
/* Get the fixed principal attributes */
if (nread == 8) {
} else {
error++;
}
/*
* Get the tagged data.
*
* Really, this code ought to discard tl data types
* that it knows are special to the current version
* and were not supported in the previous version.
* But it's a pain to implement that here, and doing
* it at dump time has almost as good an effect, so
* that's what I did. [krb5-admin/89]
*/
if (nread == 2) {
if (tl->tl_data_length) {
if (!(tl->tl_data_contents =
t2)) {
error++;
break;
}
/* test to set mask fields */
if (t1 == KRB5_TL_KADM_DATA) {
/*
* Assuming aux_attributes will always be
* there
*/
/* test for an actual policy reference */
}
xdr_destroy(&xdrs);
}
}
else {
/* Should be a null field */
error++;
break;
}
}
}
else {
error++;
break;
}
}
if (!error)
}
/* Get the key data */
if (nread == 2) {
for (j=0; j<t1; j++) {
if (nread == 2) {
if (t4) {
if (!(kdatap->key_data_contents[j] =
(krb5_octet *)
kdatap->key_data_contents[j],
t4)) {
error++;
break;
}
}
else {
/* Should be a null field */
error++;
break;
}
}
}
else {
error++;
break;
}
}
}
}
if (!error)
}
/* Get the extra data */
if (read_octet_string(filep,
error++;
}
}
else {
error++;
}
}
/* Finally, find the end of the record. */
if (!error)
/*
* We have either read in all the data or choked.
*/
if (!error) {
one = 1;
&dbentry,
&one))) {
}
else {
if (verbose)
name);
retval = 0;
}
}
else {
}
}
else {
if (kret)
else
}
}
else {
}
if (op)
if (kp)
if (name)
}
else {
retval = -1;
}
return(retval);
}
static int
char *fname;
int verbose;
int *linenop;
void *pol_db;
{
char namebuf[1024];
(*linenop)++;
return -1;
else if (nread != 7) {
gettext("cannot parse policy on line %d (%d read)\n"),
return 1;
}
if (ret &&
return 1;
}
}
if (verbose)
return 0;
}
/*
* process_k5beta7_record() - Handle a dump record in krb5b7 format.
*
* Returns -1 for end of file, 0 for success and 1 for failure.
*/
static int
char *fname;
int verbose;
int *linenop;
{
int nread;
char rectype[100];
return -1;
else if (nread != 1)
return 1;
linenop);
linenop);
else {
gettext("unknown record type \"%s\" on line %d\n"),
return 1;
}
return 0;
}
/*
* process_ov_record() - Handle a dump record in OpenV*Secure 1.0 format.
*
* Returns -1 for end of file, 0 for success and 1 for failure.
*/
static int
char *fname;
int verbose;
int *linenop;
{
int nread;
char rectype[100];
return -1;
else if (nread != 1)
return 1;
linenop);
linenop);
return -1;
else {
gettext("unknown record type \"%s\" on line %d\n"),
return 1;
}
return 0;
}
/*
* restore_dump() - Restore the database from any version dump file.
*/
static int
char *programname;
char *dumpfile;
FILE *f;
int verbose;
{
int error;
int lineno;
error = 0;
lineno = 1;
/*
* Process the records.
*/
f,
&lineno)))
;
if (error != -1)
else
error = 0;
return(error);
}
/*
* Usage: load_db [-i] [-old] [-ov] [-b6] [-b7] [-verbose] [-update] [-hash]
* filename
*/
void
int argc;
char **argv;
{
FILE *f;
extern char *optarg;
extern int optind;
char *programname;
char *dumpfile;
char *dbname;
char *dbname_tmp;
int aindex;
char iheader[MAX_HEADER];
int db_locked = 0;
/*
* Parse the arguments.
*/
programname = argv[0];
update = 0;
verbose = 0;
exit_status = 0;
dbname_tmp = (char *) NULL;
load = &old_version;
load = &beta6_version;
load = &beta7_version;
load = &ov_version;
load = &iprop_version;
add_update = FALSE;
} else {
exit_status++;
return;
}
}
verbose = 1;
update = 1;
if (!add_db_arg("hash=true")) {
exit(1);
}
} else
break;
}
usage();
return;
}
exit_status++;
return;
}
/*
* Initialize the Kerberos context and error tables.
*/
exit_status++;
return;
}
{
exit_status++;
return;
}
/*
* Open the dumpfile
*/
if (dumpfile) {
exit_status++;
return;
}
KRB5_LOCKMODE_SHARED))) {
exit_status++;
return;
}
} else
f = stdin;
/*
* Auto-detect dump version if we weren't told, verify if we
* were told.
*/
if (load) {
/* only check what we know; some headers only contain a prefix */
exit_status++;
return;
}
} else {
/* perhaps this should be in an array, but so what? */
load = &old_version;
load = &beta6_version;
load = &beta7_version;
load = &r1_3_version;
load = &ov_version;
else {
exit_status++;
return;
}
}
gettext("%s: dump version %s can only "
"be loaded with the -update flag\n"),
exit_status++;
return;
}
/*
* Cons up params for the new databases. If we are not in update
* mode, we create an alternate database and then promote it to
* be the live db.
*/
if (! update) {
/* Solaris kerberos: using older kadm5_get_config_params interface */
gettext("while retreiving new "
"configuration parameters"));
exit_status++;
return;
}
if (!add_db_arg("temporary")) {
exit(1);
}
}
/*
* If not an update restoration, create the database. otherwise open
*/
if (!update) {
/*
* See if something (like DAL KDB plugin) has set a specific error
* message and use that otherwise use default.
*/
} else {
}
exit_status++;
return;
}
}
else {
/*
* Initialize the database.
*/
/*
* See if something (like DAL KDB plugin) has set a specific
* error message and use that otherwise use default.
*/
} else {
}
exit_status++;
goto error;
}
}
/*
* If an update restoration, make sure the db is left unusable if
* the update fails.
*/
if ((kret = krb5_db_lock(kcontext, update?KRB5_DB_LOCKMODE_PERMANENT: KRB5_DB_LOCKMODE_EXCLUSIVE))) {
/*
* Ignore a not supported error since there is nothing to do about it
* anyway.
*/
if (kret != KRB5_PLUGIN_OP_NOTSUPP) {
exit_status++;
goto error;
}
}
else
db_locked = 1;
if (add_update)
else
gettext("%s: Could not map log\n"),
exit_status++;
goto error;
}
/*
* We don't want to take out the ulog out from underneath
* kadmind so we reinit the header log.
*
* We also don't want to add to the update log since we
* are doing a whole sale replace of the db, because:
* we could easily exceed # of update entries
* we could implicity delete db entries during a replace
* no advantage in incr updates when entire db is replaced
*/
if (!update) {
if (!add_update) {
}
}
}
exit_status++;
}
/* error message printed by create_magic_princs */
exit_status++;
}
/* change this error? */
exit_status++;
}
#if 0
exit_status++;
}
#endif
/* close policy db below */
if (exit_status == 0 && !update) {
/*
* Ignore a not supported error since there is nothing to do about it
* anyway.
*/
exit_status++;
}
}
/*
* If not an update: if there was an error, destroy the temp database,
* otherwise rename it into place.
*
* If an update: if there was no error, unlock the database.
*/
if (!update) {
if (exit_status) {
/*
* Ignore a not supported error since there is nothing to do about
* it anyway.
*/
exit_status++;
}
}
}
if (dumpfile) {
fclose(f);
}
if (dbname_tmp)
}