diff options
Diffstat (limited to 'crypto/heimdal/kpasswd/kpasswd.c')
-rw-r--r-- | crypto/heimdal/kpasswd/kpasswd.c | 227 |
1 files changed, 164 insertions, 63 deletions
diff --git a/crypto/heimdal/kpasswd/kpasswd.c b/crypto/heimdal/kpasswd/kpasswd.c index 02f9557..b844628 100644 --- a/crypto/heimdal/kpasswd/kpasswd.c +++ b/crypto/heimdal/kpasswd/kpasswd.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. * @@ -32,12 +32,16 @@ */ #include "kpasswd_locl.h" -RCSID("$Id: kpasswd.c,v 1.24 2001/09/27 01:29:40 assar Exp $"); +RCSID("$Id: kpasswd.c 19078 2006-11-20 18:12:41Z lha $"); static int version_flag; static int help_flag; +static char *admin_principal_str; +static char *cred_cache_str; static struct getargs args[] = { + { "admin-principal", 0, arg_string, &admin_principal_str }, + { "cache", 'c', arg_string, &cred_cache_str }, { "version", 0, arg_flag, &version_flag }, { "help", 0, arg_flag, &help_flag } }; @@ -45,10 +49,68 @@ static struct getargs args[] = { static void usage (int ret, struct getargs *a, int num_args) { - arg_printusage (a, num_args, NULL, "[principal]"); + arg_printusage (a, num_args, NULL, "[principal ...]"); exit (ret); } +static int +change_password(krb5_context context, + krb5_principal principal, + krb5_ccache id) +{ + krb5_data result_code_string, result_string; + int result_code; + krb5_error_code ret; + char pwbuf[BUFSIZ]; + char *msg, *name; + + krb5_data_zero (&result_code_string); + krb5_data_zero (&result_string); + + name = msg = NULL; + if (principal == NULL) + asprintf(&msg, "New password: "); + else { + ret = krb5_unparse_name(context, principal, &name); + if (ret) + krb5_err(context, 1, ret, "krb5_unparse_name"); + + asprintf(&msg, "New password for %s: ", name); + } + + if (msg == NULL) + krb5_errx (context, 1, "out of memory"); + + ret = UI_UTIL_read_pw_string (pwbuf, sizeof(pwbuf), msg, 1); + free(msg); + if (name) + free(name); + if (ret != 0) { + return 1; + } + + ret = krb5_set_password_using_ccache (context, id, pwbuf, + principal, + &result_code, + &result_code_string, + &result_string); + if (ret) { + krb5_warn (context, ret, "krb5_set_password_using_ccache"); + return 1; + } + + printf ("%s%s%.*s\n", krb5_passwd_result_to_string(context, result_code), + result_string.length > 0 ? " : " : "", + (int)result_string.length, + result_string.length > 0 ? (char *)result_string.data : ""); + + krb5_data_free (&result_code_string); + krb5_data_free (&result_string); + + return ret != 0; +} + + int main (int argc, char **argv) { @@ -56,11 +118,9 @@ main (int argc, char **argv) krb5_context context; krb5_principal principal; int optind = 0; - krb5_get_init_creds_opt opt; - krb5_creds cred; - int result_code; - krb5_data result_code_string, result_string; - char pwbuf[BUFSIZ]; + krb5_get_init_creds_opt *opt; + krb5_ccache id = NULL; + int exit_value; optind = krb5_program_setup(&context, argc, argv, args, sizeof(args) / sizeof(args[0]), usage); @@ -73,74 +133,115 @@ main (int argc, char **argv) exit(0); } - krb5_get_init_creds_opt_init (&opt); - - krb5_get_init_creds_opt_set_tkt_life (&opt, 300); - krb5_get_init_creds_opt_set_forwardable (&opt, FALSE); - krb5_get_init_creds_opt_set_proxiable (&opt, FALSE); - argc -= optind; argv += optind; - if (argc > 1) - usage (1, args, sizeof(args) / sizeof(args[0])); - ret = krb5_init_context (&context); if (ret) errx (1, "krb5_init_context failed: %d", ret); - if(argv[0]) { - ret = krb5_parse_name (context, argv[0], &principal); + ret = krb5_get_init_creds_opt_alloc (context, &opt); + if (ret) + krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc"); + + krb5_get_init_creds_opt_set_tkt_life (opt, 300); + krb5_get_init_creds_opt_set_forwardable (opt, FALSE); + krb5_get_init_creds_opt_set_proxiable (opt, FALSE); + + if (cred_cache_str) { + ret = krb5_cc_resolve(context, cred_cache_str, &id); if (ret) - krb5_err (context, 1, ret, "krb5_parse_name"); - } else - principal = NULL; - - ret = krb5_get_init_creds_password (context, - &cred, - principal, - NULL, - krb5_prompter_posix, - NULL, - 0, - "kadmin/changepw", - &opt); - switch (ret) { - case 0: - break; - case KRB5_LIBOS_PWDINTR : - return 1; - case KRB5KRB_AP_ERR_BAD_INTEGRITY : - case KRB5KRB_AP_ERR_MODIFIED : - krb5_errx(context, 1, "Password incorrect"); - break; - default: - krb5_err(context, 1, ret, "krb5_get_init_creds"); + krb5_err (context, 1, ret, "krb5_cc_resolve"); + } else { + ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &id); + if (ret) + krb5_err (context, 1, ret, "krb5_cc_gen_new"); } - krb5_data_zero (&result_code_string); - krb5_data_zero (&result_string); + if (cred_cache_str == NULL) { + krb5_principal admin_principal = NULL; + krb5_creds cred; + + if (admin_principal_str) { + ret = krb5_parse_name (context, admin_principal_str, + &admin_principal); + if (ret) + krb5_err (context, 1, ret, "krb5_parse_name"); + } else if (argc == 1) { + ret = krb5_parse_name (context, argv[0], &admin_principal); + if (ret) + krb5_err (context, 1, ret, "krb5_parse_name"); + } else { + ret = krb5_get_default_principal (context, &admin_principal); + if (ret) + krb5_err (context, 1, ret, "krb5_get_default_principal"); + } + + ret = krb5_get_init_creds_password (context, + &cred, + admin_principal, + NULL, + krb5_prompter_posix, + NULL, + 0, + "kadmin/changepw", + opt); + switch (ret) { + case 0: + break; + case KRB5_LIBOS_PWDINTR : + return 1; + case KRB5KRB_AP_ERR_BAD_INTEGRITY : + case KRB5KRB_AP_ERR_MODIFIED : + krb5_errx(context, 1, "Password incorrect"); + break; + default: + krb5_err(context, 1, ret, "krb5_get_init_creds"); + } + + krb5_get_init_creds_opt_free(context, opt); + + ret = krb5_cc_initialize(context, id, admin_principal); + krb5_free_principal(context, admin_principal); + if (ret) + krb5_err(context, 1, ret, "krb5_cc_initialize"); - if(des_read_pw_string (pwbuf, sizeof(pwbuf), "New password: ", 1) != 0) - return 1; + ret = krb5_cc_store_cred(context, id, &cred); + if (ret) + krb5_err(context, 1, ret, "krb5_cc_store_cred"); + + krb5_free_cred_contents (context, &cred); + } - ret = krb5_change_password (context, &cred, pwbuf, - &result_code, - &result_code_string, - &result_string); - if (ret) - krb5_err (context, 1, ret, "krb5_change_password"); + if (argc == 0) { + exit_value = change_password(context, NULL, id); + } else { + exit_value = 0; - printf ("%s%s%.*s\n", krb5_passwd_result_to_string(context, - result_code), - result_string.length > 0 ? " : " : "", - (int)result_string.length, - (char *)result_string.data); + while (argc-- > 0) { + + ret = krb5_parse_name (context, argv[0], &principal); + if (ret) + krb5_err (context, 1, ret, "krb5_parse_name"); + + ret = change_password(context, principal, id); + if (ret) + exit_value = 1; + krb5_free_principal(context, principal); + argv++; + } + } + + if (cred_cache_str == NULL) { + ret = krb5_cc_destroy(context, id); + if (ret) + krb5_err (context, 1, ret, "krb5_cc_destroy"); + } else { + ret = krb5_cc_close(context, id); + if (ret) + krb5_err (context, 1, ret, "krb5_cc_close"); + } - krb5_data_free (&result_code_string); - krb5_data_free (&result_string); - - krb5_free_creds_contents (context, &cred); krb5_free_context (context); - return result_code; + return ret; } |