summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBarry Jaspan <bjaspan@mit.edu>1996-08-01 18:39:54 +0000
committerBarry Jaspan <bjaspan@mit.edu>1996-08-01 18:39:54 +0000
commita1c27c428f327f07e7685211da432ee4aa454e78 (patch)
treec3e10f272644daf8ebae532226d12e62c49a8f1e /src
parent173ff1359701936021151119c67c4f69d3bb8ac9 (diff)
* Makefile.in, Makefile.ov, configure.in, dump.c: add support for
dump/load of OV*Secure-compatible format. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@8889 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/kadmin/dbutil/ChangeLog5
-rw-r--r--src/kadmin/dbutil/Makefile.in11
-rw-r--r--src/kadmin/dbutil/Makefile.ov10
-rw-r--r--src/kadmin/dbutil/configure.in1
-rw-r--r--src/kadmin/dbutil/dump.c283
-rw-r--r--src/kadmin/dbutil/import_err.et26
-rw-r--r--src/kadmin/dbutil/ovload.c207
-rw-r--r--src/kadmin/dbutil/strtok.c125
8 files changed, 632 insertions, 36 deletions
diff --git a/src/kadmin/dbutil/ChangeLog b/src/kadmin/dbutil/ChangeLog
index e870b8485..8c8aa4ce2 100644
--- a/src/kadmin/dbutil/ChangeLog
+++ b/src/kadmin/dbutil/ChangeLog
@@ -1,3 +1,8 @@
+Thu Aug 1 14:34:51 1996 Barry Jaspan <bjaspan@DUN-DUN-NOODLES>
+
+ * Makefile.in, Makefile.ov, configure.in, dump.c: add support for
+ dump/load of OV*Secure-compatible format.
+
Wed Jul 31 14:55:38 1996 Tom Yu <tlyu@mit.edu>
* kdb5_stash.c (kdb5_stash): Declare optind.
diff --git a/src/kadmin/dbutil/Makefile.in b/src/kadmin/dbutil/Makefile.in
index 30c19894c..c6325fd1e 100644
--- a/src/kadmin/dbutil/Makefile.in
+++ b/src/kadmin/dbutil/Makefile.in
@@ -1,10 +1,9 @@
-CFLAGS = $(CCOPTS) $(DEFS) -DKDB4_DISABLE $(LOCALINCLUDE) @KRB4_INCLUDES@
+CFLAGS = $(CCOPTS) $(DEFS) -DKDB4_DISABLE -I. $(LOCALINCLUDE) @KRB4_INCLUDES@
PROG = kdb5_util
-OBJS = kdb5_create.o kadm5_create.o string_table.o
OBJS = kdb5_util.o kdb5_util_ct.o dump.o dumpv4.o loadv4.o ss_wrapper.o \
kdb5_create.o kadm5_create.o string_table.o kdb5_stash.o \
- kdb5_destroy.o
+ kdb5_destroy.o ovload.o import_err.o strtok.o
all:: $(PROG)
@@ -13,8 +12,12 @@ $(PROG): $(OBJS) $(DEPLIBS)
kdb5_util_ct.o: kdb5_util_ct.c
+import_err.c import_err.h: $(srcdir)/import_err.et
+
+$(OBJS): import_err.h
+
install::
$(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(ADMIN_BINDIR)/$(PROG)
clean::
- $(RM) $(PROG) $(OBJS)
+ $(RM) $(PROG) $(OBJS) import_err.c import_err.h
diff --git a/src/kadmin/dbutil/Makefile.ov b/src/kadmin/dbutil/Makefile.ov
index f762282f2..c314aa2b1 100644
--- a/src/kadmin/dbutil/Makefile.ov
+++ b/src/kadmin/dbutil/Makefile.ov
@@ -6,14 +6,14 @@ CFLAGS += -I$(TOP)/../include/kerberosIV
PROG = kdb5_util
SRCS = kdb5_util.c kdb5_util_ct.c dump.c ss_wrapper.c dumpv4.c loadv4.c \
kdb5_create.c kadm5_create.c string_table.c kdb5_stash.c \
- kdb5_destroy.c
+ kdb5_destroy.c ovload.c strtok.c
OBJS = kdb5_util.o kdb5_util_ct.o dump.o dumpv4.o loadv4.o ss_wrapper.o \
kdb5_create.o kadm5_create.o string_table.o kdb5_stash.o \
- kdb5_destroy.o
-ETABLES = kdb5_util_ct.ct
+ kdb5_destroy.o ovload.o import_err.o strtok.o
+ETABLES = import_err.et
-LIBS = $(LIBADMSRV) $(LIBKDB5) $(LIBKRB5_ALL) $(LIBRPCLIB) $(LIBDYN) \
- $(LIBSS) $(LIBDB)
+LIBS = $(LIBADMSRV) $(LIBKDB5) $(LIBDES425) $(LIBKRB5_ALL) \
+ $(LIBRPCLIB) $(LIBDYN) $(LIBSS) $(LIBDB) $(NETLIB)
expand NormalProgram
expand ErrorTables
diff --git a/src/kadmin/dbutil/configure.in b/src/kadmin/dbutil/configure.in
index c9234524e..66edf685f 100644
--- a/src/kadmin/dbutil/configure.in
+++ b/src/kadmin/dbutil/configure.in
@@ -2,6 +2,7 @@ AC_INIT(kdb5_create.c)
CONFIG_RULES
WITH_KRB4
AC_PROG_INSTALL
+AC_PROG_AWK
USE_KADMSRV_LIBRARY
USE_GSSRPC_LIBRARY
USE_KDB5_LIBRARY
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
index 8bd54ca4d..29bda177a 100644
--- a/src/kadmin/dbutil/dump.c
+++ b/src/kadmin/dbutil/dump.c
@@ -63,6 +63,8 @@ static krb5_error_code dump_k5beta6_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_ov_princ PROTOTYPE((krb5_pointer,
+ krb5_db_entry *));
static void dump_k5beta7_policy PROTOTYPE((void *, osa_policy_ent_t));
typedef krb5_error_code (*dump_func)PROTOTYPE((krb5_pointer,
@@ -74,12 +76,15 @@ static int process_k5beta6_record PROTOTYPE((char *, krb5_context,
FILE *, int, int *, void *));
static int process_k5beta7_record PROTOTYPE((char *, krb5_context,
FILE *, int, int *, void *));
+static int process_ov_record PROTOTYPE((char *, krb5_context,
+ FILE *, int, int *, void *));
typedef krb5_error_code (*load_func)PROTOTYPE((char *, krb5_context,
FILE *, int, int *, void *));
typedef struct _dump_version {
char *name;
char *header;
+ int updateonly;
dump_func dump_princ;
osa_adb_iter_policy_func dump_policy;
load_func load_record;
@@ -88,6 +93,7 @@ typedef struct _dump_version {
dump_version old_version = {
"Kerberos version 5 old format",
"kdb5_edit load_dump version 2.0\n",
+ 0,
dump_k5beta_iterator,
NULL,
process_k5beta_record,
@@ -95,6 +101,7 @@ dump_version old_version = {
dump_version beta6_version = {
"Kerberos version 5 beta 6 format",
"kdb5_edit load_dump version 3.0\n",
+ 0,
dump_k5beta6_iterator,
NULL,
process_k5beta6_record,
@@ -102,10 +109,19 @@ dump_version beta6_version = {
dump_version beta7_version = {
"Kerberos version 5",
"kdb5_util load_dump version 4\n",
+ 0,
dump_k5beta7_princ,
dump_k5beta7_policy,
process_k5beta7_record,
};
+dump_version ov_version = {
+ "OpenV*Secure V1.0",
+ "OpenV*Secure V1.0\t",
+ 1,
+ dump_ov_princ,
+ dump_k5beta7_policy,
+ process_ov_record,
+};
/* External data */
extern char *current_dbname;
@@ -186,6 +202,7 @@ static const char oldoption[] = "-old";
static const char b6option[] = "-b6";
static const char verboseoption[] = "-verbose";
static const char updateoption[] = "-update";
+static const char ovoption[] = "-ov";
static const char dump_tmptrail[] = "~";
/*
@@ -722,9 +739,115 @@ void dump_k5beta7_policy(void *data, osa_policy_ent_t entry)
entry->policy_refcnt);
}
+void print_key_data(FILE *f, krb5_key_data *key_data)
+{
+ int c;
+
+ fprintf(f, "%d\t%d\t", key_data->key_data_type[0],
+ 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
+ *
+ */
+static krb5_error_code dump_ov_princ(krb5_pointer ptr, krb5_db_entry *kdb)
+{
+ char *princstr;
+ int x, y, foundcrc, ret;
+ struct dump_args *arg;
+ krb5_tl_data tl_data;
+ osa_princ_ent_rec adb;
+ XDR xdrs;
+
+ arg = (struct dump_args *) ptr;
+ /*
+ * 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_type = KRB5_TL_KADM_DATA;
+ if ((ret = krb5_dbe_lookup_tl_data(arg->kcontext, kdb, &tl_data))
+ || (tl_data.tl_data_length == 0))
+ return 0;
+
+ memset(&adb, 0, sizeof(adb));
+ xdrmem_create(&xdrs, tl_data.tl_data_contents,
+ tl_data.tl_data_length, XDR_DECODE);
+ if (! xdr_osa_princ_ent_rec(&xdrs, &adb)) {
+ xdr_destroy(&xdrs);
+ return(OSA_ADB_XDR_FAILURE);
+ }
+ xdr_destroy(&xdrs);
+
+ krb5_unparse_name(arg->kcontext, kdb->princ, &princstr);
+ fprintf(arg->ofile, "princ\t%s\t", princstr);
+ if(adb.policy == NULL)
+ fputc('\t', arg->ofile);
+ else
+ fprintf(arg->ofile, "%s\t", adb.policy);
+ fprintf(arg->ofile, "%x\t%d\t%d\t%d", adb.aux_attributes,
+ adb.old_key_len,adb.old_key_next, adb.admin_history_kvno);
+
+ for (x = 0; x < adb.old_key_len; x++) {
+ foundcrc = 0;
+ for (y = 0; y < adb.old_keys[x].n_key_data; y++) {
+ krb5_key_data *key_data = &adb.old_keys[x].key_data[y];
+
+ if (key_data->key_data_type[0] != ENCTYPE_DES_CBC_CRC)
+ continue;
+ if (foundcrc) {
+ fprintf(stderr, "Warning! Multiple DES-CBC-CRC keys "
+ "for principal %s; skipping duplicates.\n",
+ princstr);
+ continue;
+ }
+ foundcrc++;
+
+ fputc('\t', arg->ofile);
+ print_key_data(arg->ofile, key_data);
+ }
+ if (!foundcrc)
+ fprintf(stderr, "Warning! No DES-CBC-CRC key for principal "
+ "%s, cannot generate OV-compatible record; skipping\n",
+ princstr);
+ }
+
+ fputc('\n', arg->ofile);
+ free(princstr);
+ return 0;
+}
+
/*
* usage is:
- * dump_db [-old] [-b6] [-verbose] [filename [principals...]]
+ * dump_db [-old] [-b6] [-ov] [-verbose] [filename [principals...]]
*/
void
dump_db(argc, argv)
@@ -761,6 +884,8 @@ dump_db(argc, argv)
dump = &old_version;
else if (!strcmp(argv[aindex], b6option))
dump = &beta6_version;
+ else if (!strcmp(argv[aindex], ovoption))
+ dump = &ov_version;
else if (!strcmp(argv[aindex], verboseoption))
arglist.verbose++;
else
@@ -824,6 +949,9 @@ dump_db(argc, argv)
arglist.ofile = f;
arglist.kcontext = util_context;
fprintf(arglist.ofile, "%s", dump->header);
+ if (dump->header[strlen(dump->header)-1] != '\n')
+ fputc('\n', arglist.ofile);
+
if ((kret = krb5_db_iterate(util_context,
dump->dump_princ,
(krb5_pointer) &arglist))) {
@@ -1588,9 +1716,12 @@ int process_k5beta7_policy(fname, kcontext, filep, verbose, linenop, pol_db)
}
if (ret = osa_adb_create_policy(pol_db, &rec)) {
- fprintf(stderr, "cannot create policy on line %d: %s\n",
- *linenop, error_message(ret));
- return 1;
+ if (ret == OSA_ADB_DUP &&
+ (ret = osa_adb_put_policy(pol_db, &rec))) {
+ fprintf(stderr, "cannot create policy on line %d: %s\n",
+ *linenop, error_message(ret));
+ return 1;
+ }
}
if (verbose)
fprintf(stderr, "created policy %s\n", rec.name);
@@ -1598,7 +1729,6 @@ int process_k5beta7_policy(fname, kcontext, filep, verbose, linenop, pol_db)
return 0;
}
-
/*
* process_k5beta7_record() - Handle a dump record in krb5b6 format.
*
@@ -1637,6 +1767,45 @@ process_k5beta7_record(fname, kcontext, filep, verbose, linenop, pol_db)
}
/*
+ * 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
+process_ov_record(fname, kcontext, filep, verbose, linenop, pol_db)
+ char *fname;
+ krb5_context kcontext;
+ FILE *filep;
+ int verbose;
+ int *linenop;
+ void *pol_db;
+{
+ int nread;
+ char rectype[100];
+
+ nread = fscanf(filep, "%100s\t", rectype);
+ if (nread == EOF)
+ return -1;
+ else if (nread != 1)
+ return 1;
+ if (strcmp(rectype, "princ") == 0)
+ process_ov_principal(fname, kcontext, filep, verbose,
+ linenop, pol_db);
+ else if (strcmp(rectype, "policy") == 0)
+ process_k5beta7_policy(fname, kcontext, filep, verbose,
+ linenop, pol_db);
+ else if (strcmp(rectype, "End") == 0)
+ return -1;
+ else {
+ fprintf(stderr, "unknown record type \"%s\" on line %d\n",
+ rectype, *linenop);
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
* restore_dump() - Restore the database from any version dump file.
*/
static int
@@ -1710,7 +1879,8 @@ load_db(argc, argv)
update = 0;
verbose = 0;
exit_status = 0;
- dbname_tmp = (char *) NULL;
+ adbname_real = dbname_tmp = (char *) NULL;
+ pol_db = NULL;
for (aindex = 1; aindex < argc; aindex++) {
if (!strcmp(argv[aindex], oldoption))
load = &old_version;
@@ -1778,7 +1948,12 @@ load_db(argc, argv)
*/
fgets(buf, sizeof(buf), f);
if (load) {
- if (strcmp(buf, load->header) != 0) {
+ /*
+ * If the header does not end in null, only check what we know.
+ */
+ if ((load->header[strlen(load->header)-1] != '\n' &&
+ strncmp(buf, load->header, strlen(load->header)) != 0) ||
+ (strcmp(buf, load->header) != 0)) {
fprintf(stderr, head_bad_fmt, programname, dumpfile);
exit_status++;
if (dumpfile) fclose(f);
@@ -1792,6 +1967,9 @@ load_db(argc, argv)
load = &beta6_version;
else if (strcmp(buf, beta7_version.header) == 0)
load = &beta7_version;
+ else if (strncmp(buf, ov_version.header,
+ strlen(ov_version.header)) == 0)
+ load = &ov_version;
else {
fprintf(stderr, head_bad_fmt, programname, dumpfile);
exit_status++;
@@ -1799,20 +1977,26 @@ load_db(argc, argv)
return;
}
- if (load != &beta7_version && adbname != NULL) {
+ if (load->dump_policy == NULL && adbname != NULL) {
fprintf(stderr, lusage_err_fmt, argv[0], argv[0],
oldoption, verboseoption, updateoption);
exit_status++;
return;
}
}
+ if (load->updateonly && !update) {
+ fprintf(stderr, "%s: dump version %s can only be loaded in "
+ "update mode\n", programname, load->name);
+ exit_status++;
+ return;
+ }
/*
- * Cons up config params for new policy database. Use adbname is
+ * Cons up config params for new policy database. Use adbname if
* specified, otherwise let the policy dbname key off the dbname.
- * However, after the name is retrieved, change the actual file
- * name to a temp name that we'll rename later (but use the
- * correct lock file).
+ * However, after the name is retrieved, if we are not in update
+ * mode change the actual file name to a temp name that we'll
+ * rename later (but use the correct lock file).
*/
newparams = global_params;
newparams.mask &= ~(KADM5_CONFIG_ADBNAME | KADM5_CONFIG_ADB_LOCKFILE);
@@ -1831,13 +2015,15 @@ load_db(argc, argv)
return;
}
adbname_real = newparams.admin_dbname;
- newparams.admin_dbname = (char *) malloc(strlen(adbname_real) +
- strlen(dump_tmptrail) + 1);
- strcpy(newparams.admin_dbname, adbname_real);
- strcat(newparams.admin_dbname, dump_tmptrail);
+ if (! update) {
+ newparams.admin_dbname = (char *) malloc(strlen(adbname_real) +
+ strlen(dump_tmptrail) + 1);
+ strcpy(newparams.admin_dbname, adbname_real);
+ strcat(newparams.admin_dbname, dump_tmptrail);
+ }
/*
- * Create the new database if not an update restoration. Always
+ * If not an update restoration, create the new database. Always
* create the policy db, even if we are not loading a dump file
* with policy info, because they may be loading an old dump
* intending to use it with the new kadm5 system (ie: using load
@@ -1876,7 +2062,19 @@ load_db(argc, argv)
exit_status++;
goto error;
}
-
+ /*
+ * If an update restoration, make sure the db is left unusable if
+ * the update fails.
+ */
+ if (update) {
+ if (kret = osa_adb_get_lock(pol_db, OSA_ADB_PERMANENT)) {
+ fprintf(stderr, "%s: %s while permanently locking database\n",
+ programname, error_message(kret));
+ exit_status++;
+ goto error;
+ }
+ }
+
/*
* Initialize the database.
*/
@@ -1894,8 +2092,7 @@ load_db(argc, argv)
exit_status++;
}
- if ((kret = krb5_db_fini(kcontext)) ||
- (kret = osa_adb_close_policy(pol_db))) {
+ if (kret = krb5_db_fini(kcontext)) {
fprintf(stderr, close_err_fmt,
programname, error_message(kret));
exit_status++;
@@ -1903,8 +2100,10 @@ load_db(argc, argv)
error:
/*
- * If there was an error and this is not an update, then
- * destroy the database.
+ * If not an update: if there was an error, destroy the database,
+ * otherwise rename it into place.
+ *
+ * If an update: if there was no error, unlock the database.
*/
if (!update) {
if (exit_status) {
@@ -1913,6 +2112,11 @@ error:
programname, dbname_tmp, error_message(kret));
exit_status++;
}
+ if (kret = osa_adb_destroy_policy_db(&newparams)) {
+ fprintf(stderr, "%s: %s while destroying policy database\n",
+ programname, error_message(kret));
+ exit_status++;
+ }
}
else {
if ((kret = krb5_db_rename(kcontext,
@@ -1942,16 +2146,41 @@ error:
exit_status++;
}
}
+ } else /* update */ {
+ if (! exit_status && (kret = osa_adb_release_lock(pol_db))) {
+ fprintf(stderr, "%s: %s while releasing permanent lock\n",
+ programname, error_message(kret));
+ exit_status++;
+ }
}
-
+
+ /*
+ * Don't close this database until here because of permanent lock
+ * handling above. However, always close it even in case of
+ * error, so that the refcnt for an acquired permanent lock that
+ * is not released due to an error is decremented, thus ensuring
+ * that a subsequent attempt to get a lock in the same process
+ * fails.
+ */
+ if(pol_db && (kret = osa_adb_close_policy(pol_db))) {
+ fprintf(stderr, close_err_fmt,
+ programname, error_message(kret));
+ exit_status++;
+ }
+
if (dumpfile) {
(void) krb5_lock_file(kcontext, fileno(f), KRB5_LOCKMODE_UNLOCK);
fclose(f);
}
- free(newparams.admin_dbname);
- newparams.admin_dbname = adbname_real;
- kadm5_free_config_params(kcontext, &newparams);
- free(dbname_tmp);
+ if (adbname_real) {
+ if (adbname_real != newparams.admin_dbname) {
+ free(newparams.admin_dbname);
+ newparams.admin_dbname = adbname_real;
+ }
+ kadm5_free_config_params(kcontext, &newparams);
+ }
+ if (dbname_tmp)
+ free(dbname_tmp);
krb5_free_context(kcontext);
}
diff --git a/src/kadmin/dbutil/import_err.et b/src/kadmin/dbutil/import_err.et
new file mode 100644
index 000000000..e091fe33c
--- /dev/null
+++ b/src/kadmin/dbutil/import_err.et
@@ -0,0 +1,26 @@
+error_table imp
+error_code IMPORT_NO_ERR, "Successfully imported %d record%s.\n"
+error_code IMPORT_BAD_FILE, "Input not recognized as database dump"
+error_code IMPORT_BAD_TOKEN, "Bad token in dump file."
+error_code IMPORT_BAD_VERSION, "Bad version in dump file"
+error_code IMPORT_BAD_RECORD, "Defective record encountered: "
+error_code IMPORT_BAD_FOOTER, "Truncated input file detected."
+error_code IMPORT_FAILED, "Import of dump failed"
+error_code IMPORT_COUNT_MESSAGE, "Mismatched record count: %d record%s indicated, %d record%s scanned.\n"
+error_code IMPORT_MISMATCH_COUNT, "Number of records imported does not match count"
+error_code IMPORT_UNK_OPTION, "Unknown command line option.\nUsage: ovsec_adm_import [filename]"
+error_code IMPORT_WARN_DB, "Warning -- continuing to import will overwrite existing databases!"
+error_code IMPORT_RENAME_FAILED, "Database rename Failed!!"
+error_code IMPORT_EXTRA_DATA, "Extra data after footer is ignored."
+error_code IMPORT_CONFIRM, "Proceed <y|n>?"
+error_code IMPORT_OPEN_DUMP, "while opening input file"
+error_code IMPORT_IMPORT, "while importing databases"
+error_code IMPORT_TTY, "cannot open /dev/tty!!"
+error_code IMPORT_RENAME_OPEN, "while opening databases"
+error_code IMPORT_RENAME_LOCK, "while acquiring permanent lock"
+error_code IMPORT_RENAME_UNLOCK, "while releasing permanent lock"
+error_code IMPORT_RENAME_CLOSE, "while closing databases"
+error_code IMPORT_SINGLE_RECORD, ""
+error_code IMPORT_PLURAL_RECORDS, "s"
+error_code IMPORT_GET_PARAMS, "while retrieving configuration parameters"
+end
diff --git a/src/kadmin/dbutil/ovload.c b/src/kadmin/dbutil/ovload.c
new file mode 100644
index 000000000..a57dece95
--- /dev/null
+++ b/src/kadmin/dbutil/ovload.c
@@ -0,0 +1,207 @@
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <memory.h>
+
+#include <kadm5/adb.h>
+#include "import_err.h"
+
+char *nstrtok();
+
+#define LINESIZE 32768 /* XXX */
+#define PLURAL(count) (((count) == 1) ? error_message(IMPORT_SINGLE_RECORD) : error_message(IMPORT_PLURAL_RECORDS))
+
+int parse_pw_hist_ent(current, hist)
+ char *current;
+ osa_pw_hist_ent *hist;
+{
+ int tmp, i, j, ret;
+ char *cp;
+
+ ret = 0;
+ hist->n_key_data = 1;
+
+ hist->key_data = (krb5_key_data *) malloc(hist->n_key_data *
+ sizeof(krb5_key_data));
+ if (hist->key_data == NULL)
+ return ENOMEM;
+ memset(hist->key_data, 0, sizeof(krb5_key_data)*hist->n_key_data);
+
+ for (i = 0; i < hist->n_key_data; i++) {
+ krb5_key_data *key_data = &hist->key_data[i];
+
+ key_data->key_data_ver = 1;
+
+ if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
+ com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
+ ret = IMPORT_FAILED;
+ goto done;
+ }
+ key_data->key_data_type[0] = atoi(cp);
+
+ if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
+ com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
+ ret = IMPORT_FAILED;
+ goto done;
+ }
+ key_data->key_data_length[0] = atoi(cp);
+
+ if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
+ com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
+ ret = IMPORT_FAILED;
+ goto done;
+ }
+ if(!(key_data->key_data_contents[0] =
+ (krb5_octet *) malloc(key_data->key_data_length[0]+1))) {
+ ret = ENOMEM;
+ goto done;
+ }
+ for(j = 0; j < key_data->key_data_length[0]; j++) {
+ if(sscanf(cp, "%02x", &tmp) != 1) {
+ com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
+ ret = IMPORT_FAILED;
+ goto done;
+ }
+ key_data->key_data_contents[0][j] = tmp;
+ cp = strchr(cp, ' ') + 1;
+ }
+ }
+
+done:
+ return ret;
+}
+
+/*
+ * Function: parse_principal
+ *
+ * Purpose: parse principal line in db dump file
+ *
+ * Arguments:
+ * <return value> 0 on sucsess, error code on failure
+ *
+ * Requires:
+ * principal database to be opened.
+ * nstrtok(3) to have a valid buffer in memory.
+ *
+ * Effects:
+ * [effects]
+ *
+ * Modifies:
+ * [modifies]
+ *
+ */
+int process_ov_principal(fname, kcontext, filep, verbose, linenop, pol_db)
+ char *fname;
+ krb5_context kcontext;
+ FILE *filep;
+ int verbose;
+ int *linenop;
+ void *pol_db;
+{
+ XDR xdrs;
+ osa_princ_ent_t rec;
+ osa_adb_ret_t ret;
+ krb5_tl_data tl_data;
+ krb5_principal princ;
+ krb5_db_entry kdb;
+ char *current;
+ char *cp;
+ int tmp, x, i, one, more;
+ char line[LINESIZE];
+
+ if (fgets(line, LINESIZE, filep) == (char *) NULL) {
+ return IMPORT_BAD_FILE;
+ }
+ if((cp = nstrtok(line, "\t")) == NULL)
+ return IMPORT_BAD_FILE;
+ if((rec = (osa_princ_ent_t) malloc(sizeof(osa_princ_ent_rec))) == NULL)
+ return ENOMEM;
+ memset(rec, 0, sizeof(osa_princ_ent_rec));
+ if((ret = krb5_parse_name(kcontext, cp, &princ)))
+ goto done;
+ krb5_unparse_name(kcontext, princ, &current);
+ if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
+ com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
+ ret = IMPORT_FAILED;
+ goto done;
+ } else {
+ if(strcmp(cp, "")) {
+ if((rec->policy = (char *) malloc(strlen(cp)+1)) == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ strcpy(rec->policy, cp);
+ } else rec->policy = NULL;
+ }
+ if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
+ com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
+ ret = IMPORT_FAILED;
+ goto done;
+ }
+ rec->aux_attributes = strtol(cp, (char **)NULL, 16);
+ if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
+ com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
+ ret = IMPORT_FAILED;
+ goto done;
+ }
+ rec->old_key_len = atoi(cp);
+ if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
+ com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
+ ret = IMPORT_FAILED;
+ goto done;
+ }
+ rec->old_key_next = atoi(cp);
+ if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
+ com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
+ ret = IMPORT_FAILED;
+ goto done;
+ }
+ rec->admin_history_kvno = atoi(cp);
+ if (! rec->old_key_len) {
+ rec->old_keys = NULL;
+ } else {
+ if(!(rec->old_keys = (osa_pw_hist_ent *)
+ malloc(sizeof(osa_pw_hist_ent) * rec->old_key_len))) {
+ ret = ENOMEM;
+ goto done;
+ }
+ memset(rec->old_keys,0,
+ sizeof(osa_pw_hist_ent) * rec->old_key_len);
+ for(x = 0; x < rec->old_key_len; x++)
+ parse_pw_hist_ent(current, &rec->old_keys[x]);
+ }
+
+ xdralloc_create(&xdrs, XDR_ENCODE);
+ if (! xdr_osa_princ_ent_rec(&xdrs, rec)) {
+ xdr_destroy(&xdrs);
+ ret = OSA_ADB_XDR_FAILURE;
+ goto done;
+ }
+
+ tl_data.tl_data_type = KRB5_TL_KADM_DATA;
+ tl_data.tl_data_length = xdr_getpos(&xdrs);
+ tl_data.tl_data_contents = xdralloc_getdata(&xdrs);
+
+ one = 1;
+ ret = krb5_db_get_principal(kcontext, princ, &kdb, &one,
+ &more);
+ if (ret)
+ goto done;
+
+ if (ret = krb5_dbe_update_tl_data(kcontext, &kdb,
+ &tl_data))
+ goto done;
+
+ if (ret = krb5_db_put_principal(kcontext, &kdb, &one))
+ goto done;
+
+ xdr_destroy(&xdrs);
+
+ (*linenop)++;
+
+done:
+ free(current);
+ krb5_free_principal(kcontext, princ);
+ osa_free_princ_ent(rec);
+ return ret;
+}
diff --git a/src/kadmin/dbutil/strtok.c b/src/kadmin/dbutil/strtok.c
new file mode 100644
index 000000000..4458e0c0b
--- /dev/null
+++ b/src/kadmin/dbutil/strtok.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
+ *
+ * $Header$
+ *
+ * $Log$
+ * Revision 1.1 1996/08/01 18:39:54 bjaspan
+ * * Makefile.in, Makefile.ov, configure.in, dump.c: add support for
+ * dump/load of OV*Secure-compatible format.
+ *
+ * Revision 1.1.2.1 1996/06/20 21:49:01 marc
+ * File added to the repository on a branch
+ *
+ * Revision 1.1 1993/11/14 23:51:23 shanzer
+ * Initial revision
+ *
+ */
+
+#if !defined(lint) && !defined(__CODECENTER__)
+static char *rcsid = "$Header$";
+#endif
+
+
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtok.c 5.7 (Berkeley) 6/1/90";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stddef.h>
+#include <string.h>
+
+/*
+ * Function: nstrtok
+ *
+ * Purpose: the same as strtok ... just different. does not deal with
+ * multiple tokens in row.
+ *
+ * Arguments:
+ * s (input) string to scan
+ * delim (input) list of delimiters
+ * <return value> string or null on error.
+ *
+ * Requires:
+ * nuttin
+ *
+ * Effects:
+ * sets last to string
+ *
+ * Modifies:
+ * last
+ *
+ */
+
+char *
+nstrtok(s, delim)
+ register char *s, *delim;
+{
+ register char *spanp;
+ register int c, sc;
+ char *tok;
+ static char *last;
+
+
+ if (s == NULL && (s = last) == NULL)
+ return (NULL);
+
+ /*
+ * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
+ */
+#ifdef OLD
+cont:
+ c = *s++;
+ for (spanp = delim; (sc = *spanp++) != 0;) {
+ if (c == sc)
+ goto cont;
+ }
+
+ if (c == 0) { /* no non-delimiter characters */
+ last = NULL;
+ return (NULL);
+ }
+ tok = s - 1;
+#else
+ tok = s;
+#endif
+
+ /*
+ * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+ * Note that delim must have one NUL; we stop if we see that, too.
+ */
+ for (;;) {
+ c = *s++;
+ spanp = delim;
+ do {
+ if ((sc = *spanp++) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = 0;
+ last = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
+