* Makefile.in, Makefile.ov, configure.in, dump.c: add support for
authorBarry Jaspan <bjaspan@mit.edu>
Thu, 1 Aug 1996 18:39:54 +0000 (18:39 +0000)
committerBarry Jaspan <bjaspan@mit.edu>
Thu, 1 Aug 1996 18:39:54 +0000 (18:39 +0000)
        dump/load of OV*Secure-compatible format.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@8889 dc483132-0cff-0310-8789-dd5450dbe970

src/kadmin/dbutil/ChangeLog
src/kadmin/dbutil/Makefile.in
src/kadmin/dbutil/Makefile.ov
src/kadmin/dbutil/configure.in
src/kadmin/dbutil/dump.c
src/kadmin/dbutil/import_err.et [new file with mode: 0644]
src/kadmin/dbutil/ovload.c [new file with mode: 0644]
src/kadmin/dbutil/strtok.c [new file with mode: 0644]

index e870b8485043231df874d283a1f7e40ba1f91e79..8c8aa4ce2a1bef1518f8f43484b811465038959c 100644 (file)
@@ -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.
index 30c19894c2be7b9f4e304fc549d9a60fa9f13351..c6325fd1e7e817d59a9224da1a2ce4bf938b117c 100644 (file)
@@ -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
index f762282f25e4007b74cf1f57f3ce8f0fdd1bc002..c314aa2b166e465843f21f92c43e48dbcd099d2b 100644 (file)
@@ -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
index c9234524efc7559e9b7ba56c044405f4bc92dfc0..66edf685f8927d57969b85859044ae8c9910ca3d 100644 (file)
@@ -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
index 8bd54ca4dd90897e449fee06b2ee008fa8a2278a..29bda177a94bbca8f1b0b245bac0e53d5af78e32 100644 (file)
@@ -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.
  *
@@ -1636,6 +1766,45 @@ process_k5beta7_record(fname, kcontext, filep, verbose, linenop, pol_db)
      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
+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.
  */
@@ -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 (file)
index 0000000..e091fe3
--- /dev/null
@@ -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 (file)
index 0000000..a57dece
--- /dev/null
@@ -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 (file)
index 0000000..4458e0c
--- /dev/null
@@ -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 */
+}
+