diff options
Diffstat (limited to 'src/kadmin/import')
| -rw-r--r-- | src/kadmin/import/ChangeLog | 17 | ||||
| -rw-r--r-- | src/kadmin/import/Makefile.in | 18 | ||||
| -rw-r--r-- | src/kadmin/import/Makefile.ov | 24 | ||||
| -rw-r--r-- | src/kadmin/import/configure.in | 12 | ||||
| -rw-r--r-- | src/kadmin/import/import.c | 421 | ||||
| -rw-r--r-- | src/kadmin/import/import.h | 40 | ||||
| -rw-r--r-- | src/kadmin/import/import_err.et | 26 | ||||
| -rw-r--r-- | src/kadmin/import/misc.c | 95 | ||||
| -rw-r--r-- | src/kadmin/import/ovsec_adm_import.c | 164 | ||||
| -rw-r--r-- | src/kadmin/import/strtok.c | 131 | ||||
| -rw-r--r-- | src/kadmin/import/unit-test/Makefile.ov | 9 | ||||
| -rw-r--r-- | src/kadmin/import/unit-test/config/unix.exp | 36 | ||||
| -rw-r--r-- | src/kadmin/import/unit-test/helpers.exp | 93 | ||||
| -rw-r--r-- | src/kadmin/import/unit-test/import.0/usage.exp | 23 | ||||
| -rw-r--r-- | src/kadmin/import/unit-test/valid_export_file | 27 |
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, ¤t); + 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, ¶ms, + ¶ms)) { + 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, ¶ms)) != 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, ¶ms); + params.mask = 0; + if (ret = kadm5_get_config_params(context, NULL, NULL, ¶ms, + ¶ms)) { + 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, ¶ms)) != 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 |
