summaryrefslogtreecommitdiffstats
path: root/src/kadmin/import
diff options
context:
space:
mode:
Diffstat (limited to 'src/kadmin/import')
-rw-r--r--src/kadmin/import/ChangeLog17
-rw-r--r--src/kadmin/import/Makefile.in18
-rw-r--r--src/kadmin/import/Makefile.ov24
-rw-r--r--src/kadmin/import/configure.in12
-rw-r--r--src/kadmin/import/import.c421
-rw-r--r--src/kadmin/import/import.h40
-rw-r--r--src/kadmin/import/import_err.et26
-rw-r--r--src/kadmin/import/misc.c95
-rw-r--r--src/kadmin/import/ovsec_adm_import.c164
-rw-r--r--src/kadmin/import/strtok.c131
-rw-r--r--src/kadmin/import/unit-test/Makefile.ov9
-rw-r--r--src/kadmin/import/unit-test/config/unix.exp36
-rw-r--r--src/kadmin/import/unit-test/helpers.exp93
-rw-r--r--src/kadmin/import/unit-test/import.0/usage.exp23
-rw-r--r--src/kadmin/import/unit-test/valid_export_file27
15 files changed, 1136 insertions, 0 deletions
diff --git a/src/kadmin/import/ChangeLog b/src/kadmin/import/ChangeLog
new file mode 100644
index 000000000..ca7c0bc2d
--- /dev/null
+++ b/src/kadmin/import/ChangeLog
@@ -0,0 +1,17 @@
+Thu Jul 18 20:40:32 1996 Marc Horowitz <marc@mit.edu>
+
+ * configure.in: removed ET_RULES, replaced with AC_PROG_AWK
+
+Mon Jul 15 16:58:08 1996 Marc Horowitz <marc@mit.edu>
+
+ * configure.in (USE_GSSAPI_LIBRARY): shared libraries require all
+ symbols to be resolved, so this needs to be here.
+
+Wed Jul 10 01:26:47 1996 Marc Horowitz <marc@mit.edu>
+
+ * Makefile.in, configure.in: added autoconf support
+
+Tue Jul 9 17:12:08 1996 Marc Horowitz <marc@mit.edu>
+
+ * ovsec_adm_import.c, import.c: renamed <ovsec_admin/foo.h> to
+ <kadm5/foo.h>
diff --git a/src/kadmin/import/Makefile.in b/src/kadmin/import/Makefile.in
new file mode 100644
index 000000000..2f15e706f
--- /dev/null
+++ b/src/kadmin/import/Makefile.in
@@ -0,0 +1,18 @@
+CFLAGS = $(CCOPTS) $(DEFS) -I. $(LOCALINCLUDE)
+
+PROG = kadm5_import
+OBJS = ovsec_adm_import.o import.o import_err.o strtok.o misc.o
+
+all:: $(PROG)
+
+import_err.c import_err.h: $(srcdir)/import_err.et
+$(OBJS): import_err.h
+
+$(PROG): $(OBJS) $(DEPLIBS)
+ $(CC) $(LDFLAGS) $(LDARGS) -o $(PROG) $(OBJS) $(LIBS)
+
+install::
+ $(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(ADMIN_BINDIR)/$(PROG)
+
+clean::
+ $(RM) $(PROG) $(OBJS)
diff --git a/src/kadmin/import/Makefile.ov b/src/kadmin/import/Makefile.ov
new file mode 100644
index 000000000..f2750313d
--- /dev/null
+++ b/src/kadmin/import/Makefile.ov
@@ -0,0 +1,24 @@
+TOP = ..
+include $(TOP)/config.mk/template
+CFLAGS := $(CFLAGS)
+
+# The next line *shouldn't* work, because the : should be a ::.
+# However, it does work, and if I change it to :: gmake does really
+# weird things.
+ovsec_adm_import: import_err.h
+
+depend:: import_err.h
+
+PROG := kadm5_import
+OBJS := ovsec_adm_import.o import_err.o import.o strtok.o misc.o
+SRCS := ovsec_adm_import.c import.c import_err.et strtok.c misc.c
+ETABLES := import_err.et
+
+LIBS = $(LIBADMSRV) $(LIBRPCLIB) $(LIBKDB5) $(LIBKRB5_ALL) $(LIBDYN) $(LIBDB)
+
+expand ErrorTables
+expand InstallAdmin
+expand Depend
+
+SUBDIRS = unit-test
+expand SubdirTarget
diff --git a/src/kadmin/import/configure.in b/src/kadmin/import/configure.in
new file mode 100644
index 000000000..ad66ebd7c
--- /dev/null
+++ b/src/kadmin/import/configure.in
@@ -0,0 +1,12 @@
+AC_INIT(ovsec_adm_import.c)
+CONFIG_RULES
+AC_PROG_INSTALL
+AC_PROG_AWK
+USE_KADMSRV_LIBRARY
+USE_GSSRPC_LIBRARY
+USE_GSSAPI_LIBRARY
+USE_DYN_LIBRARY
+USE_KDB5_LIBRARY
+KRB5_LIBRARIES
+V5_USE_SHARED_LIB
+V5_AC_OUTPUT_MAKEFILE
diff --git a/src/kadmin/import/import.c b/src/kadmin/import/import.c
new file mode 100644
index 000000000..b1a8c0a76
--- /dev/null
+++ b/src/kadmin/import/import.c
@@ -0,0 +1,421 @@
+/*
+ * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
+ *
+ * $Header$
+ */
+
+#if !defined(lint) && !defined(__CODECENTER__)
+static char *rcsid = "$Header$";
+#endif
+
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <memory.h>
+
+#include <kadm5/adb.h>
+#include "import_err.h"
+#include "import.h"
+
+#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, ovsec_compat)
+ char *current;
+ osa_pw_hist_ent *hist;
+ int ovsec_compat;
+{
+ int tmp, i, j, ret;
+ char *cp;
+
+ ret = 0;
+ if (!ovsec_compat) {
+ if ((cp = nstrtok((char *) NULL, "\t")) == NULL) {
+ com_err(NULL, IMPORT_BAD_RECORD, "%s", current);
+ return IMPORT_FAILED;
+ }
+ hist->n_key_data = atoi(cp);
+ } else
+ 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 parse_principal(context, ovsec_compat)
+ krb5_context context;
+ int ovsec_compat;
+{
+ 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;
+
+ if((cp = nstrtok((char *) NULL, "\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(context, cp, &princ)))
+ goto done;
+ krb5_unparse_name(context, 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], ovsec_compat);
+ }
+
+ 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(context, princ, &kdb, &one,
+ &more);
+ if (ret)
+ goto done;
+
+ if (ret = krb5_dbe_update_tl_data(context, &kdb,
+ &tl_data))
+ goto done;
+
+ if (ret = krb5_db_put_principal(context, &kdb, &one))
+ goto done;
+
+ xdr_destroy(&xdrs);
+
+done:
+ free(current);
+ krb5_free_principal(context, princ);
+ osa_free_princ_ent(rec);
+ return ret;
+}
+
+/*
+ * Function: parse-policy
+ *
+ * Purpose: parse the ascii text of a dump file and turn it into
+ * a policy_ent_rec.
+ *
+ * Arguments:
+ * <return value> 0 on sucsess, error code on failure;
+ *
+ * Requires:
+ * nstrtok to have a buffer in memory
+ *
+ * Effects:
+ * write data out to db.
+ *
+ * Modifies:
+ * policy db.
+ *
+ */
+int
+parse_policy(pol_db)
+ osa_adb_policy_t pol_db;
+{
+ osa_policy_ent_t rec;
+ char *cp;
+ osa_adb_ret_t ret;
+
+ if((rec = (osa_policy_ent_t) malloc(sizeof(osa_princ_ent_rec))) == NULL)
+ return ENOMEM;
+ memset(rec, 0, sizeof(osa_princ_ent_rec));
+ if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
+ ret = IMPORT_BAD_FILE;
+ goto done;
+ }
+ if((rec->name = (char *) malloc(strlen(cp) + 1)) == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ strcpy(rec->name, cp);
+ if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
+ com_err(NULL, IMPORT_BAD_RECORD, "%s", rec->name);
+ ret = IMPORT_FAILED;
+ goto done;
+ }
+ rec->pw_min_life = atoi(cp);
+ if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
+ com_err(NULL, IMPORT_BAD_RECORD, "%s", rec->name);
+ ret = IMPORT_FAILED;
+ goto done;
+ }
+ rec->pw_max_life = atoi(cp);
+ if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
+ com_err(NULL, IMPORT_BAD_RECORD, "%s", rec->name);
+ ret = IMPORT_FAILED;
+ goto done;
+ }
+ rec->pw_min_length = atoi(cp);
+ if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
+ com_err(NULL, IMPORT_BAD_RECORD, "%s", rec->name);
+ ret = IMPORT_FAILED;
+ goto done;
+ }
+ rec->pw_min_classes = atoi(cp);
+ if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
+ com_err(NULL, IMPORT_BAD_RECORD, "%s", rec->name);
+ ret = IMPORT_FAILED;
+ goto done;
+ }
+ rec->pw_history_num = atoi(cp);
+ if((cp = nstrtok((char *) NULL, "\t")) == NULL) {
+ com_err(NULL, IMPORT_BAD_RECORD, "%s", rec->name);
+ ret = IMPORT_FAILED;
+ goto done;
+ }
+ rec->policy_refcnt = atoi(cp);
+ ret = osa_adb_create_policy(pol_db, rec);
+done:
+ osa_free_policy_ent(rec);
+ return ret;
+}
+
+/*
+ * Function: import-file
+ *
+ * Purpose: import a flat ascii file and convert it to a db file.
+ *
+ * Arguments:
+ * fp (input) file pointer to read db.
+ * <return value> 0 or error code on error.
+ *
+ * Requires:
+ * fp be valid
+ *
+ * Effects:
+ * calls appropriate routine to write out db files.
+ *
+ * Modifies:
+ * database file.
+ *
+ */
+
+int import_file(krb5_context context, FILE *fp, int merge_princs,
+ osa_adb_policy_t pol_db)
+{
+
+ int count = 0;
+ int errcnt = 0;
+ int ret = 0;
+ int found_footer = 0;
+ int file_count;
+ int ovsec_compat;
+ char line[LINESIZE];
+ char version[BUFSIZ];
+ char date[BUFSIZ];
+ char *cp;
+
+ if(fgets(line, LINESIZE, fp) == NULL)
+ return IMPORT_BAD_FILE;
+ if ((sscanf(line, "%[^\t]\t %[^\t]", version, date)) != 2)
+ return IMPORT_BAD_FILE;
+ if(!strcmp(version, VERSION_OVSEC_10))
+ ovsec_compat++;
+ else if (strcmp(version, VERSION_KADM5_20))
+ return IMPORT_BAD_VERSION;
+
+ while(fgets(line, LINESIZE, fp) != (char *) NULL) {
+ if(found_footer) {
+ com_err(NULL, IMPORT_EXTRA_DATA, NULL);
+ break;
+ }
+ cp = nstrtok(line, "\t");
+ if(!strcasecmp(cp, "princ")) {
+ if(merge_princs &&
+ (ret = parse_principal(context, ovsec_compat)) != OSA_ADB_OK) {
+ if(ret == IMPORT_FAILED) {
+ if(!confirm())
+ break;
+ else {
+ errcnt++;
+ continue;
+ }
+ } else break;
+ } else {
+ count++;
+ continue;
+ }
+ }
+ if(!strcasecmp(cp, "policy")) {
+ if((ret = parse_policy(pol_db)) != OSA_ADB_OK) {
+ if(ret == IMPORT_FAILED) {
+ if(!confirm())
+ break;
+ else {
+ errcnt++;
+ continue;
+ }
+ } else break;
+ } else {
+ count++;
+ continue;
+ }
+ }
+ if(!strcasecmp(cp, "end of database")) {
+ found_footer = 1;
+ } else {
+ com_err(NULL, IMPORT_BAD_TOKEN, "%s", cp);
+ if(!confirm()) {
+ ret = IMPORT_BAD_FILE;
+ break;
+ } else {
+ errcnt++;
+ continue;
+ }
+ }
+ }
+ if(ret == OSA_ADB_OK && found_footer) {
+ if((cp = nstrtok(NULL, "\t")) == NULL) {
+ com_err(NULL, IMPORT_BAD_FOOTER, NULL);
+ if(!confirm())
+ ret = IMPORT_BAD_FOOTER;
+ else
+ ret = OSA_ADB_OK;
+ } else
+ file_count = atoi(cp);
+ if(file_count != (count + errcnt)) {
+ fprintf(stderr, error_message(IMPORT_COUNT_MESSAGE), file_count,
+ PLURAL(file_count), count, PLURAL(count));
+ if(!confirm())
+ ret = IMPORT_MISMATCH_COUNT;
+ else
+ ret = OSA_ADB_OK;
+ } else fprintf(stderr, error_message(IMPORT_NO_ERR), count,
+ PLURAL(count));
+ } else if(ret == OSA_ADB_OK && !found_footer) {
+ com_err(NULL, IMPORT_BAD_FOOTER, NULL);
+ if(!confirm())
+ ret = IMPORT_BAD_FOOTER;
+ else
+ ret = OSA_ADB_OK;
+ }
+
+ return ret;
+}
+
diff --git a/src/kadmin/import/import.h b/src/kadmin/import/import.h
new file mode 100644
index 000000000..e0c3fedf9
--- /dev/null
+++ b/src/kadmin/import/import.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
+ *
+ * $Header$
+ *
+ * $Log$
+ * Revision 1.3 1996/07/22 20:26:27 marc
+ * this commit includes all the changes on the OV_9510_INTEGRATION and
+ * OV_MERGE branches. This includes, but is not limited to, the new openvision
+ * admin system, and major changes to gssapi to add functionality, and bring
+ * the implementation in line with rfc1964. before committing, the
+ * code was built and tested for netbsd and solaris.
+ *
+ * Revision 1.2.4.1 1996/07/18 03:02:23 marc
+ * merged in changes from OV_9510_BP to OV_9510_FINAL1
+ *
+ * Revision 1.2.2.1 1996/06/20 21:48:24 marc
+ * File added to the repository on a branch
+ *
+ * Revision 1.2 1996/06/05 20:52:28 bjaspan
+ * initial hack at porting to mit kerberos
+ *
+ * Revision 1.1 1993/11/17 06:13:23 shanzer
+ * Initial revision
+ *
+ */
+
+#include <stdio.h>
+
+/*
+ * XXX These should be defined somewhere so import and export get the
+ * same value.
+ */
+#define VERSION_OVSEC_10 "OpenV*Secure V1.0"
+#define VERSION_KADM5_20 "Kerberos KADM5 database V2.0"
+
+int import_file(krb5_context context, FILE *fp, int merge_princs,
+ osa_adb_policy_t pol_db);
+int confirm(void);
+char *nstrtok(char *str, char *delim);
diff --git a/src/kadmin/import/import_err.et b/src/kadmin/import/import_err.et
new file mode 100644
index 000000000..e091fe33c
--- /dev/null
+++ b/src/kadmin/import/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/import/misc.c b/src/kadmin/import/misc.c
new file mode 100644
index 000000000..bc58c7e7f
--- /dev/null
+++ b/src/kadmin/import/misc.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
+ *
+ * $Header$
+ *
+ * $Log$
+ * Revision 1.4 1996/07/22 20:26:31 marc
+ * this commit includes all the changes on the OV_9510_INTEGRATION and
+ * OV_MERGE branches. This includes, but is not limited to, the new openvision
+ * admin system, and major changes to gssapi to add functionality, and bring
+ * the implementation in line with rfc1964. before committing, the
+ * code was built and tested for netbsd and solaris.
+ *
+ * Revision 1.3.4.1 1996/07/18 03:02:26 marc
+ * merged in changes from OV_9510_BP to OV_9510_FINAL1
+ *
+ * Revision 1.3.2.1 1996/06/20 21:48:39 marc
+ * File added to the repository on a branch
+ *
+ * Revision 1.3 1994/04/11 23:52:10 jik
+ * Sandbox:
+ *
+ * Include <com_err.h> to get the declaration of error_message.
+ *
+ * Revision 1.3 1994/03/29 21:18:54 jik
+ * Include <com_err.h> to get the declaration of error_message.
+ *
+ * Revision 1.2 1993/12/21 18:59:25 shanzer
+ * make sure we prompt for input from /dev/tty
+ *
+ * Revision 1.1 1993/11/14 23:51:04 shanzer
+ * Initial revision
+ *
+ */
+
+#if !defined(lint) && !defined(__CODECENTER__)
+static char *rcsid = "$Header$";
+#endif
+
+#include <stdio.h>
+#include <com_err.h> /* for error_message() */
+#include "import_err.h"
+
+#ifndef TRUE
+#define TRUE (1);
+#endif
+#ifndef FALSE
+#define FALSE (0);
+#endif
+
+/*
+ * Function: confirm
+ *
+ * Purpose: ask a yes or no question you must answer
+ * with a 'y|n|Y|n'
+ *
+ * Arguments:
+ * (input) none
+ * <return value> 1 if answered yes. 0 if no.
+ *
+ * Requires:
+ * IMPORT_CONFIRM be be defined. and com_err be init.
+ *
+ * Effects:
+ * none
+ *
+ * Modifies:
+ * nuttin
+ *
+ */
+
+int
+confirm(void)
+{
+ char buf[BUFSIZ]; /* can we say overkill ... */
+ FILE *fp;
+
+ if ((fp = fopen("/dev/tty", "r")) == NULL) {
+ fprintf(stderr, error_message(IMPORT_TTY));
+ return FALSE;
+ }
+ while(1) {
+ fprintf(stderr, error_message(IMPORT_CONFIRM));
+ fgets(buf, BUFSIZ, fp);
+ if(buf[0] == 'y' || buf[0] == 'Y') {
+ fclose(fp);
+ return TRUE;
+ }
+ if(buf[0] == 'n' || buf[0] == 'N') {
+ fclose(fp);
+ return FALSE;
+ }
+ }
+}
+
diff --git a/src/kadmin/import/ovsec_adm_import.c b/src/kadmin/import/ovsec_adm_import.c
new file mode 100644
index 000000000..4ca920434
--- /dev/null
+++ b/src/kadmin/import/ovsec_adm_import.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
+ *
+ * $Header$
+ */
+
+#if !defined(lint) && !defined(__CODECENTER__)
+static char *rcsid = "$Header$";
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <kadm5/adb.h>
+#include "import_err.h"
+#include "import.h"
+
+#define TMP_POLICY_FMT "/krb5/#ovsec_import_policy.%d"
+
+int
+main(int argc, char *argv[])
+{
+ char *filename,
+ *whoami;
+ int ret, merge_princs;
+ FILE *fp;
+ osa_adb_policy_t policy_db;
+ char pol_dbfile[BUFSIZ];
+ kadm5_config_params params;
+ krb5_context context;
+
+ filename = NULL;
+ initialize_imp_error_table();
+ initialize_adb_error_table();
+ krb5_init_context(&context);
+ krb5_init_ets(context);
+
+ whoami = argv[0];
+ merge_princs = 0;
+ while(--argc) {
+ if(*++argv == NULL)
+ break;
+ if (!strcmp(*argv, "-merge_princs")) {
+ merge_princs++;
+ continue;
+ }
+ if (*argv[0] == '-') {
+ com_err(whoami, IMPORT_UNK_OPTION, NULL);
+ exit(2);
+ }
+ if(filename == NULL)
+ filename = *argv;
+ else {
+ com_err(whoami, IMPORT_UNK_OPTION, NULL);
+ exit(2);
+ }
+ }
+ if(filename != NULL) {
+ if ((fp = fopen(filename, "r")) == NULL) {
+ com_err(whoami, errno, "%s (%s)", error_message(IMPORT_OPEN_DUMP),
+ filename);
+ exit(2);
+ }
+ } else fp = stdin;
+
+ sprintf(pol_dbfile, TMP_POLICY_FMT, getpid());
+ if(access(pol_dbfile, F_OK) == 0) {
+ if(unlink(pol_dbfile) != 0)
+ return errno;
+ }
+
+ params.mask = 0;
+ if (ret = kadm5_get_config_params(context, NULL, NULL, &params,
+ &params)) {
+ com_err(whoami, ret, error_message(IMPORT_GET_PARAMS));
+ exit(2);
+ }
+#define REQUIRED_MASK (KADM5_CONFIG_DBNAME | \
+ KADM5_CONFIG_ADBNAME)
+ if ((params.mask & REQUIRED_MASK) != REQUIRED_MASK) {
+ com_err(whoami, KADM5_BAD_SERVER_PARAMS,
+ error_message(IMPORT_GET_PARAMS));
+ exit(2);
+ }
+ /*
+ * This trick lets me use the temporary policy db name but the
+ * standard policy db lockfile, thus ensuring that no one changes
+ * the policy while this program is working.
+ */
+ params.admin_dbname = pol_dbfile;
+
+ if((ret = osa_adb_open_policy(&policy_db, &params)) != OSA_ADB_OK) {
+ com_err(whoami, ret, error_message(IMPORT_RENAME_OPEN));
+ exit(2);
+ }
+ if ((ret = osa_adb_get_lock(policy_db, OSA_ADB_PERMANENT) != OSA_ADB_OK)) {
+ com_err(whoami, ret, error_message(IMPORT_RENAME_LOCK));
+ exit(2);
+ }
+ if (merge_princs) {
+ if ((ret = krb5_db_set_name(context, params.dbname)) ||
+ (ret = krb5_db_init(context))) {
+ com_err(whoami, ret, error_message(IMPORT_RENAME_OPEN));
+ exit(2);
+ }
+ }
+
+ if((ret = import_file(context, fp, merge_princs, policy_db)) !=
+ OSA_ADB_OK) {
+ unlink(pol_dbfile);
+ com_err(whoami, ret, error_message(IMPORT_IMPORT));
+ exit(2);
+ }
+
+ if (merge_princs && (ret = krb5_db_fini(context))) {
+ com_err(whoami, ret, error_message(IMPORT_RENAME_CLOSE));
+ exit(2);
+ }
+
+ kadm5_free_config_params(context, &params);
+ params.mask = 0;
+ if (ret = kadm5_get_config_params(context, NULL, NULL, &params,
+ &params)) {
+ com_err(whoami, ret, error_message(IMPORT_GET_PARAMS));
+ exit(2);
+ }
+
+ if (access(params.admin_dbname, F_OK) == 0) {
+ puts(error_message(IMPORT_WARN_DB));
+ if(!confirm()) {
+ com_err(whoami, IMPORT_FAILED, NULL);
+ exit(2);
+ }
+ }
+
+ if((ret = osa_adb_open_policy(&policy_db, &params)) != OSA_ADB_OK) {
+ com_err(whoami, ret, error_message(IMPORT_RENAME_OPEN));
+ exit(2);
+ }
+ if ((ret = osa_adb_get_lock(policy_db, OSA_ADB_PERMANENT) != OSA_ADB_OK)) {
+ com_err(whoami, ret, error_message(IMPORT_RENAME_LOCK));
+ exit(2);
+ }
+ if (rename(pol_dbfile, params.admin_dbname) != 0) {
+ com_err(whoami, IMPORT_RENAME_FAILED, NULL);
+
+ /* WARNING! Permanent lock is not replaced. This will */
+ /* require manual administrative action! */
+ exit(2);
+ }
+ if ((ret = osa_adb_release_lock(policy_db)) != OSA_ADB_OK) {
+ com_err(whoami, ret, error_message(IMPORT_RENAME_UNLOCK));
+
+ /* WARNING! Permanent lock is not replaced. This will */
+ /* require manual administrative action! */
+ exit(2);
+ }
+ if ((ret = osa_adb_close_policy(policy_db)) != OSA_ADB_OK) {
+ com_err(whoami, ret, error_message(IMPORT_RENAME_CLOSE));
+ exit(2);
+ }
+ exit(0);
+}
diff --git a/src/kadmin/import/strtok.c b/src/kadmin/import/strtok.c
new file mode 100644
index 000000000..7b7155786
--- /dev/null
+++ b/src/kadmin/import/strtok.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
+ *
+ * $Header$
+ *
+ * $Log$
+ * Revision 1.2 1996/07/22 20:26:35 marc
+ * this commit includes all the changes on the OV_9510_INTEGRATION and
+ * OV_MERGE branches. This includes, but is not limited to, the new openvision
+ * admin system, and major changes to gssapi to add functionality, and bring
+ * the implementation in line with rfc1964. before committing, the
+ * code was built and tested for netbsd and solaris.
+ *
+ * Revision 1.1.4.1 1996/07/18 03:02:29 marc
+ * merged in changes from OV_9510_BP to OV_9510_FINAL1
+ *
+ * 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 */
+}
+
diff --git a/src/kadmin/import/unit-test/Makefile.ov b/src/kadmin/import/unit-test/Makefile.ov
new file mode 100644
index 000000000..c7ac33c0b
--- /dev/null
+++ b/src/kadmin/import/unit-test/Makefile.ov
@@ -0,0 +1,9 @@
+#
+# $Id$
+#
+
+TOP = ../..
+include $(TOP)/config.mk/template
+
+unit-test::
+ $(RUNTEST) IMPORT=../ovsec_adm_import --tool import
diff --git a/src/kadmin/import/unit-test/config/unix.exp b/src/kadmin/import/unit-test/config/unix.exp
new file mode 100644
index 000000000..af4ff443e
--- /dev/null
+++ b/src/kadmin/import/unit-test/config/unix.exp
@@ -0,0 +1,36 @@
+#
+# import_version -- extract and print the version number of import
+#
+
+proc import_version {} {
+ global IMPORT
+ set tmp [exec ident $IMPORT]
+ if [regexp {Header: .*import.c,v ([0-9]+\.[0-9]+)} $tmp \
+ dummy version] then {
+ clone_output "$IMPORT version $version\n"
+ } else {
+ clone_output "$IMPORT version <unknown>\n"
+ }
+}
+#
+# import_load -- loads the program
+#
+proc import_load {} {
+ #
+}
+
+# import_exit -- clean up and exit
+proc import_exit {} {
+ #
+}
+
+#
+# import_start -- start import running
+#
+proc import_start { args } {
+ global IMPORT
+ global spawn_id
+
+ verbose "% $IMPORT $args" 1
+ eval spawn $IMPORT $args
+}
diff --git a/src/kadmin/import/unit-test/helpers.exp b/src/kadmin/import/unit-test/helpers.exp
new file mode 100644
index 000000000..5905614e7
--- /dev/null
+++ b/src/kadmin/import/unit-test/helpers.exp
@@ -0,0 +1,93 @@
+#
+# $Id$
+#
+
+proc myfail { comment } {
+ global mytest_name
+ global mytest_status
+ wait
+ fail "$mytest_name: $comment"
+ set mytest_status 1
+}
+
+proc mypass {} {
+}
+
+##
+## When you expect on an id, and eof is detected, the spawn_id is closed.
+## It may be waited for, but calling expect or close on this id is an ERROR!
+##
+
+proc mytest { name kpargs status args } {
+ global spawn_id
+ global timeout
+ global mytest_name
+ global mytest_status
+
+ verbose "starting test: $name"
+
+ set mytest_name "$name"
+
+ eval import_start $kpargs
+
+ # at the end, eof is success
+
+ lappend args { eof { if {[regexp "\[\r\n\]$" $expect_out(buffer)] == 0} { myfail "final status message not newline-terminated" } } }
+
+ # for each test argument....
+ # rep invariant: when this foreach ends, the id is close'd, but
+ # not wait'ed.
+
+ foreach test $args {
+ set mytest_status 0
+
+ # treat the arg as an expect parameter
+ # if failure, the process will be closed and waited.
+
+ uplevel 1 "expect {
+ $test
+ timeout { close; myfail \"timeout\"}
+ eof { myfail \"eof read before expected message string\" }
+ }"
+
+ if {$mytest_status == 1} { return }
+ }
+
+ # at this point, the id is closed and we can wait on it.
+
+ set ret [wait]
+ verbose "% Exit $ret" 1
+ if {[lindex $ret 0] == -1} {
+ fail "$name: wait returned error [lindex $ret 1]"
+ } else {
+ if { ((![string compare $status zero]) &&
+ ([lindex $ret 1] == 0)) ||
+ ((![string compare $status nonzero]) &&
+ ([lindex $ret 1] != 0)) } {
+ pass "$name"
+ } else {
+ fail "$name: unexpected return status [lindex $ret 1], should be $status"
+ }
+ }
+}
+
+proc import_win { name args } {
+ mytest "$name" "$args" zero {
+ -re "Successfully imported \[0-9\]+ records."
+ { mypass }
+ eof
+ { myfail "error: $expect_out(buffer)" }
+ }
+}
+
+proc import_lose { name args error } {
+ mytest "$name" "$args" nonzero {
+ -re "Successfully imported \[0-9\]+ records."
+ { myfail "unexpected success" }
+ -re "ovsec_adm_import: .*$error"
+ { mypass }
+ eof
+ { myfail "error: $expect_out(buffer)" }
+ }
+}
+
diff --git a/src/kadmin/import/unit-test/import.0/usage.exp b/src/kadmin/import/unit-test/import.0/usage.exp
new file mode 100644
index 000000000..8e82f5a21
--- /dev/null
+++ b/src/kadmin/import/unit-test/import.0/usage.exp
@@ -0,0 +1,23 @@
+#
+# $Id$
+#
+
+set timeout 5
+
+load_lib "helpers.exp"
+
+#
+# Here are the tests
+#
+
+import_lose "C.6: input file not readable" /foo/bar/baz \
+ "No such file or directory while opening input file"
+
+import_lose "C.7: two arguments" {foo bar} \
+ "Usage:"
+
+system {rm -rf /krb5}
+
+import_lose "C.2: /krb5 doesn't exist" ./valid_export_file \
+ "Secure administration database lock file missing while importing"
+
diff --git a/src/kadmin/import/unit-test/valid_export_file b/src/kadmin/import/unit-test/valid_export_file
new file mode 100644
index 000000000..dad19c874
--- /dev/null
+++ b/src/kadmin/import/unit-test/valid_export_file
@@ -0,0 +1,27 @@
+OpenV*Secure V1.0 Tue Dec 21 14:18:18 1993
+policy test-pol 0 10000 8 2 3 1
+policy dict-only 0 0 1 1 1 1
+policy once-a-min 30 0 1 1 1 1
+policy test-pol-nopw 0 0 1 1 1 2
+princ admin/delete@SECURE-TEST.OV.COM 0 0 0 0
+princ test3@SECURE-TEST.OV.COM 0 0 0 0
+princ admin/modify@SECURE-TEST.OV.COM 0 0 0 0
+princ ovsec_adm/changepw@SECURE-TEST.OV.COM 0 0 0 0
+princ test2@SECURE-TEST.OV.COM 0 0 0 0
+princ admin/pol@SECURE-TEST.OV.COM test-pol-nopw 800 0 0 0
+princ admin/rename@SECURE-TEST.OV.COM 0 0 0 0
+princ test1@SECURE-TEST.OV.COM 0 0 0 0
+princ krbtgt/SECURE-TEST.OV.COM@SECURE-TEST.OV.COM 0 0 0 0
+princ pol3@SECURE-TEST.OV.COM dict-only 800 0 0 0
+princ admin/get-pol@SECURE-TEST.OV.COM test-pol-nopw 800 0 0 0
+princ admin/none@SECURE-TEST.OV.COM 0 0 0 0
+princ testuser@SECURE-TEST.OV.COM 0 0 0 0
+princ pol2@SECURE-TEST.OV.COM once-a-min 800 0 0 0
+princ K/M@SECURE-TEST.OV.COM 0 0 0 0
+princ pol1@SECURE-TEST.OV.COM test-pol 800 0 0 0
+princ ovsec_adm/history@SECURE-TEST.OV.COM 0 0 0 0
+princ admin@SECURE-TEST.OV.COM 0 0 0 0
+princ admin/add@SECURE-TEST.OV.COM 0 0 0 0
+princ admin/get@SECURE-TEST.OV.COM 0 0 0 0
+princ ovsec_adm/admin@SECURE-TEST.OV.COM 0 0 0 0
+End of Database 25 records