Path: blob/main/crypto/heimdal/lib/kadm5/iprop-log.c
34870 views
/*1* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan2* (Royal Institute of Technology, Stockholm, Sweden).3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11*12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* 3. Neither the name of the Institute nor the names of its contributors17* may be used to endorse or promote products derived from this software18* without specific prior written permission.19*20* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND21* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE23* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE24* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL25* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS26* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)27* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT28* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY29* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF30* SUCH DAMAGE.31*/3233#include "iprop.h"34#include <sl.h>35#include <parse_time.h>36#include "iprop-commands.h"3738RCSID("$Id$");3940static krb5_context context;4142static kadm5_server_context *43get_kadmin_context(const char *config_file, char *realm)44{45kadm5_config_params conf;46krb5_error_code ret;47void *kadm_handle;48char **files;4950if (config_file == NULL) {51char *file;52asprintf(&file, "%s/kdc.conf", hdb_db_dir(context));53if (file == NULL)54errx(1, "out of memory");55config_file = file;56}5758ret = krb5_prepend_config_files_default(config_file, &files);59if (ret)60krb5_err(context, 1, ret, "getting configuration files");6162ret = krb5_set_config_files(context, files);63krb5_free_config_files(files);64if (ret)65krb5_err(context, 1, ret, "reading configuration files");6667memset(&conf, 0, sizeof(conf));68if(realm) {69conf.mask |= KADM5_CONFIG_REALM;70conf.realm = realm;71}7273ret = kadm5_init_with_password_ctx (context,74KADM5_ADMIN_SERVICE,75NULL,76KADM5_ADMIN_SERVICE,77&conf, 0, 0,78&kadm_handle);79if (ret)80krb5_err (context, 1, ret, "kadm5_init_with_password_ctx");8182return (kadm5_server_context *)kadm_handle;83}8485/*86* dump log87*/8889static const char *op_names[] = {90"get",91"delete",92"create",93"rename",94"chpass",95"modify",96"randkey",97"get_privs",98"get_princs",99"chpass_with_key",100"nop"101};102103static void104print_entry(kadm5_server_context *server_context,105uint32_t ver,106time_t timestamp,107enum kadm_ops op,108uint32_t len,109krb5_storage *sp,110void *ctx)111{112char t[256];113int32_t mask;114hdb_entry ent;115krb5_principal source;116char *name1, *name2;117krb5_data data;118krb5_context scontext = server_context->context;119120off_t end = krb5_storage_seek(sp, 0, SEEK_CUR) + len;121122krb5_error_code ret;123124strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S", localtime(×tamp));125126if((int)op < (int)kadm_get || (int)op > (int)kadm_nop) {127printf("unknown op: %d\n", op);128krb5_storage_seek(sp, end, SEEK_SET);129return;130}131132printf ("%s: ver = %u, timestamp = %s, len = %u\n",133op_names[op], ver, t, len);134switch(op) {135case kadm_delete:136ret = krb5_unparse_name(scontext, source, &name1);137if (ret == 0)138ret = krb5_ret_principal(sp, &source);139if (ret)140krb5_err(scontext, 1, ret, "Failed to read a delete record");141printf(" %s\n", name1);142free(name1);143krb5_free_principal(scontext, source);144break;145case kadm_rename:146ret = krb5_data_alloc(&data, len);147if (ret == 0)148krb5_ret_principal(sp, &source);149if (ret == 0 && krb5_storage_read(sp, data.data, data.length))150ret = errno;151if (ret == 0)152ret = hdb_value2entry(scontext, &data, &ent);153if (ret == 0)154ret = krb5_unparse_name(scontext, source, &name1);155if (ret == 0)156ret = krb5_unparse_name(scontext, ent.principal, &name2);157if (ret)158krb5_err (scontext, 1, ret, "kadm_rename: data alloc: %d", len);159printf(" %s -> %s\n", name1, name2);160free(name1);161free(name2);162krb5_free_principal(scontext, source);163free_hdb_entry(&ent);164break;165case kadm_create:166ret = krb5_data_alloc(&data, len);167if (ret == 0 && krb5_storage_read(sp, data.data, data.length))168ret = errno;169if (ret == 0)170ret = hdb_value2entry(scontext, &data, &ent);171if (ret)172krb5_err (scontext, 1, ret, "kadm_create: data alloc: %d", len);173mask = ~0;174goto foo;175case kadm_modify:176ret = krb5_data_alloc(&data, len);177if (ret == 0)178ret = krb5_ret_int32(sp, &mask);179if (ret == 0 && krb5_storage_read(sp, data.data, data.length))180ret = errno;181if (ret == 0)182ret = hdb_value2entry(scontext, &data, &ent);183if (ret)184krb5_err (scontext, 1, ret, "kadm_modify: data alloc: %d", len);185foo:186if(ent.principal /* mask & KADM5_PRINCIPAL */) {187ret = krb5_unparse_name(scontext, ent.principal, &name1);188if (ret)189krb5_err(scontext, 1, ret,190"Failed to process a create or modify record");191printf(" principal = %s\n", name1);192free(name1);193}194if(mask & KADM5_PRINC_EXPIRE_TIME) {195if(ent.valid_end == NULL) {196strlcpy(t, "never", sizeof(t));197} else {198strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S",199localtime(ent.valid_end));200}201printf(" expires = %s\n", t);202}203if(mask & KADM5_PW_EXPIRATION) {204if(ent.pw_end == NULL) {205strlcpy(t, "never", sizeof(t));206} else {207strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S",208localtime(ent.pw_end));209}210printf(" password exp = %s\n", t);211}212if(mask & KADM5_LAST_PWD_CHANGE) {213}214if(mask & KADM5_ATTRIBUTES) {215unparse_flags(HDBFlags2int(ent.flags),216asn1_HDBFlags_units(), t, sizeof(t));217printf(" attributes = %s\n", t);218}219if(mask & KADM5_MAX_LIFE) {220if(ent.max_life == NULL)221strlcpy(t, "for ever", sizeof(t));222else223unparse_time(*ent.max_life, t, sizeof(t));224printf(" max life = %s\n", t);225}226if(mask & KADM5_MAX_RLIFE) {227if(ent.max_renew == NULL)228strlcpy(t, "for ever", sizeof(t));229else230unparse_time(*ent.max_renew, t, sizeof(t));231printf(" max rlife = %s\n", t);232}233if(mask & KADM5_MOD_TIME) {234printf(" mod time\n");235}236if(mask & KADM5_MOD_NAME) {237printf(" mod name\n");238}239if(mask & KADM5_KVNO) {240printf(" kvno = %d\n", ent.kvno);241}242if(mask & KADM5_MKVNO) {243printf(" mkvno\n");244}245if(mask & KADM5_AUX_ATTRIBUTES) {246printf(" aux attributes\n");247}248if(mask & KADM5_POLICY) {249printf(" policy\n");250}251if(mask & KADM5_POLICY_CLR) {252printf(" mod time\n");253}254if(mask & KADM5_LAST_SUCCESS) {255printf(" last success\n");256}257if(mask & KADM5_LAST_FAILED) {258printf(" last failed\n");259}260if(mask & KADM5_FAIL_AUTH_COUNT) {261printf(" fail auth count\n");262}263if(mask & KADM5_KEY_DATA) {264printf(" key data\n");265}266if(mask & KADM5_TL_DATA) {267printf(" tl data\n");268}269free_hdb_entry(&ent);270break;271case kadm_nop :272break;273default:274krb5_errx(scontext, 1, "Unknown record type");275}276krb5_storage_seek(sp, end, SEEK_SET);277}278279int280iprop_dump(struct dump_options *opt, int argc, char **argv)281{282kadm5_server_context *server_context;283krb5_error_code ret;284285server_context = get_kadmin_context(opt->config_file_string,286opt->realm_string);287288ret = kadm5_log_init (server_context);289if (ret)290krb5_err (context, 1, ret, "kadm5_log_init");291292ret = kadm5_log_foreach (server_context, print_entry, NULL);293if(ret)294krb5_warn(context, ret, "kadm5_log_foreach");295296ret = kadm5_log_end (server_context);297if (ret)298krb5_warn(context, ret, "kadm5_log_end");299return 0;300}301302int303iprop_truncate(struct truncate_options *opt, int argc, char **argv)304{305kadm5_server_context *server_context;306krb5_error_code ret;307308server_context = get_kadmin_context(opt->config_file_string,309opt->realm_string);310311ret = kadm5_log_truncate (server_context);312if (ret)313krb5_err (context, 1, ret, "kadm5_log_truncate");314315return 0;316}317318int319last_version(struct last_version_options *opt, int argc, char **argv)320{321kadm5_server_context *server_context;322krb5_error_code ret;323uint32_t version;324325server_context = get_kadmin_context(opt->config_file_string,326opt->realm_string);327328ret = kadm5_log_init (server_context);329if (ret)330krb5_err (context, 1, ret, "kadm5_log_init");331332ret = kadm5_log_get_version (server_context, &version);333if (ret)334krb5_err (context, 1, ret, "kadm5_log_get_version");335336ret = kadm5_log_end (server_context);337if (ret)338krb5_warn(context, ret, "kadm5_log_end");339340printf("version: %lu\n", (unsigned long)version);341342return 0;343}344345/*346* Replay log347*/348349int start_version = -1;350int end_version = -1;351352static void353apply_entry(kadm5_server_context *server_context,354uint32_t ver,355time_t timestamp,356enum kadm_ops op,357uint32_t len,358krb5_storage *sp,359void *ctx)360{361struct replay_options *opt = ctx;362krb5_error_code ret;363364if((opt->start_version_integer != -1 && ver < (uint32_t)opt->start_version_integer) ||365(opt->end_version_integer != -1 && ver > (uint32_t)opt->end_version_integer)) {366/* XXX skip this entry */367krb5_storage_seek(sp, len, SEEK_CUR);368return;369}370printf ("ver %u... ", ver);371fflush (stdout);372373ret = kadm5_log_replay (server_context,374op, ver, len, sp);375if (ret)376krb5_warn (server_context->context, ret, "kadm5_log_replay");377378printf ("done\n");379}380381int382iprop_replay(struct replay_options *opt, int argc, char **argv)383{384kadm5_server_context *server_context;385krb5_error_code ret;386387server_context = get_kadmin_context(opt->config_file_string,388opt->realm_string);389390ret = server_context->db->hdb_open(context,391server_context->db,392O_RDWR | O_CREAT, 0600);393if (ret)394krb5_err (context, 1, ret, "db->open");395396ret = kadm5_log_init (server_context);397if (ret)398krb5_err (context, 1, ret, "kadm5_log_init");399400ret = kadm5_log_foreach (server_context, apply_entry, opt);401if(ret)402krb5_warn(context, ret, "kadm5_log_foreach");403ret = kadm5_log_end (server_context);404if (ret)405krb5_warn(context, ret, "kadm5_log_end");406ret = server_context->db->hdb_close (context, server_context->db);407if (ret)408krb5_err (context, 1, ret, "db->close");409410return 0;411}412413static int help_flag;414static int version_flag;415416static struct getargs args[] = {417{ "version", 0, arg_flag, &version_flag,418NULL, NULL419},420{ "help", 'h', arg_flag, &help_flag,421NULL, NULL422}423};424425static int num_args = sizeof(args) / sizeof(args[0]);426427int428help(void *opt, int argc, char **argv)429{430if(argc == 0) {431sl_help(commands, 1, argv - 1 /* XXX */);432} else {433SL_cmd *c = sl_match (commands, argv[0], 0);434if(c == NULL) {435fprintf (stderr, "No such command: %s. "436"Try \"help\" for a list of commands\n",437argv[0]);438} else {439if(c->func) {440static char shelp[] = "--help";441char *fake[3];442fake[0] = argv[0];443fake[1] = shelp;444fake[2] = NULL;445(*c->func)(2, fake);446fprintf(stderr, "\n");447}448if(c->help && *c->help)449fprintf (stderr, "%s\n", c->help);450if((++c)->name && c->func == NULL) {451int f = 0;452fprintf (stderr, "Synonyms:");453while (c->name && c->func == NULL) {454fprintf (stderr, "%s%s", f ? ", " : " ", (c++)->name);455f = 1;456}457fprintf (stderr, "\n");458}459}460}461return 0;462}463464static void465usage(int status)466{467arg_printusage(args, num_args, NULL, "command");468exit(status);469}470471int472main(int argc, char **argv)473{474int optidx = 0;475krb5_error_code ret;476477setprogname(argv[0]);478479if(getarg(args, num_args, argc, argv, &optidx))480usage(1);481if(help_flag)482usage(0);483if(version_flag) {484print_version(NULL);485exit(0);486}487argc -= optidx;488argv += optidx;489if(argc == 0)490usage(1);491492ret = krb5_init_context(&context);493if (ret)494errx(1, "krb5_init_context failed with: %d\n", ret);495496ret = sl_command(commands, argc, argv);497if(ret == -1)498warnx ("unrecognized command: %s", argv[0]);499return ret;500}501502503