Udiff dump.c
--- /net/etna.eng/build7/semery/mit2/webrev/usr/src/cmd/krb5/kadmin/dbutil/dump.c- Wed Sep 8 16:59:46 2004
+++ dump.c Wed Sep 8 13:41:04 2004
@@ -1,11 +1,11 @@
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "@(#)dump.c 1.9 04/09/08 SMI"
+#pragma ident "@(#)dump.c 1.8 04/05/04 SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
* Openvision retains the copyright to derivative works of
@@ -124,13 +124,19 @@
PROTOTYPE((krb5_pointer,
krb5_db_entry *));
static krb5_error_code dump_k5beta6_iterator
PROTOTYPE((krb5_pointer,
krb5_db_entry *));
+static krb5_error_code dump_iprop_iterator
+PROTOTYPE((krb5_pointer,
+ krb5_db_entry *));
static krb5_error_code dump_k5beta7_princ
PROTOTYPE((krb5_pointer,
krb5_db_entry *));
+static krb5_error_code dump_iprop_princ
+PROTOTYPE((krb5_pointer,
+ krb5_db_entry *));
static krb5_error_code dump_ov_princ
PROTOTYPE((krb5_pointer,
krb5_db_entry *));
static void dump_k5beta7_policy PROTOTYPE((void *, osa_policy_ent_t));
@@ -189,10 +195,19 @@
0,
dump_k5beta7_princ,
dump_k5beta7_policy,
process_k5beta7_record,
};
+dump_version iprop_version = {
+ "Kerberos iprop version",
+ "iprop",
+ 0,
+ 0,
+ dump_iprop_princ,
+ dump_k5beta7_policy,
+ process_k5beta7_record,
+};
dump_version ov_version = {
"OpenV*Secure V1.0",
"OpenV*Secure V1.0\t",
1,
1,
@@ -352,10 +367,11 @@
*/
#undef gettext
static const char oldoption[] = "-old";
static const char b6option[] = "-b6";
+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[] = "~";
@@ -953,12 +969,168 @@
}
}
krb5_xfree(name);
return(retval);
}
+/*
+ * dump_iprop_iterator() - Output a dump record in iprop format.
+ */
+static krb5_error_code
+dump_iprop_iterator(ptr, entry)
+ krb5_pointer ptr;
+ krb5_db_entry *entry;
+{
+ krb5_error_code retval;
+ struct dump_args *arg;
+ char *name;
+ krb5_tl_data *tlp;
+ krb5_key_data *kdata;
+ int counter, i, j;
+ /* Initialize */
+ arg = (struct dump_args *) ptr;
+ name = (char *) NULL;
+
/*
+ * Flatten the principal name.
+ */
+ if ((retval = krb5_unparse_name(arg->kcontext,
+ entry->princ,
+ &name))) {
+ fprintf(stderr, gettext(pname_unp_err),
+ arg->programname, error_message(retval));
+ return(retval);
+ }
+
+ /*
+ * Re-encode the keys in the new master key, if necessary.
+ */
+ if (mkey_convert) {
+ retval = master_key_convert(arg->kcontext, entry);
+ if (retval) {
+ com_err(arg->programname, retval, remaster_err_fmt, 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.
+ */
+ if (!arg->nnames || name_matches(name, arg)) {
+ /*
+ * 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;
+ for (tlp = entry->tl_data; tlp; tlp = tlp->tl_data_next)
+ counter++;
+
+ if (counter == entry->n_tl_data) {
+ /* Pound out header */
+ fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%s\t",
+ (int) entry->len,
+ strlen(name),
+ (int) entry->n_tl_data,
+ (int) entry->n_key_data,
+ (int) entry->e_length,
+ name);
+ fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t",
+ entry->attributes,
+ entry->max_life,
+ entry->max_renewable_life,
+ entry->expiration,
+ entry->pw_expiration,
+ entry->last_success,
+ entry->last_failed,
+ entry->fail_auth_count);
+ /* Pound out tagged data. */
+ for (tlp = entry->tl_data; tlp;
+ tlp = tlp->tl_data_next) {
+ fprintf(arg->ofile, "%d\t%d\t",
+ (int) tlp->tl_data_type,
+ (int) tlp->tl_data_length);
+ if (tlp->tl_data_length)
+ for (i = 0;
+ i < tlp->tl_data_length;
+ i++)
+ fprintf(arg->ofile, "%02x",
+ tlp->
+ tl_data_contents[i]);
+ else
+ fprintf(arg->ofile, "%d", -1);
+ fprintf(arg->ofile, "\t");
+ }
+
+ /* Pound out key data */
+ for (counter = 0;
+ counter < entry->n_key_data; counter++) {
+ kdata = &entry->key_data[counter];
+ fprintf(arg->ofile, "%d\t%d\t",
+ (int) kdata->key_data_ver,
+ (int) kdata->key_data_kvno);
+ for (i=0; i<kdata->key_data_ver; i++) {
+ fprintf(arg->ofile, "%d\t%d\t",
+ 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++)
+ fprintf(arg->ofile,
+ "%02x",
+ kdata->
+ key_data_contents
+ [i][j]);
+ else
+ fprintf(arg->ofile, "%d", -1);
+ fprintf(arg->ofile, "\t");
+ }
+ }
+
+ /* Pound out extra data */
+ if (entry->e_length)
+ for (i=0; i<entry->e_length; i++)
+ fprintf(arg->ofile, "%02x",
+ entry->e_data[i]);
+ else
+ fprintf(arg->ofile, "%d", -1);
+
+ /* Print trailer */
+ fprintf(arg->ofile, ";\n");
+
+ if (arg->verbose)
+ fprintf(stderr, "%s\n", name);
+ } else {
+ fprintf(stderr, gettext(sdump_tl_inc_err),
+ arg->programname, name, counter,
+ (int) entry->n_tl_data);
+ retval = EINVAL;
+ }
+ }
+ krb5_xfree(name);
+ return(retval);
+}
+
+/*
* dump_k5beta7_iterator() - Output a dump record in krb5b7 format.
*/
static krb5_error_code
dump_k5beta7_princ(ptr, entry)
krb5_pointer ptr;
@@ -998,10 +1170,54 @@
}
free(name);
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
+dump_iprop_princ(ptr, entry)
+ krb5_pointer ptr;
+ krb5_db_entry *entry;
+{
+ krb5_error_code retval;
+ struct dump_args *arg;
+ char *name;
+ int tmp_nnames;
+
+ /* Initialize */
+ arg = (struct dump_args *) ptr;
+ name = (char *) NULL;
+
+ /*
+ * Flatten the principal name.
+ */
+ if ((retval = krb5_unparse_name(arg->kcontext,
+ entry->princ,
+ &name))) {
+ fprintf(stderr, gettext(pname_unp_err),
+ arg->programname, error_message(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.
+ */
+ if (!arg->nnames || name_matches(name, arg)) {
+ fprintf(arg->ofile, "princ\t");
+
+ /* save the callee from matching the name again */
+ tmp_nnames = arg->nnames;
+ arg->nnames = 0;
+ retval = dump_iprop_iterator(ptr, entry);
+ arg->nnames = tmp_nnames;
+ }
+ free(name);
+ return (retval);
+}
void
dump_k5beta7_policy(void *data, osa_policy_ent_t entry)
{
struct dump_args *arg;
@@ -1142,10 +1358,12 @@
dump_version *dump;
int aindex;
krb5_boolean locked;
extern osa_adb_policy_t policy_db;
char *new_mkey_file = 0;
+ bool_t dump_sno = FALSE;
+ kdb_log_context *log_ctx;
/*
* Parse the arguments.
*/
programname = argv[0];
@@ -1155,10 +1373,11 @@
error = 0;
dump = &beta7_version;
arglist.verbose = 0;
new_mkey_file = 0;
mkey_convert = 0;
+ log_ctx = util_context->kdblog_context;
/*
* Parse the qualifiers.
*/
for (aindex = 1; aindex < argc; aindex++) {
@@ -1166,10 +1385,26 @@
dump = &old_version;
else if (strcmp(argv[aindex], b6option) == 0)
dump = &beta6_version;
else if (strcmp(argv[aindex], ovoption) == 0)
dump = &ov_version;
+ else if (!strcmp(argv[aindex], ipropoption)) {
+ if (log_ctx && log_ctx->iproprole) {
+ 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
+ */
+ dump_sno = TRUE;
+ } else {
+ fprintf(stderr, gettext("Iprop not enabled\n"));
+ exit_status++;
+ return;
+ }
+ }
else if (strcmp(argv[aindex], verboseoption) == 0)
arglist.verbose++;
else if (!strcmp(argv[aindex], "-mkey_convert"))
mkey_convert = 1;
else if (!strcmp(argv[aindex], "-new_mkey_file")) {
@@ -1274,19 +1509,45 @@
arglist.programname = programname;
arglist.ofile = f;
arglist.kcontext = util_context;
fprintf(arglist.ofile, "%s", dump->header);
+ if (dump_sno) {
+ if (ulog_map(util_context, &global_params, FKCOMMAND)) {
+ fprintf(stderr,
+ gettext("%s: Could not map log\n"), programname);
+ 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.
+ */
+ if (krb5_db_lock(util_context, KRB5_LOCKMODE_SHARED)) {
+ fprintf(stderr,
+ gettext("%s: Couldn't grab lock\n"), programname);
+ exit_status++;
+ goto error;
+ }
+
+ fprintf(f, " %u", log_ctx->ulog->kdb_last_sno);
+ fprintf(f, " %u", log_ctx->ulog->kdb_last_time.seconds);
+ fprintf(f, " %u", log_ctx->ulog->kdb_last_time.useconds);
+ }
+
if (dump->header[strlen(dump->header)-1] != '\n')
fputc('\n', arglist.ofile);
if ((kret = krb5_dbm_db_iterate(util_context,
dump->dump_princ,
(krb5_pointer) &arglist))) {
fprintf(stderr, gettext(dumprec_err),
programname, dump->name, error_message(kret));
exit_status++;
+ if (dump_sno)
+ (void) krb5_db_unlock(util_context);
}
if (dump->dump_policy &&
(kret = osa_adb_iter_policy(policy_db, dump->dump_policy,
&arglist))) {
fprintf(stderr, gettext(dumprec_err),
@@ -2318,11 +2579,13 @@
dump_version *load;
int update, verbose;
krb5_int32 crflags;
int aindex;
bool_t add_update = TRUE;
+ char iheader[MAX_HEADER];
uint32_t caller, last_sno, last_seconds, last_useconds;
+ kdb_log_context *log_ctx;
/*
* Parse the arguments.
*/
programname = argv[0];
@@ -2335,17 +2598,28 @@
verbose = 0;
crflags = KRB5_KDB_CREATE_BTREE;
exit_status = 0;
dbname_tmp = (char *) NULL;
tmppol_db = NULL;
+ log_ctx = util_context->kdblog_context;
+
for (aindex = 1; aindex < argc; aindex++) {
if (strcmp(argv[aindex], oldoption) == 0)
load = &old_version;
else if (strcmp(argv[aindex], b6option) == 0)
load = &beta6_version;
else if (strcmp(argv[aindex], ovoption) == 0)
load = &ov_version;
+ else if (!strcmp(argv[aindex], ipropoption)) {
+ if (log_ctx && log_ctx->iproprole) {
+ load = &iprop_version;
+ add_update = FALSE;
+ } else {
+ fprintf(stderr, gettext("Iprop not enabled\n"));
+ exit_status++;
+ return;
+ }
} else if (strcmp(argv[aindex], verboseoption) == 0)
verbose = 1;
else if (strcmp(argv[aindex], updateoption) == 0)
update = 1;
else if (!strcmp(argv[aindex], hashoption))
@@ -2375,10 +2649,14 @@
fprintf(stderr, gettext(ctx_err_fmt), programname);
free(dbname_tmp);
exit_status++;
return;
}
+
+ if (log_ctx && log_ctx->iproprole)
+ kcontext->kdblog_context = (void *)log_ctx;
+
/*
* Open the dumpfile
*/
if (dumpfile) {
if ((f = fopen(dumpfile, "r+")) == NULL) {
@@ -2538,10 +2816,57 @@
programname, error_message(kret));
exit_status++;
goto error;
}
}
+
+ if (log_ctx && log_ctx->iproprole) {
+ if (add_update)
+ caller = FKCOMMAND;
+ else
+ caller = FKPROPD;
+
+ if (ulog_map(kcontext, &global_params, caller)) {
+ fprintf(stderr,
+ gettext("%s: Could not map log\n"),
+ programname);
+ 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) {
+ memset(log_ctx->ulog, 0, sizeof (kdb_hlog_t));
+
+ log_ctx->ulog->kdb_hmagic = KDB_HMAGIC;
+ log_ctx->ulog->db_version_num = KDB_VERSION;
+ log_ctx->ulog->kdb_state = KDB_STABLE;
+ log_ctx->ulog->kdb_block = ULOG_BLOCK;
+
+ log_ctx->iproprole = IPROP_NULL;
+
+ if (!add_update) {
+ sscanf(buf, "%s %u %u %u", iheader, &last_sno,
+ &last_seconds, &last_useconds);
+
+ log_ctx->ulog->kdb_last_sno = last_sno;
+ log_ctx->ulog->kdb_last_time.seconds =
+ last_seconds;
+ log_ctx->ulog->kdb_last_time.useconds =
+ last_useconds;
+ }
+ }
+ }
if (restore_dump(programname, kcontext,
(dumpfile) ? dumpfile : stdin_name,
f, verbose, load, tmppol_db)) {
fprintf(stderr, gettext(restfail_fmt),