convert to use slc; also add stash subcommand

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@13970 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Johan Danielsson
2004-06-21 19:19:45 +00:00
parent 3cc8ea1b60
commit d7f9fac88e
18 changed files with 646 additions and 608 deletions

View File

@@ -121,6 +121,25 @@
change it own password to a key, since that password might violate change it own password to a key, since that password might violate
the password quality check. the password quality check.
2002-12-03 Johan Danielsson <joda@pdc.kth.se>
* 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 <joda@pdc.kth.se>
* version4.c: speling (from Tomas Olsson)
2002-10-23 Assar Westerlund <assar@kth.se> 2002-10-23 Assar Westerlund <assar@kth.se>
* version4.c (decode_packet): check the length of the version * version4.c (decode_packet): check the length of the version

View File

@@ -8,6 +8,8 @@ sbin_PROGRAMS = kadmin
libexec_PROGRAMS = kadmind libexec_PROGRAMS = kadmind
SLC = $(top_builddir)/lib/sl/slc
man_MANS = kadmin.8 kadmind.8 man_MANS = kadmin.8 kadmind.8
noinst_PROGRAMS = add_random_users noinst_PROGRAMS = add_random_users
@@ -25,11 +27,20 @@ kadmin_SOURCES = \
load.c \ load.c \
mod.c \ mod.c \
rename.c \ rename.c \
stash.c \
util.c \ util.c \
pw_quality.c \ pw_quality.c \
random_password.c \ random_password.c \
kadmin-commands.c \
kadmin_locl.h 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_SOURCES = \
kadmind.c \ kadmind.c \
server.c \ server.c \

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -197,84 +197,32 @@ out:
* the ank command * 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. * Parse arguments and add all the principals.
*/ */
int 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; 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 i;
int num; int num;
krb5_key_data key_data[3]; krb5_key_data key_data[3];
krb5_key_data *kdp = NULL; 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) { if(optind == argc) {
usage (); printf("foo\n");
return 0; return 0;
} }
num = 0; num = 0;
if (random_key) if (opt->random_key_flag)
++num; ++num;
if (random_password) if (opt->random_password_flag)
++num; ++num;
if (password) if (opt->password_string)
++num; ++num;
if (key) if (opt->key_string)
++num; ++num;
if (num > 1) { if (num > 1) {
@@ -283,26 +231,28 @@ add_new_key(int argc, char **argv)
return 0; return 0;
} }
if (key) { if (opt->key_string) {
const char *error; const char *error;
if (parse_des_key (key, key_data, &error)) { if (parse_des_key (opt->key_string, key_data, &error)) {
printf ("failed parsing key `%s': %s\n", key, error); printf ("failed parsing key `%s': %s\n", opt->key_string, error);
return 0; return 0;
} }
kdp = key_data; kdp = key_data;
} }
for (i = optind; i < argc; ++i) { for (i = optind; i < argc; ++i) {
ret = add_one_principal (argv[i], random_key, random_password, ret = add_one_principal (argv[i],
use_defaults, opt->random_key_flag,
password, opt->random_password_flag,
opt->use_defaults_flag,
opt->password_string,
kdp, kdp,
max_ticket_life, opt->max_ticket_life_string,
max_renewable_life, opt->max_renewable_life_string,
attributes, opt->attributes_string,
expiration, opt->expiration_time_string,
pw_expiration); opt->pw_expiration_time_string);
if (ret) { if (ret) {
krb5_warn (context, ret, "adding %s", argv[i]); krb5_warn (context, ret, "adding %s", argv[i]);
break; break;

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -42,21 +42,6 @@ struct cpw_entry_data {
krb5_key_data *key_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 static int
set_random_key (krb5_principal principal) set_random_key (krb5_principal principal)
{ {
@@ -146,32 +131,19 @@ do_cpw_entry(krb5_principal principal, void *data)
} }
int int
cpw_entry(int argc, char **argv) cpw_entry(struct passwd_options *opt, int argc, char **argv)
{ {
krb5_error_code ret; krb5_error_code ret;
int i; int i;
int optind = 0;
struct cpw_entry_data data; struct cpw_entry_data data;
int num; int num;
char *key_string;
krb5_key_data key_data[3]; krb5_key_data key_data[3];
data.random_key = 0; data.random_key = opt->random_key_flag;
data.random_password = 0; data.random_password = opt->random_password_flag;
data.password = NULL; data.password = opt->password_string;
data.key_data = NULL; 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; num = 0;
if (data.random_key) if (data.random_key)
++num; ++num;
@@ -179,7 +151,7 @@ cpw_entry(int argc, char **argv)
++num; ++num;
if (data.password) if (data.password)
++num; ++num;
if (key_string) if (opt->key_string)
++num; ++num;
if (num > 1) { if (num > 1) {
@@ -188,19 +160,16 @@ cpw_entry(int argc, char **argv)
return 0; return 0;
} }
if (key_string) { if (opt->key_string) {
const char *error; const char *error;
if (parse_des_key (key_string, key_data, &error)) { if (parse_des_key (opt->key_string, key_data, &error)) {
printf ("failed parsing key `%s': %s\n", key_string, error); printf ("failed parsing key `%s': %s\n", opt->key_string, error);
return 0; return 0;
} }
data.key_data = key_data; data.key_data = key_data;
} }
argc -= optind;
argv += optind;
for(i = 0; i < argc; i++) for(i = 0; i < argc; i++)
ret = foreach_principal(argv[i], do_cpw_entry, "cpw", &data); ret = foreach_principal(argv[i], do_cpw_entry, "cpw", &data);

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -41,40 +41,18 @@ do_del_entry(krb5_principal principal, void *data)
return kadm5_delete_principal(kadm_handle, principal); 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 int
del_entry(int argc, char **argv) del_entry(void *opt, int argc, char **argv)
{ {
int optind = 0;
int help_flag = 0;
int i; int i;
krb5_error_code ret; krb5_error_code ret;
args[0].value = &help_flag; if(argc == 0) {
printf("foo\n");
if(getarg(args, num_args, argc, argv, &optind)) {
usage ();
return 0;
}
if(optind == argc || help_flag) {
usage ();
return 0; return 0;
} }
for(i = 1; i < argc; i++) for(i = 0; i < argc; i++)
ret = foreach_principal(argv[i], do_del_entry, "del", NULL); ret = foreach_principal(argv[i], do_del_entry, "del", NULL);
return 0; return 0;
} }

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -39,25 +39,9 @@ RCSID("$Id$");
* del_enctype principal enctypes... * 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 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; kadm5_principal_ent_rec princ;
krb5_principal princ_ent = NULL; krb5_principal princ_ent = NULL;
krb5_error_code ret; krb5_error_code ret;
@@ -67,29 +51,23 @@ del_enctype(int argc, char **argv)
int n_etypes; int n_etypes;
krb5_enctype *etypes; krb5_enctype *etypes;
args[0].value = &help_flag; if(argc < 2) {
printf("usage: del_enctype principal enctypes...\n");
if(getarg(args, num_args, argc, argv, &optind)) {
usage ();
return 0;
}
if(argc - optind < 2 || help_flag) {
usage ();
return 0; return 0;
} }
memset (&princ, 0, sizeof(princ)); memset (&princ, 0, sizeof(princ));
princ_name = argv[1]; princ_name = argv[0];
n_etypes = argc - 2; n_etypes = argc - 1;
etypes = malloc (n_etypes * sizeof(*etypes)); etypes = malloc (n_etypes * sizeof(*etypes));
if (etypes == NULL) { if (etypes == NULL) {
krb5_warnx (context, "out of memory"); krb5_warnx (context, "out of memory");
return 0; return 0;
} }
for (i = 0; i < n_etypes; ++i) { 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) { if (ret) {
krb5_warnx (context, "bad enctype `%s'", argv[i + 2]); krb5_warnx (context, "bad enctype `%s'", argv[i]);
goto out2; goto out2;
} }
} }

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -37,44 +37,29 @@
RCSID("$Id$"); RCSID("$Id$");
int int
dump(int argc, char **argv) dump(struct dump_options *opt, int argc, char **argv)
{ {
krb5_error_code ret; krb5_error_code ret;
FILE *f; FILE *f;
HDB *db = _kadm5_s_get_db(kadm_handle); HDB *db = _kadm5_s_get_db(kadm_handle);
int decrypt = 0;
int optind = 0;
struct getargs args[] = { if(argc == 0)
{ "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)
f = stdout; f = stdout;
else else
f = fopen(argv[0], "w"); f = fopen(argv[0], "w");
if(f == NULL)
krb5_warn(context, errno, "%s", argv[0]);
ret = db->hdb_open(context, db, O_RDONLY, 0600); ret = db->hdb_open(context, db, O_RDONLY, 0600);
if(ret){ if(ret) {
krb5_warn(context, ret, "hdb_open"); krb5_warn(context, ret, "hdb_open");
if(f != stdout) goto out;
fclose(f);
return 0;
} }
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) if(f != stdout)
fclose(f); fclose(f);
db->hdb_close(context, db);
return 0; return 0;
} }

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -39,18 +39,6 @@ struct ext_keytab_data {
krb5_keytab keytab; 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 static int
do_ext_keytab(krb5_principal principal, void *data) do_ext_keytab(krb5_principal principal, void *data)
{ {
@@ -81,32 +69,22 @@ do_ext_keytab(krb5_principal principal, void *data)
} }
int int
ext_keytab(int argc, char **argv) ext_keytab(struct ext_keytab_options *opt, int argc, char **argv)
{ {
krb5_error_code ret; krb5_error_code ret;
int i; int i;
int optind = 0;
char *keytab = NULL;
struct ext_keytab_data data; struct ext_keytab_data data;
args[0].value = &keytab; if (opt->keytab_string == NULL)
if(getarg(args, num_args, argc, argv, &optind)){
usage();
return 0;
}
if (keytab == NULL)
ret = krb5_kt_default(context, &data.keytab); ret = krb5_kt_default(context, &data.keytab);
else else
ret = krb5_kt_resolve(context, keytab, &data.keytab); ret = krb5_kt_resolve(context, opt->keytab_string, &data.keytab);
if(ret){ if(ret){
krb5_warn(context, ret, "krb5_kt_resolve"); krb5_warn(context, ret, "krb5_kt_resolve");
return 0; return 0;
} }
argc -= optind;
argv += optind;
for(i = 0; i < argc; i++) for(i = 0; i < argc; i++)
foreach_principal(argv[i], do_ext_keytab, "ext", &data); foreach_principal(argv[i], do_ext_keytab, "ext", &data);

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -227,69 +227,51 @@ do_get_entry(krb5_principal principal, void *data)
} }
static int 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; int i;
krb5_error_code ret; krb5_error_code ret;
struct get_entry_data data; 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; if(argc == 0) {
args[1].value = &short_flag; printf("usage: %s principal...\n", name);
args[2].value = &terse_flag; return 0;
}
if(getarg(args, num_args, argc, argv, &optind)) if(opt->long_flag == -1 && (opt->short_flag == 1 || opt->terse_flag == 1))
goto usage; opt->long_flag = 0;
if(optind == argc) if(opt->short_flag == -1 && (opt->long_flag == 1 || opt->terse_flag == 1))
goto usage; 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)) if(opt->long_flag) {
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) {
data.format = print_entry_long; data.format = print_entry_long;
data.header = NULL; data.header = NULL;
} else if(short_flag){ } else if(opt->short_flag){
data.format = print_entry_short; data.format = print_entry_short;
data.header = print_header_short; data.header = print_header_short;
} else if(terse_flag) { } else if(opt->terse_flag) {
data.format = print_entry_terse; data.format = print_entry_terse;
data.header = NULL; data.header = NULL;
} }
argc -= optind;
argv += optind;
for(i = 0; i < argc; i++) for(i = 0; i < argc; i++)
ret = foreach_principal(argv[i], do_get_entry, "get", &data); ret = foreach_principal(argv[i], do_get_entry, "get", &data);
return 0; return 0;
usage:
arg_printusage (args, num_args, name, "principal...");
return 0;
} }
int 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 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);
} }

