192108Sphk/* 292108Sphk * Copyright (c) 1997-2004 Kungliga Tekniska H��gskolan 392108Sphk * (Royal Institute of Technology, Stockholm, Sweden). 492108Sphk * All rights reserved. 592108Sphk * 692108Sphk * Redistribution and use in source and binary forms, with or without 792108Sphk * modification, are permitted provided that the following conditions 892108Sphk * are met: 992108Sphk * 1092108Sphk * 1. Redistributions of source code must retain the above copyright 1192108Sphk * notice, this list of conditions and the following disclaimer. 1292108Sphk * 1392108Sphk * 2. Redistributions in binary form must reproduce the above copyright 1492108Sphk * notice, this list of conditions and the following disclaimer in the 1592108Sphk * documentation and/or other materials provided with the distribution. 1692108Sphk * 1792108Sphk * 3. Neither the name of the Institute nor the names of its contributors 1892108Sphk * may be used to endorse or promote products derived from this software 1992108Sphk * without specific prior written permission. 2092108Sphk * 2192108Sphk * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2292108Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2392108Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2492108Sphk * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2592108Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2692108Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2792108Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2892108Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2992108Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3092108Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3192108Sphk * SUCH DAMAGE. 3292108Sphk */ 3392108Sphk 3492108Sphk#include "kpasswd_locl.h" 3592108SphkRCSID("$Id$"); 36116196Sobrien 37116196Sobrienstatic int version_flag; 3892108Sphkstatic int help_flag; 3992108Sphkstatic char *admin_principal_str; 4092108Sphkstatic char *cred_cache_str; 4192108Sphk 4292108Sphkstatic struct getargs args[] = { 4392108Sphk { "admin-principal", 0, arg_string, &admin_principal_str, NULL, 4492108Sphk NULL }, 4592108Sphk { "cache", 'c', arg_string, &cred_cache_str, NULL, NULL }, 4692108Sphk { "version", 0, arg_flag, &version_flag, NULL, NULL }, 4792108Sphk { "help", 0, arg_flag, &help_flag, NULL, NULL } 4892108Sphk}; 4992108Sphk 5092108Sphkstatic void 5192108Sphkusage (int ret, struct getargs *a, int num_args) 5292108Sphk{ 5392108Sphk arg_printusage (a, num_args, NULL, "[principal ...]"); 5492108Sphk exit (ret); 5593776Sphk} 5693776Sphk 5793776Sphkstatic int 5895321Sphkchange_password(krb5_context context, 59114493Sphk krb5_principal principal, 6092108Sphk krb5_ccache id) 6192108Sphk{ 6292108Sphk krb5_data result_code_string, result_string; 63111119Simp int result_code; 64131046Spjd krb5_error_code ret; 65131046Spjd char pwbuf[BUFSIZ]; 66131046Spjd char *msg, *name; 67131046Spjd 68104057Sphk krb5_data_zero (&result_code_string); 69111119Simp krb5_data_zero (&result_string); 7092108Sphk 7192108Sphk name = msg = NULL; 7292108Sphk if (principal == NULL) 7392108Sphk asprintf(&msg, "New password: "); 74114493Sphk else { 75114493Sphk ret = krb5_unparse_name(context, principal, &name); 76114493Sphk if (ret) 77114493Sphk krb5_err(context, 1, ret, "krb5_unparse_name"); 78132631Sle 79132631Sle asprintf(&msg, "New password for %s: ", name); 80114493Sphk } 81114493Sphk 82114493Sphk if (msg == NULL) 83131408Spjd krb5_errx (context, 1, "out of memory"); 84131408Spjd 85114493Sphk ret = UI_UTIL_read_pw_string (pwbuf, sizeof(pwbuf), msg, 1); 86114493Sphk free(msg); 87114493Sphk if (name) 8893776Sphk free(name); 8992108Sphk if (ret != 0) { 9092108Sphk return 1; 91107953Sphk } 92107953Sphk 9392108Sphk ret = krb5_set_password_using_ccache (context, id, pwbuf, 9492108Sphk principal, 9592108Sphk &result_code, 9692108Sphk &result_code_string, 9792108Sphk &result_string); 9892108Sphk if (ret) { 9992108Sphk krb5_warn (context, ret, "krb5_set_password_using_ccache"); 10092108Sphk return 1; 10192108Sphk } 10292108Sphk 103131568Sphk printf ("%s%s%.*s\n", krb5_passwd_result_to_string(context, result_code), 104131568Sphk result_string.length > 0 ? " : " : "", 105131568Sphk (int)result_string.length, 106131568Sphk result_string.length > 0 ? (char *)result_string.data : ""); 107131568Sphk 108131568Sphk krb5_data_free (&result_code_string); 109131568Sphk krb5_data_free (&result_string); 110131568Sphk 111131568Sphk return ret != 0; 112131568Sphk} 113131568Sphk 114131568Sphk 115131568Sphkint 116131568Sphkmain (int argc, char **argv) 117131568Sphk{ 118131568Sphk krb5_error_code ret; 119131568Sphk krb5_context context; 120131568Sphk krb5_principal principal; 121131568Sphk krb5_get_init_creds_opt *opt; 12292108Sphk krb5_ccache id = NULL; 12392108Sphk int exit_value; 12492108Sphk int optidx = 0; 12592108Sphk 12692108Sphk setprogname(argv[0]); 12792108Sphk 12892108Sphk if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) 129125755Sphk usage(1, args, sizeof(args) / sizeof(args[0])); 13092108Sphk if (help_flag) 13192108Sphk usage(0, args, sizeof(args) / sizeof(args[0])); 13292108Sphk if (version_flag) { 133113713Sphk print_version(NULL); 134113713Sphk return 0; 135113713Sphk } 136113713Sphk argc -= optidx; 137113713Sphk argv += optidx; 138113713Sphk 139113713Sphk ret = krb5_init_context (&context); 140107522Sphk if (ret) 141107522Sphk errx (1, "krb5_init_context failed: %d", ret); 142107522Sphk 143107522Sphk ret = krb5_get_init_creds_opt_alloc (context, &opt); 144107522Sphk if (ret) 145107522Sphk krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc"); 146107522Sphk 147107522Sphk krb5_get_init_creds_opt_set_tkt_life (opt, 300); 148107953Sphk krb5_get_init_creds_opt_set_forwardable (opt, FALSE); 149107522Sphk krb5_get_init_creds_opt_set_proxiable (opt, FALSE); 150113713Sphk 151113713Sphk if (cred_cache_str) { 152113713Sphk ret = krb5_cc_resolve(context, cred_cache_str, &id); 153113713Sphk if (ret) 154107522Sphk krb5_err (context, 1, ret, "krb5_cc_resolve"); 155107522Sphk } else { 156107522Sphk ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id); 157107522Sphk if (ret) 158107953Sphk krb5_err (context, 1, ret, "krb5_cc_new_unique"); 159107953Sphk } 160107522Sphk 161107522Sphk if (cred_cache_str == NULL) { 162107522Sphk krb5_principal admin_principal = NULL; 163107522Sphk krb5_creds cred; 164107522Sphk 165107522Sphk if (admin_principal_str) { 166107522Sphk ret = krb5_parse_name (context, admin_principal_str, 167107522Sphk &admin_principal); 168107522Sphk if (ret) 169107522Sphk krb5_err (context, 1, ret, "krb5_parse_name"); 170107522Sphk } else if (argc == 1) { 171107522Sphk ret = krb5_parse_name (context, argv[0], &admin_principal); 172107522Sphk if (ret) 173107522Sphk krb5_err (context, 1, ret, "krb5_parse_name"); 17493776Sphk } else { 175169288Spjd ret = krb5_get_default_principal (context, &admin_principal); 176169288Spjd if (ret) 177169288Spjd krb5_err (context, 1, ret, "krb5_get_default_principal"); 178169288Spjd } 179169288Spjd 180169288Spjd ret = krb5_get_init_creds_password (context, 181169288Spjd &cred, 182169288Spjd admin_principal, 183169288Spjd NULL, 184169288Spjd krb5_prompter_posix, 185169288Spjd NULL, 186169288Spjd 0, 187169288Spjd "kadmin/changepw", 188169288Spjd opt); 189169288Spjd switch (ret) { 190169288Spjd case 0: 191169288Spjd break; 192169288Spjd case KRB5_LIBOS_PWDINTR : 193169288Spjd return 1; 194169288Spjd case KRB5KRB_AP_ERR_BAD_INTEGRITY : 195169288Spjd case KRB5KRB_AP_ERR_MODIFIED : 196169288Spjd krb5_errx(context, 1, "Password incorrect"); 19792108Sphk break; 19892108Sphk default: 19992108Sphk krb5_err(context, 1, ret, "krb5_get_init_creds"); 20092108Sphk } 20192108Sphk 20292108Sphk krb5_get_init_creds_opt_free(context, opt); 20392108Sphk 204113712Sphk ret = krb5_cc_initialize(context, id, admin_principal); 205113713Sphk krb5_free_principal(context, admin_principal); 206107953Sphk if (ret) 207107522Sphk krb5_err(context, 1, ret, "krb5_cc_initialize"); 20894287Sphk 20992108Sphk ret = krb5_cc_store_cred(context, id, &cred); 21092108Sphk if (ret) 21192108Sphk krb5_err(context, 1, ret, "krb5_cc_store_cred"); 21292108Sphk 21392108Sphk krb5_free_cred_contents (context, &cred); 214107953Sphk } 215107953Sphk 21692108Sphk if (argc == 0) { 21792108Sphk exit_value = change_password(context, NULL, id); 21892108Sphk } else { 21992108Sphk exit_value = 0; 22092108Sphk 221104195Sphk while (argc-- > 0) { 22292108Sphk 22392108Sphk ret = krb5_parse_name (context, argv[0], &principal); 224107522Sphk if (ret) 225107522Sphk krb5_err (context, 1, ret, "krb5_parse_name"); 226107522Sphk 227107522Sphk ret = change_password(context, principal, id); 228107832Sphk if (ret) 229113712Sphk exit_value = 1; 230113713Sphk krb5_free_principal(context, principal); 231113713Sphk argv++; 232107522Sphk } 233113713Sphk } 234107522Sphk 235113713Sphk if (cred_cache_str == NULL) { 236113713Sphk ret = krb5_cc_destroy(context, id); 237113713Sphk if (ret) 238113713Sphk krb5_err (context, 1, ret, "krb5_cc_destroy"); 239113713Sphk } else { 240113713Sphk ret = krb5_cc_close(context, id); 241113713Sphk if (ret) 242113713Sphk krb5_err (context, 1, ret, "krb5_cc_close"); 243113713Sphk } 244113713Sphk 245113713Sphk krb5_free_context (context); 246107522Sphk return exit_value; 247113713Sphk} 248113713Sphk