diff --git a/lib/kadm5/Makefile.am b/lib/kadm5/Makefile.am index 7d8bc2452..bae88894d 100644 --- a/lib/kadm5/Makefile.am +++ b/lib/kadm5/Makefile.am @@ -7,7 +7,7 @@ SLC = $(top_builddir)/lib/sl/slc lib_LTLIBRARIES = libkadm5srv.la libkadm5clnt.la libkadm5srv_la_LDFLAGS = -version-info 7:7:0 libkadm5clnt_la_LDFLAGS = -version-info 6:5:2 -sbin_PROGRAMS = replay_log truncate_log iprop-log +sbin_PROGRAMS = iprop-log check_PROGRAMS = default_keys noinst_PROGRAMS = test_pw_quality @@ -96,14 +96,10 @@ libkadm5clnt_la_SOURCES = $(SOURCES_client) client_glue.c iprop_log_SOURCES = iprop-log.c iprop-commands.c -replay_log_SOURCES = replay_log.c kadm5_locl.h - ipropd_master_SOURCES = ipropd_master.c iprop.h kadm5_locl.h ipropd_slave_SOURCES = ipropd_slave.c iprop.h kadm5_locl.h -truncate_log_SOURCES = truncate_log.c - man_MANS = kadm5_pwcheck.3 iprop.8 LDADD = \ diff --git a/lib/kadm5/iprop-commands.in b/lib/kadm5/iprop-commands.in index cb97cdd71..ba380bd5d 100644 --- a/lib/kadm5/iprop-commands.in +++ b/lib/kadm5/iprop-commands.in @@ -51,6 +51,56 @@ command = { help = "Prints the iprop transaction log in text." max_args = "0" } +command = { + name = "truncate" + option = { + long = "config-file" + short = "c" + type = "string" + help = "configuration file" + argument = "file" + } + option = { + long = "realm" + short = "r" + type = "string" + help = "realm" + } + function = "iprop_truncate" + help = "Truncate the log, preserve the version number." + max_args = "0" +} +command = { + name = "replay" + option = { + long = "start-version" + type = "integer" + help = "start replay with this version" + argument = "version-number" + } + option = { + long = "end-version" + type = "integer" + help = "end replay with this version" + argument = "version-number" + } + option = { + long = "config-file" + short = "c" + type = "string" + help = "configuration file" + argument = "file" + } + option = { + long = "realm" + short = "r" + type = "string" + help = "realm" + } + function = "iprop_replay" + help = "Replay the log on the database." + max_args = "0" +} command = { name = "help" argument = "command" diff --git a/lib/kadm5/iprop-log.c b/lib/kadm5/iprop-log.c index 01a107486..810c61f89 100644 --- a/lib/kadm5/iprop-log.c +++ b/lib/kadm5/iprop-log.c @@ -40,6 +40,44 @@ RCSID("$Id$"); static krb5_context context; +static kadm5_server_context * +get_kadmin_context(const char *config_file, char *realm) +{ + kadm5_config_params conf; + krb5_error_code ret; + void *kadm_handle; + char **files; + + if (config_file == NULL) + config_file = HDB_DB_DIR "/kdc.conf"; + + ret = krb5_prepend_config_files_default(config_file, &files); + if (ret) + krb5_err(context, 1, ret, "getting configuration files"); + + ret = krb5_set_config_files(context, files); + krb5_free_config_files(files); + if (ret) + krb5_err(context, 1, ret, "reading configuration files"); + + memset(&conf, 0, sizeof(conf)); + if(realm) { + conf.mask |= KADM5_CONFIG_REALM; + conf.realm = realm; + } + + ret = kadm5_init_with_password_ctx (context, + KADM5_ADMIN_SERVICE, + NULL, + KADM5_ADMIN_SERVICE, + &conf, 0, 0, + &kadm_handle); + if (ret) + krb5_err (context, 1, ret, "kadm5_init_with_password_ctx"); + + return (kadm5_server_context *)kadm_handle; +} + /* * dump log */ @@ -64,7 +102,8 @@ print_entry(kadm5_server_context *server_context, time_t timestamp, enum kadm_ops op, u_int32_t len, - krb5_storage *sp) + krb5_storage *sp, + void *ctx) { char t[256]; int32_t mask; @@ -224,47 +263,17 @@ print_entry(kadm5_server_context *server_context, int iprop_dump(struct dump_options *opt, int argc, char **argv) { - const char *config_file = opt->config_file_string; - void *kadm_handle; kadm5_server_context *server_context; - kadm5_config_params conf; - char **files; krb5_error_code ret; - if (config_file == NULL) - config_file = HDB_DB_DIR "/kdc.conf"; - - ret = krb5_prepend_config_files_default(config_file, &files); - if (ret) - krb5_err(context, 1, ret, "getting configuration files"); - - ret = krb5_set_config_files(context, files); - krb5_free_config_files(files); - if (ret) - krb5_err(context, 1, ret, "reading configuration files"); - - memset(&conf, 0, sizeof(conf)); - if(opt->realm_string) { - conf.mask |= KADM5_CONFIG_REALM; - conf.realm = opt->realm_string; - } - - ret = kadm5_init_with_password_ctx (context, - KADM5_ADMIN_SERVICE, - NULL, - KADM5_ADMIN_SERVICE, - &conf, 0, 0, - &kadm_handle); - if (ret) - krb5_err (context, 1, ret, "kadm5_init_with_password_ctx"); - - server_context = (kadm5_server_context *)kadm_handle; + server_context = get_kadmin_context(opt->config_file_string, + opt->realm_string); ret = kadm5_log_init (server_context); if (ret) krb5_err (context, 1, ret, "kadm5_log_init"); - ret = kadm5_log_foreach (server_context, print_entry); + ret = kadm5_log_foreach (server_context, print_entry, NULL); if(ret) krb5_warn(context, ret, "kadm5_log_foreach"); @@ -274,7 +283,90 @@ iprop_dump(struct dump_options *opt, int argc, char **argv) return 0; } +int +iprop_truncate(struct truncate_options *opt, int argc, char **argv) +{ + kadm5_server_context *server_context; + krb5_error_code ret; + server_context = get_kadmin_context(opt->config_file_string, + opt->realm_string); + + ret = kadm5_log_truncate (server_context); + if (ret) + krb5_err (context, 1, ret, "kadm5_log_truncate"); + + return 0; +} + +/* + * Replay log + */ + +int start_version = -1; +int end_version = -1; + +static void +apply_entry(kadm5_server_context *server_context, + u_int32_t ver, + time_t timestamp, + enum kadm_ops op, + u_int32_t len, + krb5_storage *sp, + void *ctx) +{ + struct replay_options *opt = ctx; + krb5_error_code ret; + + if((opt->start_version_integer != -1 && ver < opt->start_version_integer) || + (opt->end_version_integer != -1 && ver > opt->end_version_integer)) { + /* XXX skip this entry */ + krb5_storage_seek(sp, len, SEEK_CUR); + return; + } + printf ("ver %u... ", ver); + fflush (stdout); + + ret = kadm5_log_replay (server_context, + op, ver, len, sp); + if (ret) + krb5_warn (server_context->context, ret, "kadm5_log_replay"); + + + printf ("done\n"); +} + +int +iprop_replay(struct replay_options *opt, int argc, char **argv) +{ + kadm5_server_context *server_context; + krb5_error_code ret; + + server_context = get_kadmin_context(opt->config_file_string, + opt->realm_string); + + ret = server_context->db->hdb_open(context, + server_context->db, + O_RDWR | O_CREAT, 0); + if (ret) + krb5_err (context, 1, ret, "db->open"); + + ret = kadm5_log_init (server_context); + if (ret) + krb5_err (context, 1, ret, "kadm5_log_init"); + + ret = kadm5_log_foreach (server_context, apply_entry, opt); + if(ret) + krb5_warn(context, ret, "kadm5_log_foreach"); + ret = kadm5_log_end (server_context); + if (ret) + krb5_warn(context, ret, "kadm5_log_end"); + ret = server_context->db->hdb_close (context, server_context->db); + if (ret) + krb5_err (context, 1, ret, "db->close"); + + return 0; +} static int help_flag; static int version_flag;