View File

@@ -106,57 +106,29 @@ create_random_entry(krb5_principal princ,
return ret; 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 int
init(int argc, char **argv) init(struct init_options *opt, int argc, char **argv)
{ {
kadm5_ret_t ret; kadm5_ret_t ret;
int i; int i;
char *realm_max_life = NULL;
char *realm_max_rlife = NULL;
int help_flag = 0;
HDB *db; HDB *db;
int optind = 0;
krb5_deltat max_life, max_rlife; krb5_deltat max_life, max_rlife;
args[0].value = &realm_max_life; if(argc == 0) {
args[1].value = &realm_max_rlife; printf("must have atleast one realm\n");
args[2].value = &help_flag;
if(getarg(args, num_args, argc, argv, &optind) || help_flag) {
usage();
return 0; return 0;
} }
if (opt->realm_max_ticket_life_string) {
if(argc - optind < 1) { if (str2deltat (opt->realm_max_ticket_life_string, &max_life) != 0) {
usage(); krb5_warnx (context, "unable to parse `%s'",
return 0; opt->realm_max_ticket_life_string);
}
if (realm_max_life) {
if (str2deltat (realm_max_life, &max_life) != 0) {
krb5_warnx (context, "unable to parse `%s'", realm_max_life);
return 0; return 0;
} }
} }
if (realm_max_rlife) { if (opt->realm_max_renewable_life_string) {
if (str2deltat (realm_max_rlife, &max_rlife) != 0) { if (str2deltat (opt->realm_max_renewable_life_string, &max_rlife) != 0) {
krb5_warnx (context, "unable to parse `%s'", realm_max_rlife); krb5_warnx (context, "unable to parse `%s'",
opt->realm_max_renewable_life_string);
return 0; return 0;
} }
} }
@@ -169,7 +141,7 @@ init(int argc, char **argv)
return 0; return 0;
} }
db->hdb_close(context, db); db->hdb_close(context, db);
for(i = optind; i < argc; i++){ for(i = 0; i < argc; i++){
krb5_principal princ; krb5_principal princ;
const char *realm = argv[i]; const char *realm = argv[i];
@@ -178,14 +150,14 @@ init(int argc, char **argv)
KRB5_TGS_NAME, realm, NULL); KRB5_TGS_NAME, realm, NULL);
if(ret) if(ret)
return 0; return 0;
if (realm_max_life == NULL) { if (opt->realm_max_ticket_life_string == NULL) {
max_life = 0; max_life = 0;
if(edit_deltat ("Realm max ticket life", &max_life, NULL, 0)) { if(edit_deltat ("Realm max ticket life", &max_life, NULL, 0)) {
krb5_free_principal(context, princ); krb5_free_principal(context, princ);
return 0; return 0;
} }
} }
if (realm_max_rlife == NULL) { if (opt->realm_max_renewable_life_string == NULL) {
max_rlife = 0; max_rlife = 0;
if(edit_deltat("Realm max renewable ticket life", &max_rlife, if(edit_deltat("Realm max renewable ticket life", &max_rlife,
NULL, 0)) { NULL, 0)) {

312
kadmin/kadmin-commands.in Normal file
View File

@@ -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."
}

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -81,91 +81,6 @@ static struct getargs args[] = {
static int num_args = sizeof(args) / sizeof(args[0]); 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; krb5_context context;
void *kadm_handle; void *kadm_handle;
@@ -173,14 +88,40 @@ void *kadm_handle;
static SL_cmd *actual_cmds; static SL_cmd *actual_cmds;
int 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; return 0;
} }
int int
exit_kadmin (int argc, char **argv) exit_kadmin (void *opt, int argc, char **argv)
{ {
return 1; return 1;
} }
@@ -193,30 +134,12 @@ usage(int ret)
} }
int int
get_privs(int argc, char **argv) get_privs(void *opt, int argc, char **argv)
{ {
u_int32_t privs; u_int32_t privs;
char str[128]; char str[128];
kadm5_ret_t ret; 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); ret = kadm5_get_privs(kadm_handle, &privs);
if(ret) if(ret)
krb5_warn(context, ret, "kadm5_get_privs"); krb5_warn(context, ret, "kadm5_get_privs");
@@ -314,7 +237,7 @@ main(int argc, char **argv)
KADM5_ADMIN_SERVICE, KADM5_ADMIN_SERVICE,
&conf, 0, 0, &conf, 0, 0,
&kadm_handle); &kadm_handle);
actual_cmds = commands + 4; /* XXX */ actual_cmds = commands + 5; /* XXX */
} else { } else {
ret = kadm5_c_init_with_password_ctx(context, ret = kadm5_c_init_with_password_ctx(context,
client_name, client_name,

View File

@@ -96,30 +96,11 @@
#include <parse_time.h> #include <parse_time.h>
#include <getarg.h> #include <getarg.h>
#include "kadmin-commands.h"
extern krb5_context context; extern krb5_context context;
extern void * kadm_handle; 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 #undef ALLOC
#define ALLOC(X) ((X) = malloc(sizeof(*(X)))) #define ALLOC(X) ((X) = malloc(sizeof(*(X))))

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -483,58 +483,25 @@ doit(const char *filename, int merge)
} }
static struct getargs args[] = { static int
{ "help", 'h', arg_flag, NULL } loadit(int merge, int argc, char **argv)
};
static int num_args = sizeof(args) / sizeof(args[0]);
static void
usage(const char *name)
{ {
arg_printusage (args, num_args, name, "file"); if(argc != 1) {
} printf("%s file", merge ? "merge" : "load");
return 0;
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 - optind != 1 || help_flag) {
usage ("load");
return 0;
}
doit(argv[optind], 0); doit(argv[optind], 0);
return 0; return 0;
} }
int int
merge(int argc, char **argv) load(void *opt, int argc, char **argv)
{ {
int optind = 0; return loadit(0, argc, argv);
int help_flag = 0; }
args[0].value = &help_flag; int
merge(void *opt, int argc, char **argv)
if(getarg(args, num_args, argc, argv, &optind)) { {
usage ("merge"); return loadit(1, argc, argv);
return 0;
}
if(argc - optind != 1 || help_flag) {
usage ("merge");
return 0;
}
doit(argv[optind], 1);
return 0;
} }

