diff --git a/kadmin/ChangeLog b/kadmin/ChangeLog index 5500e4caf..39505698f 100644 --- a/kadmin/ChangeLog +++ b/kadmin/ChangeLog @@ -121,6 +121,25 @@ change it own password to a key, since that password might violate the password quality check. +2002-12-03 Johan Danielsson + + * util.c (get_response): print a newline if interrupted + + * mod.c (mod_entry): check return value from edit_entry + + * ank.c (add_one_principal): check return value from edit_entry + + * ank.c (add_one_principal): don't continue if create_principal + fails + + * init.c: check return value from edit_deltat + + * init.c: add --help + +2002-10-29 Johan Danielsson + + * version4.c: speling (from Tomas Olsson) + 2002-10-23 Assar Westerlund * version4.c (decode_packet): check the length of the version diff --git a/kadmin/Makefile.am b/kadmin/Makefile.am index d59e8e8dd..7038226b5 100644 --- a/kadmin/Makefile.am +++ b/kadmin/Makefile.am @@ -8,6 +8,8 @@ sbin_PROGRAMS = kadmin libexec_PROGRAMS = kadmind +SLC = $(top_builddir)/lib/sl/slc + man_MANS = kadmin.8 kadmind.8 noinst_PROGRAMS = add_random_users @@ -25,11 +27,20 @@ kadmin_SOURCES = \ load.c \ mod.c \ rename.c \ + stash.c \ util.c \ pw_quality.c \ random_password.c \ + kadmin-commands.c \ kadmin_locl.h +$(kadmind_OBJECTS) $(kadmin_OBJECTS): kadmin-commands.h + +CLEANFILES = kadmin-commands.h kadmin-commands.c + +kadmin-commands.c kadmin-commands.h: kadmin-commands.in + $(SLC) $(srcdir)/kadmin-commands.in + kadmind_SOURCES = \ kadmind.c \ server.c \ diff --git a/kadmin/ank.c b/kadmin/ank.c index 1edeebd33..2ff090722 100644 --- a/kadmin/ank.c +++ b/kadmin/ank.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2002 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2004 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -197,84 +197,32 @@ out: * the ank command */ -static struct getargs args[] = { - { "random-key", 'r', arg_flag, NULL, "set random key" }, - { "random-password", 0, arg_flag, NULL, "set random password" }, - { "password", 'p', arg_string, NULL, "princial's password" }, - { "key", 0, arg_string, NULL, "DES-key in hex" }, - { "max-ticket-life", 0, arg_string, NULL, "max ticket lifetime", - "lifetime"}, - { "max-renewable-life", 0, arg_string, NULL, - "max renewable lifetime", "lifetime" }, - { "attributes", 0, arg_string, NULL, "principal attributes", - "attributes"}, - { "expiration-time",0, arg_string, NULL, "expiration time", - "time"}, - { "pw-expiration-time", 0, arg_string, NULL, - "password expiration time", "time"}, - { "use-defaults", 0, arg_flag, NULL, "use default values" } -}; - -static int num_args = sizeof(args) / sizeof(args[0]); - -static void -usage(void) -{ - arg_printusage (args, num_args, "add", "principal..."); -} - /* * Parse arguments and add all the principals. */ int -add_new_key(int argc, char **argv) +add_new_key(struct add_options *opt, int argc, char **argv) { - char *password = NULL; - char *key = NULL; - int random_key = 0; - int random_password = 0; - int optind = 0; krb5_error_code ret; - char *max_ticket_life = NULL; - char *max_renewable_life = NULL; - char *attributes = NULL; - char *expiration = NULL; - char *pw_expiration = NULL; - int use_defaults = 0; int i; int num; krb5_key_data key_data[3]; krb5_key_data *kdp = NULL; - args[0].value = &random_key; - args[1].value = &random_password; - args[2].value = &password; - args[3].value = &key; - args[4].value = &max_ticket_life; - args[5].value = &max_renewable_life; - args[6].value = &attributes; - args[7].value = &expiration; - args[8].value = &pw_expiration; - args[9].value = &use_defaults; - - if(getarg(args, num_args, argc, argv, &optind)) { - usage (); - return 0; - } if(optind == argc) { - usage (); + printf("foo\n"); return 0; } num = 0; - if (random_key) + if (opt->random_key_flag) ++num; - if (random_password) + if (opt->random_password_flag) ++num; - if (password) + if (opt->password_string) ++num; - if (key) + if (opt->key_string) ++num; if (num > 1) { @@ -283,26 +231,28 @@ add_new_key(int argc, char **argv) return 0; } - if (key) { + if (opt->key_string) { const char *error; - if (parse_des_key (key, key_data, &error)) { - printf ("failed parsing key `%s': %s\n", key, error); + if (parse_des_key (opt->key_string, key_data, &error)) { + printf ("failed parsing key `%s': %s\n", opt->key_string, error); return 0; } kdp = key_data; } for (i = optind; i < argc; ++i) { - ret = add_one_principal (argv[i], random_key, random_password, - use_defaults, - password, + ret = add_one_principal (argv[i], + opt->random_key_flag, + opt->random_password_flag, + opt->use_defaults_flag, + opt->password_string, kdp, - max_ticket_life, - max_renewable_life, - attributes, - expiration, - pw_expiration); + opt->max_ticket_life_string, + opt->max_renewable_life_string, + opt->attributes_string, + opt->expiration_time_string, + opt->pw_expiration_time_string); if (ret) { krb5_warn (context, ret, "adding %s", argv[i]); break; diff --git a/kadmin/cpw.c b/kadmin/cpw.c index 37f6d906a..bd3841b93 100644 --- a/kadmin/cpw.c +++ b/kadmin/cpw.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -42,21 +42,6 @@ struct cpw_entry_data { krb5_key_data *key_data; }; -static struct getargs args[] = { - { "random-key", 'r', arg_flag, NULL, "set random key" }, - { "random-password", 0, arg_flag, NULL, "set random password" }, - { "password", 'p', arg_string, NULL, "princial's password" }, - { "key", 0, arg_string, NULL, "DES key in hex" } -}; - -static int num_args = sizeof(args) / sizeof(args[0]); - -static void -usage(void) -{ - arg_printusage(args, num_args, "passwd", "principal..."); -} - static int set_random_key (krb5_principal principal) { @@ -146,32 +131,19 @@ do_cpw_entry(krb5_principal principal, void *data) } int -cpw_entry(int argc, char **argv) +cpw_entry(struct passwd_options *opt, int argc, char **argv) { krb5_error_code ret; int i; - int optind = 0; struct cpw_entry_data data; int num; - char *key_string; krb5_key_data key_data[3]; - data.random_key = 0; - data.random_password = 0; - data.password = NULL; + data.random_key = opt->random_key_flag; + data.random_password = opt->random_password_flag; + data.password = opt->password_string; data.key_data = NULL; - key_string = NULL; - - args[0].value = &data.random_key; - args[1].value = &data.random_password; - args[2].value = &data.password; - args[3].value = &key_string; - if(getarg(args, num_args, argc, argv, &optind)){ - usage(); - return 0; - } - num = 0; if (data.random_key) ++num; @@ -179,7 +151,7 @@ cpw_entry(int argc, char **argv) ++num; if (data.password) ++num; - if (key_string) + if (opt->key_string) ++num; if (num > 1) { @@ -188,19 +160,16 @@ cpw_entry(int argc, char **argv) return 0; } - if (key_string) { + if (opt->key_string) { const char *error; - if (parse_des_key (key_string, key_data, &error)) { - printf ("failed parsing key `%s': %s\n", key_string, error); + if (parse_des_key (opt->key_string, key_data, &error)) { + printf ("failed parsing key `%s': %s\n", opt->key_string, error); return 0; } data.key_data = key_data; } - argc -= optind; - argv += optind; - for(i = 0; i < argc; i++) ret = foreach_principal(argv[i], do_cpw_entry, "cpw", &data); diff --git a/kadmin/del.c b/kadmin/del.c index f91f8b903..fb04231ec 100644 --- a/kadmin/del.c +++ b/kadmin/del.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -41,40 +41,18 @@ do_del_entry(krb5_principal principal, void *data) return kadm5_delete_principal(kadm_handle, principal); } -static struct getargs args[] = { - { "help", 'h', arg_flag, NULL } -}; - -static int num_args = sizeof(args) / sizeof(args[0]); - -static void -usage(void) -{ - arg_printusage (args, num_args, "delete", "principal..."); -} - - int -del_entry(int argc, char **argv) +del_entry(void *opt, int argc, char **argv) { - int optind = 0; - int help_flag = 0; - int i; krb5_error_code ret; - args[0].value = &help_flag; - - if(getarg(args, num_args, argc, argv, &optind)) { - usage (); - return 0; - } - if(optind == argc || help_flag) { - usage (); + if(argc == 0) { + printf("foo\n"); return 0; } - for(i = 1; i < argc; i++) + for(i = 0; i < argc; i++) ret = foreach_principal(argv[i], do_del_entry, "del", NULL); return 0; } diff --git a/kadmin/del_enctype.c b/kadmin/del_enctype.c index ca967fe80..83f398200 100644 --- a/kadmin/del_enctype.c +++ b/kadmin/del_enctype.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2001 Kungliga Tekniska Högskolan + * Copyright (c) 1999-2004 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,25 +39,9 @@ RCSID("$Id$"); * del_enctype principal enctypes... */ -static struct getargs args[] = { - { "help", 'h', arg_flag, NULL } -}; - -static int num_args = sizeof(args) / sizeof(args[0]); - -static void -usage(void) -{ - arg_printusage (args, num_args, "del_enctype", "principal enctypes..."); -} - - int -del_enctype(int argc, char **argv) +del_enctype(void *opt, int argc, char **argv) { - int optind = 0; - int help_flag = 0; - kadm5_principal_ent_rec princ; krb5_principal princ_ent = NULL; krb5_error_code ret; @@ -67,29 +51,23 @@ del_enctype(int argc, char **argv) int n_etypes; krb5_enctype *etypes; - args[0].value = &help_flag; - - if(getarg(args, num_args, argc, argv, &optind)) { - usage (); - return 0; - } - if(argc - optind < 2 || help_flag) { - usage (); + if(argc < 2) { + printf("usage: del_enctype principal enctypes...\n"); return 0; } memset (&princ, 0, sizeof(princ)); - princ_name = argv[1]; - n_etypes = argc - 2; + princ_name = argv[0]; + n_etypes = argc - 1; etypes = malloc (n_etypes * sizeof(*etypes)); if (etypes == NULL) { krb5_warnx (context, "out of memory"); return 0; } for (i = 0; i < n_etypes; ++i) { - ret = krb5_string_to_enctype (context, argv[i + 2], &etypes[i]); + ret = krb5_string_to_enctype (context, argv[i], &etypes[i]); if (ret) { - krb5_warnx (context, "bad enctype `%s'", argv[i + 2]); + krb5_warnx (context, "bad enctype `%s'", argv[i]); goto out2; } } diff --git a/kadmin/dump.c b/kadmin/dump.c index 92e0b5438..2b45a7b99 100644 --- a/kadmin/dump.c +++ b/kadmin/dump.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2004 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,44 +37,29 @@ RCSID("$Id$"); int -dump(int argc, char **argv) +dump(struct dump_options *opt, int argc, char **argv) { krb5_error_code ret; FILE *f; HDB *db = _kadm5_s_get_db(kadm_handle); - int decrypt = 0; - int optind = 0; - struct getargs args[] = { - { "decrypt", 'd', arg_flag, NULL, "decrypt keys" } - }; - args[0].value = &decrypt; - - if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind)) { - arg_printusage(args, sizeof(args) / sizeof(args[0]), "kadmin dump", - "[dump-file]"); - return 0; - } - - argc -= optind; - argv += optind; - if(argc < 1) + if(argc == 0) f = stdout; else f = fopen(argv[0], "w"); + if(f == NULL) + krb5_warn(context, errno, "%s", argv[0]); ret = db->hdb_open(context, db, O_RDONLY, 0600); - if(ret){ + if(ret) { krb5_warn(context, ret, "hdb_open"); - if(f != stdout) - fclose(f); - return 0; + goto out; } - hdb_foreach(context, db, decrypt ? HDB_F_DECRYPT : 0, hdb_print_entry, f); - + hdb_foreach(context, db, opt->decrypt_flag ? HDB_F_DECRYPT : 0, hdb_print_entry, f); + db->hdb_close(context, db); +out: if(f != stdout) fclose(f); - db->hdb_close(context, db); return 0; } diff --git a/kadmin/ext.c b/kadmin/ext.c index 0e2036cdb..fca160855 100644 --- a/kadmin/ext.c +++ b/kadmin/ext.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,18 +39,6 @@ struct ext_keytab_data { krb5_keytab keytab; }; -static struct getargs args[] = { - { "keytab", 'k', arg_string, NULL, "keytab to use" }, -}; - -static int num_args = sizeof(args) / sizeof(args[0]); - -static void -usage(void) -{ - arg_printusage(args, num_args, "ext", "principal..."); -} - static int do_ext_keytab(krb5_principal principal, void *data) { @@ -81,32 +69,22 @@ do_ext_keytab(krb5_principal principal, void *data) } int -ext_keytab(int argc, char **argv) +ext_keytab(struct ext_keytab_options *opt, int argc, char **argv) { krb5_error_code ret; int i; - int optind = 0; - char *keytab = NULL; struct ext_keytab_data data; - - args[0].value = &keytab; - if(getarg(args, num_args, argc, argv, &optind)){ - usage(); - return 0; - } - if (keytab == NULL) + + if (opt->keytab_string == NULL) ret = krb5_kt_default(context, &data.keytab); else - ret = krb5_kt_resolve(context, keytab, &data.keytab); + ret = krb5_kt_resolve(context, opt->keytab_string, &data.keytab); if(ret){ krb5_warn(context, ret, "krb5_kt_resolve"); return 0; } - argc -= optind; - argv += optind; - for(i = 0; i < argc; i++) foreach_principal(argv[i], do_ext_keytab, "ext", &data); diff --git a/kadmin/get.c b/kadmin/get.c index 2cdbd761c..c443a6a41 100644 --- a/kadmin/get.c +++ b/kadmin/get.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2004 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -227,69 +227,51 @@ do_get_entry(krb5_principal principal, void *data) } static int -getit(const char *name, int terse_flag, int argc, char **argv) +getit(struct get_options *opt, const char *name, + int terse_flag, int argc, char **argv) { int i; krb5_error_code ret; struct get_entry_data data; - struct getargs args[] = { - { "long", 'l', arg_flag, NULL, "long format" }, - { "short", 's', arg_flag, NULL, "short format" }, - { "terse", 't', arg_flag, NULL, "terse format" }, - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - int long_flag = -1; - int short_flag = -1; - args[0].value = &long_flag; - args[1].value = &short_flag; - args[2].value = &terse_flag; + if(argc == 0) { + printf("usage: %s principal...\n", name); + return 0; + } - if(getarg(args, num_args, argc, argv, &optind)) - goto usage; - if(optind == argc) - goto usage; + if(opt->long_flag == -1 && (opt->short_flag == 1 || opt->terse_flag == 1)) + opt->long_flag = 0; + if(opt->short_flag == -1 && (opt->long_flag == 1 || opt->terse_flag == 1)) + opt->short_flag = 0; + if(opt->terse_flag == -1 && (opt->long_flag == 1 || opt->short_flag == 1)) + opt->terse_flag = 0; + if(opt->long_flag == 0 && opt->short_flag == 0 && opt->terse_flag == 0) + opt->short_flag = 1; - if(long_flag == -1 && (short_flag == 1 || terse_flag == 1)) - long_flag = 0; - if(short_flag == -1 && (long_flag == 1 || terse_flag == 1)) - short_flag = 0; - if(terse_flag == -1 && (long_flag == 1 || short_flag == 1)) - terse_flag = 0; - if(long_flag == 0 && short_flag == 0 && terse_flag == 0) - short_flag = 1; - - if(long_flag) { + if(opt->long_flag) { data.format = print_entry_long; data.header = NULL; - } else if(short_flag){ + } else if(opt->short_flag){ data.format = print_entry_short; data.header = print_header_short; - } else if(terse_flag) { + } else if(opt->terse_flag) { data.format = print_entry_terse; data.header = NULL; } - argc -= optind; - argv += optind; - for(i = 0; i < argc; i++) ret = foreach_principal(argv[i], do_get_entry, "get", &data); return 0; -usage: - arg_printusage (args, num_args, name, "principal..."); - return 0; } int -get_entry(int argc, char **argv) +get_entry(struct get_options *opt, int argc, char **argv) { - return getit("get", 0, argc, argv); + return getit(opt, "get", 0, argc, argv); } int -list_princs(int argc, char **argv) +list_princs(struct list_options *opt, int argc, char **argv) { - return getit("list", 1, argc, argv); + return getit((struct get_options*)opt, "list", 1, argc, argv); } diff --git a/kadmin/init.c b/kadmin/init.c index 26aa1eba5..cd23a332d 100644 --- a/kadmin/init.c +++ b/kadmin/init.c @@ -106,57 +106,29 @@ create_random_entry(krb5_principal princ, return ret; } -static struct getargs args[] = { - { "realm-max-ticket-life", 0, arg_string, NULL, - "realm max ticket lifetime" }, - { "realm-max-renewable-life", 0, arg_string, NULL, - "realm max renewable lifetime" }, - { "help", 'h', arg_flag, NULL }, -}; - -static int num_args = sizeof(args) / sizeof(args[0]); - -static void -usage(void) -{ - arg_printusage (args, num_args, "init", "realm..."); -} - int -init(int argc, char **argv) +init(struct init_options *opt, int argc, char **argv) { kadm5_ret_t ret; int i; - char *realm_max_life = NULL; - char *realm_max_rlife = NULL; - int help_flag = 0; HDB *db; - int optind = 0; krb5_deltat max_life, max_rlife; - args[0].value = &realm_max_life; - args[1].value = &realm_max_rlife; - args[2].value = &help_flag; - - if(getarg(args, num_args, argc, argv, &optind) || help_flag) { - usage(); + if(argc == 0) { + printf("must have atleast one realm\n"); return 0; } - - if(argc - optind < 1) { - usage(); - return 0; - } - - if (realm_max_life) { - if (str2deltat (realm_max_life, &max_life) != 0) { - krb5_warnx (context, "unable to parse `%s'", realm_max_life); + if (opt->realm_max_ticket_life_string) { + if (str2deltat (opt->realm_max_ticket_life_string, &max_life) != 0) { + krb5_warnx (context, "unable to parse `%s'", + opt->realm_max_ticket_life_string); return 0; } } - if (realm_max_rlife) { - if (str2deltat (realm_max_rlife, &max_rlife) != 0) { - krb5_warnx (context, "unable to parse `%s'", realm_max_rlife); + if (opt->realm_max_renewable_life_string) { + if (str2deltat (opt->realm_max_renewable_life_string, &max_rlife) != 0) { + krb5_warnx (context, "unable to parse `%s'", + opt->realm_max_renewable_life_string); return 0; } } @@ -169,7 +141,7 @@ init(int argc, char **argv) return 0; } db->hdb_close(context, db); - for(i = optind; i < argc; i++){ + for(i = 0; i < argc; i++){ krb5_principal princ; const char *realm = argv[i]; @@ -178,14 +150,14 @@ init(int argc, char **argv) KRB5_TGS_NAME, realm, NULL); if(ret) return 0; - if (realm_max_life == NULL) { + if (opt->realm_max_ticket_life_string == NULL) { max_life = 0; if(edit_deltat ("Realm max ticket life", &max_life, NULL, 0)) { krb5_free_principal(context, princ); return 0; } } - if (realm_max_rlife == NULL) { + if (opt->realm_max_renewable_life_string == NULL) { max_rlife = 0; if(edit_deltat("Realm max renewable ticket life", &max_rlife, NULL, 0)) { diff --git a/kadmin/kadmin-commands.in b/kadmin/kadmin-commands.in new file mode 100644 index 000000000..4e683a5cc --- /dev/null +++ b/kadmin/kadmin-commands.in @@ -0,0 +1,312 @@ +command = { + name = "stash" + name = "kstash" + option = { + long = "enctype" + short = "e" + type = "string" + help = "encryption type" + default = "des3-cbc-sha1" + } + option = { + long = "key-file" + short = "k" + type = "string" + argument = "file" + help = "master key file" + } + option = { + long = "convert-file" + type = "flag" + help = "just convert keyfile to new format" + } + option = { + long = "master-key-fd" + type = "integer" + argument = "fd" + help = "filedescriptor to read passphrase from" + default = "-1" + } + help = "" +} +command = { + name = "dump" + option = { + long = "decrypt" + short = "d" + type = "flag" + help = "decrypt keys" + } + argument = "[dump-file]" + help = "Dumps the database in a human readable format to the specified file, or the standard out." +} + +command = { + name = "init" + option = { + long = "realm-max-ticket-life" + type = "string" + help = "realm max ticket lifetime" + } + option = { + long = "realm-max-renewable-life" + type = "string" + help = "realm max renewable lifetime" + } + argument = "realm..." + help = "Initializes the default principals for a realm. Creates the database if necessary." +} +command = { + name = "load" + argument = "file" + help = "Loads a previously dumped file." +} +command = { + name = "merge" + argument = "file" + help = "Merges the contents of a dump file into the database." +} +command = { + name = "add" + name = "add_new_key" + function = "add_new_key" + option = { + long = "random-key" + short = "r" + type = "flag" + help = "set random key" + } + option = { + long = "random-password" + type = "flag" + help = "set random password" + } + option = { + long = "password" + short = "p" + type = "string" + help = "principal's password" + } + option = { + long = "key" + type = "string" + help = "DES-key in hex" + } + option = { + long = "max-ticket-life" + type = "string" + argument ="lifetime" + help = "max ticket lifetime" + } + option = { + long = "max-renewable-life" + type = "string" + argument = "lifetime" + help = "max renewable life" + } + option = { + long = "attributes" + type = "string" + argument = "attributes" + help = "principal attributes" + } + option = { + long = "expiration-time" + type = "string" + argument = "time" + help = "principal expiration time" + } + option = { + long = "pw-expiration-time" + type = "string" + argument = "time" + help = "password expiration time" + } + option = { + long = "use-defaults" + type = "flag" + help = "use default values" + } + argument = "principal..." + help = "Adds a principal to the database." +} +command = { + name = "passwd" + name = "cpw" + name = "change_password" + function = "cpw_entry" + option = { + long = "random-key" + short = "r" + type = "flag" + help = "set random key" + } + option = { + long = "random-password" + type = "flag" + help = "set random password" + } + option = { + long = "password" + short = "p" + type = "string" + help = "princial's password" + } + option = { + long = "key" + type = "string" + help = "DES key in hex" + } + argument = "principal..." + help = "Changes the password of one or more principals matching the expressions." +} +command = { + name = "delete" + name = "del" + name = "del_entry" + function = "del_entry" + argument = "principal..." + help = "Deletes all principals matching the expressions." +} +command = { + name = "del_enctype" + argument = "principal enctype..." + help = "Delete all the mentioned enctypes for principal." +} +command = { + name = "ext_keytab" + option = { + long = "keytab" + short = "k" + type = "string" + help = "keytab to use" + } + argument = "principal..." + help = "Extracts the keys of all principals matching the expressions, and stores them in a keytab." +} +command = { + name = "get" + name = "get_entry" + function = "get_entry" + option = { + long = "long" + short = "l" + type = "flag" + help = "long format" + } + option = { + long = "short" + short = "s" + type = "flag" + help = "short format" + } + option = { + long = "terse" + short = "t" + type = "flag" + help = "terse format" + } + argument = "principal..." + help = "Shows information about principals matching the expressions." +} +command = { + name = "rename" + function = "rename_entry" + argument = "from to" + help = "Renames a principal." +} +command = { + name = "modify" + function = "mod_entry" + option = { + long = "max-ticket-life" + type = "string" + argument ="lifetime" + help = "max ticket lifetime" + } + option = { + long = "max-renewable-life" + type = "string" + argument = "lifetime" + help = "max renewable life" + } + option = { + long = "attributes" + short = "a" + type = "string" + argument = "attributes" + help = "principal attributes" + } + option = { + long = "expiration-time" + type = "string" + argument = "time" + help = "principal expiration time" + } + option = { + long = "pw-expiration-time" + type = "string" + argument = "time" + help = "password expiration time" + } + option = { + long = "kvno" + type = "integer" + help = "key version number" + } + argument = "principal" + help = "Modifies some attributes of the specified principal." +} +command = { + name = "privileges" + name = "privs" + function = "get_privs" + help = "Shows which operations you are allowed to perform." +} +command = { + name = "list" + function = "list_princs" + option = { + long = "long" + short = "l" + type = "flag" + help = "long format" + } + option = { + long = "short" + short = "s" + type = "flag" + help = "short format" + } + option = { + long = "terse" + short = "t" + type = "flag" + help = "terse format" + } + argument = "principal..." + help = "Lists principals in a terse format. Equivalent to \"get -t\"." +} + +command = { + name = "password-quality" + name = "pwq" + function = "password_quality" + argument = "principal password" + + help = "Try run the password quality function locally (not doing RPC out to server)." +} + +command = { + name = "help" + name = "?" + argument = "[command]" + help = "Help! I need somebody." +} + +command = { + name = "exit" + name = "quit" + function = "exit_kadmin" + help = "Quits." +} diff --git a/kadmin/kadmin.c b/kadmin/kadmin.c index 2cf14cb30..038975cea 100644 --- a/kadmin/kadmin.c +++ b/kadmin/kadmin.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -81,91 +81,6 @@ static struct getargs args[] = { static int num_args = sizeof(args) / sizeof(args[0]); -static SL_cmd commands[] = { - /* commands that are only available with `-l' */ - { - "dump", dump, "dump [file]", - "Dumps the database in a human readable format to the\n" - "specified file, or the standard out." - }, - { - "load", load, "load file", - "Loads a previously dumped file." - }, - { - "merge", merge, "merge file" , - "Merges the contents of a dump file into the database." - }, - { - "init", init, "init realm...", - "Initializes the default principals for a realm.\n" - "Creates the database if necessary." - }, - /* common commands */ - { - "add", add_new_key, "add principal" , - "Adds a principal to the database." - }, - { "add_new_key"}, - { "ank"}, - { - "passwd", cpw_entry, "passwd expression..." , - "Changes the password of one or more principals\n" - "matching the expressions." - }, - { "change_password"}, - { "cpw"}, - { - "delete", del_entry, "delete expression...", - "Deletes all principals matching the expressions." - }, - { "del_entry" }, - { "del" }, - { - "del_enctype", del_enctype, "del_enctype principal enctype...", - "Delete all the mentioned enctypes for principal." - }, - { - "ext_keytab", ext_keytab, "ext_keytab expression...", - "Extracts the keys of all principals matching the expressions,\n" - "and stores them in a keytab." - }, - { - "get", get_entry, "get expression...", - "Shows information about principals matching the expressions." - }, - { "get_entry" }, - { - "rename", rename_entry, "rename source target", - "Renames `source' to `target'." - }, - { - "modify", mod_entry, "modify principal", - "Modifies some attributes of the specified principal." - }, - { - "privileges", get_privs, "privileges", - "Shows which kinds of operations you are allowed to perform." - }, - { "privs" }, - { - "password-quality", - password_quality, - "password-quality principal password", - "Try run the password quality function locally " - "(not doing RPC out to server)." - }, - { "pwq" }, - { - "list", list_princs, "list expression...", - "Lists principals in a terse format. The same as `get -t'." - }, - { "help", help, "help"}, - { "?"}, - { "exit", exit_kadmin, "exit"}, - { "quit" }, - { NULL} -}; krb5_context context; void *kadm_handle; @@ -173,14 +88,40 @@ void *kadm_handle; static SL_cmd *actual_cmds; int -help(int argc, char **argv) +help(void *opt, int argc, char **argv) { - sl_help(actual_cmds, argc, argv); + if(argc == 0) { + sl_help(actual_cmds, 1, argv - 1 /* XXX */); + } else { + SL_cmd *c = sl_match (actual_cmds, argv[0], 0); + if(c == NULL) { + printf ("No such command: %s. " + "Try \"help\" for a list of commands\n", + argv[0]); + } else { + if(c->func) { + char *fake[] = { argv[0], "--help", NULL }; + (*c->func)(2, fake); + fprintf(stderr, "\n"); + } + if(c->help && *c->help) + fprintf (stderr, "%s\n", c->help); + if((++c)->name && c->func == NULL) { + int f = 0; + fprintf (stderr, "Synonyms:"); + while (c->name && c->func == NULL) { + fprintf (stderr, "%s%s", f ? ", " : " ", (c++)->name); + f = 1; + } + fprintf (stderr, "\n"); + } + } + } return 0; } int -exit_kadmin (int argc, char **argv) +exit_kadmin (void *opt, int argc, char **argv) { return 1; } @@ -193,30 +134,12 @@ usage(int ret) } int -get_privs(int argc, char **argv) +get_privs(void *opt, int argc, char **argv) { u_int32_t privs; char str[128]; kadm5_ret_t ret; - int help_flag = 0; - struct getargs args[] = { - { "help", 'h', arg_flag, NULL } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - - args[0].value = &help_flag; - - if(getarg(args, num_args, argc, argv, &optind)) { - arg_printusage (args, num_args, "privileges", NULL); - return 0; - } - if(help_flag) { - arg_printusage (args, num_args, "privileges", NULL); - return 0; - } - ret = kadm5_get_privs(kadm_handle, &privs); if(ret) krb5_warn(context, ret, "kadm5_get_privs"); @@ -314,7 +237,7 @@ main(int argc, char **argv) KADM5_ADMIN_SERVICE, &conf, 0, 0, &kadm_handle); - actual_cmds = commands + 4; /* XXX */ + actual_cmds = commands + 5; /* XXX */ } else { ret = kadm5_c_init_with_password_ctx(context, client_name, diff --git a/kadmin/kadmin_locl.h b/kadmin/kadmin_locl.h index 56447324e..757f19f1b 100644 --- a/kadmin/kadmin_locl.h +++ b/kadmin/kadmin_locl.h @@ -96,30 +96,11 @@ #include #include +#include "kadmin-commands.h" extern krb5_context context; extern void * kadm_handle; -#define DECL(X) int X(int, char **) - -DECL(add_new_key); -DECL(cpw_entry); -DECL(del_entry); -DECL(del_enctype); -DECL(exit_kadmin); -DECL(ext_keytab); -DECL(get_entry); -DECL(get_privs); -DECL(help); -DECL(list_princs); -DECL(mod_entry); -DECL(rename_entry); -DECL(init); -DECL(dump); -DECL(load); -DECL(merge); -DECL(password_quality); - #undef ALLOC #define ALLOC(X) ((X) = malloc(sizeof(*(X)))) diff --git a/kadmin/load.c b/kadmin/load.c index 68add3d2f..6ed67d702 100644 --- a/kadmin/load.c +++ b/kadmin/load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2002 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2004 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -483,58 +483,25 @@ doit(const char *filename, int merge) } -static struct getargs args[] = { - { "help", 'h', arg_flag, NULL } -}; - -static int num_args = sizeof(args) / sizeof(args[0]); - -static void -usage(const char *name) +static int +loadit(int merge, int argc, char **argv) { - arg_printusage (args, num_args, name, "file"); -} - - - -int -load(int argc, char **argv) -{ - int optind = 0; - int help_flag = 0; - - args[0].value = &help_flag; - - if(getarg(args, num_args, argc, argv, &optind)) { - usage ("load"); - return 0; + if(argc != 1) { + printf("%s file", merge ? "merge" : "load"); + return 0; } - if(argc - optind != 1 || help_flag) { - usage ("load"); - return 0; - } - doit(argv[optind], 0); return 0; } - + int -merge(int argc, char **argv) +load(void *opt, int argc, char **argv) { - int optind = 0; - int help_flag = 0; - - args[0].value = &help_flag; - - if(getarg(args, num_args, argc, argv, &optind)) { - usage ("merge"); - return 0; - } - if(argc - optind != 1 || help_flag) { - usage ("merge"); - return 0; - } - - doit(argv[optind], 1); - return 0; + return loadit(0, argc, argv); +} + +int +merge(void *opt, int argc, char **argv) +{ + return loadit(1, argc, argv); } diff --git a/kadmin/mod.c b/kadmin/mod.c index 6b16b1f89..52d36aba7 100644 --- a/kadmin/mod.c +++ b/kadmin/mod.c @@ -35,22 +35,13 @@ RCSID("$Id$"); -struct mod_entry_data { - char *attr_str; - char *max_life_str; - char *max_rlife_str; - char *expiration_str; - char *pw_expiration_str; - int new_kvno; -}; - static int do_mod_entry(krb5_principal principal, void *data) { krb5_error_code ret; kadm5_principal_ent_rec princ; int mask = 0; - struct mod_entry_data *e = data; + struct modify_options *e = data; memset (&princ, 0, sizeof(princ)); ret = kadm5_get_principal(kadm_handle, principal, &princ, @@ -61,20 +52,22 @@ do_mod_entry(krb5_principal principal, void *data) if(ret) return ret; - if(e->max_life_str || e->max_rlife_str || - e->expiration_str || e->pw_expiration_str || e->attr_str || - e->new_kvno != -1) { + if(e->max_ticket_life_string || + e->max_renewable_life_string || + e->expiration_time_string || + e->pw_expiration_time_string || + e->attributes_string || + e->kvno_integer != -1) { ret = set_entry(context, &princ, &mask, - e->max_life_str, - e->max_rlife_str, - e->expiration_str, - e->pw_expiration_str, - e->attr_str); - if(e->new_kvno != -1) { - princ.kvno = e->new_kvno; + e->max_ticket_life_string, + e->max_renewable_life_string, + e->expiration_time_string, + e->pw_expiration_time_string, + e->attributes_string); + if(e->kvno_integer != -1) { + princ.kvno = e->kvno_integer; mask |= KADM5_KVNO; } - } else ret = edit_entry(&princ, &mask, NULL, 0); if(ret == 0) { @@ -88,64 +81,18 @@ do_mod_entry(krb5_principal principal, void *data) } int -mod_entry(int argc, char **argv) +mod_entry(struct modify_options *opt, int argc, char **argv) { krb5_error_code ret; - int optind; - - struct mod_entry_data data; int i; - struct getargs args[] = { - {"attributes", 'a', arg_string, NULL, "Attributies", - "attributes"}, - {"max-ticket-life", 0, arg_string, NULL, "max ticket lifetime", - "lifetime"}, - {"max-renewable-life", 0, arg_string, NULL, - "max renewable lifetime", "lifetime" }, - {"expiration-time", 0, arg_string, - NULL, "Expiration time", "time"}, - {"pw-expiration-time", 0, arg_string, - NULL, "Password expiration time", "time"}, - {"kvno", 0, arg_integer, - NULL, "Key version number", "number"}, - }; - - i = 0; - data.attr_str = NULL; - args[i++].value = &data.attr_str; - data.max_life_str = NULL; - args[i++].value = &data.max_life_str; - data.max_rlife_str = NULL; - args[i++].value = &data.max_rlife_str; - data.expiration_str = NULL; - args[i++].value = &data.expiration_str; - data.pw_expiration_str = NULL; - args[i++].value = &data.pw_expiration_str; - data.new_kvno = -1; - args[i++].value = &data.new_kvno; - - optind = 0; - - if(getarg(args, sizeof(args) / sizeof(args[0]), - argc, argv, &optind)){ - arg_printusage(args, - sizeof(args) / sizeof(args[0]), - "mod", - "principal..."); - return -1; - } - - argc -= optind; - argv += optind; - if (argc < 1) { printf ("Usage: mod [options] principal\n"); return 0; } for(i = 0; i < argc; i++) - ret = foreach_principal(argv[i], do_mod_entry, "mod", &data); + ret = foreach_principal(argv[i], do_mod_entry, "mod", opt); return 0; } diff --git a/kadmin/pw_quality.c b/kadmin/pw_quality.c index b692c2298..2a02cd40b 100644 --- a/kadmin/pw_quality.c +++ b/kadmin/pw_quality.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Kungliga Tekniska Högskolan + * Copyright (c) 2003-2004 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -35,53 +35,32 @@ RCSID("$Id$"); -static struct getargs args[] = { - { "help", 'h', arg_flag, NULL } -}; - -static int num_args = sizeof(args) / sizeof(args[0]); - -static void -usage(void) -{ - arg_printusage (args, num_args, "password-quality", "principal password"); -} - int -password_quality(int argc, char **argv) +password_quality(void *opt, int argc, char **argv) { - int optind = 0; - int help_flag = 0; - krb5_error_code ret; - krb5_principal princ; + krb5_principal principal; krb5_data pw_data; const char *s; - args[0].value = &help_flag; - - if(getarg(args, num_args, argc, argv, &optind)) { - usage (); - return 0; - } - if(argc - optind != 2 || help_flag) { - usage (); + if(argc != 2) { + printf ("Usage: password-quality principal password\n"); return 0; } - ret = krb5_parse_name(context, argv[1], &princ); + ret = krb5_parse_name(context, argv[0], &principal); if(ret){ - krb5_warn(context, ret, "krb5_parse_name(%s)", argv[1]); + krb5_warn(context, ret, "krb5_parse_name(%s)", argv[0]); return 0; } - pw_data.data = argv[2]; - pw_data.length = strlen(argv[2]); + pw_data.data = argv[1]; + pw_data.length = strlen(argv[1]); - s = kadm5_check_password_quality (context, princ, &pw_data); + s = kadm5_check_password_quality (context, principal, &pw_data); if (s) krb5_warnx(context, "kadm5_check_password_quality: %s", s); - krb5_free_principal(context, princ); + krb5_free_principal(context, principal); return 0; } diff --git a/kadmin/rename.c b/kadmin/rename.c index c46494faf..2f0f99959 100644 --- a/kadmin/rename.c +++ b/kadmin/rename.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2004 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -35,47 +35,26 @@ RCSID("$Id$"); -static struct getargs args[] = { - { "help", 'h', arg_flag, NULL } -}; - -static int num_args = sizeof(args) / sizeof(args[0]); - -static void -usage(void) -{ - arg_printusage (args, num_args, "rename", "from to"); -} - int -rename_entry(int argc, char **argv) +rename_entry(void *opt, int argc, char **argv) { - int optind = 0; - int help_flag = 0; - krb5_error_code ret; krb5_principal princ1, princ2; - args[0].value = &help_flag; - - if(getarg(args, num_args, argc, argv, &optind)) { - usage (); - return 0; - } - if(argc - optind != 2 || help_flag) { - usage (); + if(argc != 2) { + printf("rename [options] from to\n"); return 0; } - ret = krb5_parse_name(context, argv[1], &princ1); + ret = krb5_parse_name(context, argv[0], &princ1); if(ret){ - krb5_warn(context, ret, "krb5_parse_name(%s)", argv[1]); + krb5_warn(context, ret, "krb5_parse_name(%s)", argv[0]); return 0; } - ret = krb5_parse_name(context, argv[2], &princ2); + ret = krb5_parse_name(context, argv[1], &princ2); if(ret){ krb5_free_principal(context, princ2); - krb5_warn(context, ret, "krb5_parse_name(%s)", argv[2]); + krb5_warn(context, ret, "krb5_parse_name(%s)", argv[1]); return 0; } ret = kadm5_rename_principal(kadm_handle, princ1, princ2); diff --git a/kadmin/stash.c b/kadmin/stash.c new file mode 100644 index 000000000..b343b0087 --- /dev/null +++ b/kadmin/stash.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute 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 BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "kadmin_locl.h" + +RCSID("$Id$"); + +int +stash(struct stash_options *opt, int argc, char **argv) +{ + char buf[1024]; + krb5_error_code ret; + krb5_enctype enctype; + hdb_master_key mkey; + + ret = krb5_string_to_enctype(context, opt->enctype_string, &enctype); + if(ret) + krb5_warn(context, ret, "%s", opt->enctype_string); + return 0; + + if(opt->key_file_string == NULL) + opt->key_file_string = HDB_DB_DIR "/m-key"; + + ret = hdb_read_master_key(context, opt->key_file_string, &mkey); + if(ret && ret != ENOENT) { + krb5_warn(context, ret, "reading master key from %s", + opt->key_file_string); + return 0; + } + + if (opt->convert_file_flag) { + if (ret) + krb5_warn(context, ret, "reading master key from %s", + opt->key_file_string); + return 0; + } else { + krb5_keyblock key; + krb5_salt salt; + salt.salttype = KRB5_PW_SALT; + /* XXX better value? */ + salt.saltvalue.data = NULL; + salt.saltvalue.length = 0; + if(opt->master_key_fd_integer != -1) { + ssize_t n; + n = read(opt->master_key_fd_integer, buf, sizeof(buf)); + if(n == 0) + krb5_warnx(context, "end of file reading passphrase"); + else if(n < 0) + krb5_warn(context, errno, "reading passphrase"); + buf[n] = '\0'; + buf[strcspn(buf, "\r\n")] = '\0'; + } else { + if(UI_UTIL_read_pw_string(buf, sizeof(buf), "Master key: ", 1)) { + hdb_free_master_key(context, mkey); + return 0; + } + } + ret = krb5_string_to_key_salt(context, enctype, buf, salt, &key); + ret = hdb_add_master_key(context, &key, &mkey); + krb5_free_keyblock_contents(context, &key); + } + + { + char *new, *old; + asprintf(&old, "%s.old", opt->key_file_string); + asprintf(&new, "%s.new", opt->key_file_string); + if(old == NULL || new == NULL) { + ret = ENOMEM; + goto out; + } + + if(unlink(new) < 0 && errno != ENOENT) { + ret = errno; + goto out; + } + krb5_warnx(context, "writing key to `%s'", opt->key_file_string); + ret = hdb_write_master_key(context, new, mkey); + if(ret) + unlink(new); + else { + unlink(old); + if(link(opt->key_file_string, old) < 0 && errno != ENOENT) { + ret = errno; + unlink(new); + } else if(rename(new, opt->key_file_string) < 0) { + ret = errno; + } + } + out: + free(old); + free(new); + if(ret) + krb5_warn(context, errno, "writing master key file"); + } + + hdb_free_master_key(context, mkey); + return 0; +}