View File

@@ -35,22 +35,13 @@
RCSID("$Id$"); 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 static int
do_mod_entry(krb5_principal principal, void *data) do_mod_entry(krb5_principal principal, void *data)
{ {
krb5_error_code ret; krb5_error_code ret;
kadm5_principal_ent_rec princ; kadm5_principal_ent_rec princ;
int mask = 0; int mask = 0;
struct mod_entry_data *e = data; struct modify_options *e = data;
memset (&princ, 0, sizeof(princ)); memset (&princ, 0, sizeof(princ));
ret = kadm5_get_principal(kadm_handle, principal, &princ, ret = kadm5_get_principal(kadm_handle, principal, &princ,
@@ -61,20 +52,22 @@ do_mod_entry(krb5_principal principal, void *data)
if(ret) if(ret)
return ret; return ret;
if(e->max_life_str || e->max_rlife_str || if(e->max_ticket_life_string ||
e->expiration_str || e->pw_expiration_str || e->attr_str || e->max_renewable_life_string ||
e->new_kvno != -1) { e->expiration_time_string ||
e->pw_expiration_time_string ||
e->attributes_string ||
e->kvno_integer != -1) {
ret = set_entry(context, &princ, &mask, ret = set_entry(context, &princ, &mask,
e->max_life_str, e->max_ticket_life_string,
e->max_rlife_str, e->max_renewable_life_string,
e->expiration_str, e->expiration_time_string,
e->pw_expiration_str, e->pw_expiration_time_string,
e->attr_str); e->attributes_string);
if(e->new_kvno != -1) { if(e->kvno_integer != -1) {
princ.kvno = e->new_kvno; princ.kvno = e->kvno_integer;
mask |= KADM5_KVNO; mask |= KADM5_KVNO;
} }
} else } else
ret = edit_entry(&princ, &mask, NULL, 0); ret = edit_entry(&princ, &mask, NULL, 0);
if(ret == 0) { if(ret == 0) {
@@ -88,64 +81,18 @@ do_mod_entry(krb5_principal principal, void *data)
} }
int int
mod_entry(int argc, char **argv) mod_entry(struct modify_options *opt, int argc, char **argv)
{ {
krb5_error_code ret; krb5_error_code ret;
int optind;
struct mod_entry_data data;
int i; 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) { if (argc < 1) {
printf ("Usage: mod [options] principal\n"); printf ("Usage: mod [options] principal\n");
return 0; return 0;
} }
for(i = 0; i < argc; i++) 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; return 0;
} }

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -35,53 +35,32 @@
RCSID("$Id$"); 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 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_error_code ret;
krb5_principal princ; krb5_principal principal;
krb5_data pw_data; krb5_data pw_data;
const char *s; const char *s;
args[0].value = &help_flag; if(argc != 2) {
printf ("Usage: password-quality principal password\n");
if(getarg(args, num_args, argc, argv, &optind)) {
usage ();
return 0;
}
if(argc - optind != 2 || help_flag) {
usage ();
return 0; return 0;
} }
ret = krb5_parse_name(context, argv[1], &princ); ret = krb5_parse_name(context, argv[0], &principal);
if(ret){ if(ret){
krb5_warn(context, ret, "krb5_parse_name(%s)", argv[1]); krb5_warn(context, ret, "krb5_parse_name(%s)", argv[0]);
return 0; return 0;
} }
pw_data.data = argv[2]; pw_data.data = argv[1];
pw_data.length = strlen(argv[2]); 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) if (s)
krb5_warnx(context, "kadm5_check_password_quality: %s", s); krb5_warnx(context, "kadm5_check_password_quality: %s", s);
krb5_free_principal(context, princ); krb5_free_principal(context, principal);
return 0; return 0;
} }

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -35,47 +35,26 @@
RCSID("$Id$"); 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 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_error_code ret;
krb5_principal princ1, princ2; krb5_principal princ1, princ2;
args[0].value = &help_flag; if(argc != 2) {
printf("rename [options] from to\n");
if(getarg(args, num_args, argc, argv, &optind)) {
usage ();
return 0;
}
if(argc - optind != 2 || help_flag) {
usage ();
return 0; return 0;
} }
ret = krb5_parse_name(context, argv[1], &princ1); ret = krb5_parse_name(context, argv[0], &princ1);
if(ret){ if(ret){
krb5_warn(context, ret, "krb5_parse_name(%s)", argv[1]); krb5_warn(context, ret, "krb5_parse_name(%s)", argv[0]);
return 0; return 0;
} }
ret = krb5_parse_name(context, argv[2], &princ2); ret = krb5_parse_name(context, argv[1], &princ2);
if(ret){ if(ret){
krb5_free_principal(context, princ2); 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; return 0;
} }
ret = kadm5_rename_principal(kadm_handle, princ1, princ2); ret = kadm5_rename_principal(kadm_handle, princ1, princ2);

128
kadmin/stash.c Normal file
View File

@@ -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;
}