1/* $NetBSD: cpw.c,v 1.4 2023/06/19 21:41:41 christos Exp $ */ 2 3/* 4 * Copyright (c) 1997 - 2004 Kungliga Tekniska H��gskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#include "kadmin_locl.h" 37#include "kadmin-commands.h" 38 39struct cpw_entry_data { 40 int keepold; 41 int random_key; 42 int random_password; 43 char *password; 44 krb5_key_data *key_data; 45}; 46 47static int 48set_random_key (krb5_principal principal, int keepold) 49{ 50 krb5_error_code ret; 51 int i; 52 krb5_keyblock *keys; 53 int num_keys; 54 55 ret = kadm5_randkey_principal_3(kadm_handle, principal, keepold, 0, NULL, 56 &keys, &num_keys); 57 if(ret) 58 return ret; 59 for(i = 0; i < num_keys; i++) 60 krb5_free_keyblock_contents(context, &keys[i]); 61 free(keys); 62 return 0; 63} 64 65static int 66set_random_password (krb5_principal principal, int keepold) 67{ 68 krb5_error_code ret; 69 char pw[128]; 70 71 random_password (pw, sizeof(pw)); 72 ret = kadm5_chpass_principal_3(kadm_handle, principal, keepold, 0, NULL, pw); 73 if (ret == 0) { 74 char *princ_name; 75 76 krb5_unparse_name(context, principal, &princ_name); 77 78 printf ("%s's password set to \"%s\"\n", princ_name, pw); 79 free (princ_name); 80 } 81 memset_s(pw, sizeof(pw), 0, sizeof(pw)); 82 return ret; 83} 84 85static int 86set_password (krb5_principal principal, char *password, int keepold) 87{ 88 krb5_error_code ret = 0; 89 char pwbuf[128]; 90 int aret; 91 92 if(password == NULL) { 93 char *princ_name; 94 char *prompt; 95 96 ret = krb5_unparse_name(context, principal, &princ_name); 97 if (ret) 98 return ret; 99 aret = asprintf(&prompt, "%s's Password: ", princ_name); 100 free (princ_name); 101 if (aret == -1) 102 return ENOMEM; 103 ret = UI_UTIL_read_pw_string(pwbuf, sizeof(pwbuf), prompt, 104 UI_UTIL_FLAG_VERIFY | 105 UI_UTIL_FLAG_VERIFY_SILENT); 106 free (prompt); 107 if(ret){ 108 return 0; /* XXX error code? */ 109 } 110 password = pwbuf; 111 } 112 if(ret == 0) 113 ret = kadm5_chpass_principal_3(kadm_handle, principal, keepold, 0, NULL, 114 password); 115 memset_s(pwbuf, sizeof(pwbuf), 0, sizeof(pwbuf)); 116 return ret; 117} 118 119static int 120set_key_data (krb5_principal principal, krb5_key_data *key_data, int keepold) 121{ 122 krb5_error_code ret; 123 124 ret = kadm5_chpass_principal_with_key_3(kadm_handle, principal, keepold, 125 3, key_data); 126 return ret; 127} 128 129static int 130do_cpw_entry(krb5_principal principal, void *data) 131{ 132 struct cpw_entry_data *e = data; 133 134 if (e->random_key) 135 return set_random_key (principal, e->keepold); 136 else if (e->random_password) 137 return set_random_password (principal, e->keepold); 138 else if (e->key_data) 139 return set_key_data (principal, e->key_data, e->keepold); 140 else 141 return set_password (principal, e->password, e->keepold); 142} 143 144int 145cpw_entry(struct passwd_options *opt, int argc, char **argv) 146{ 147 krb5_error_code ret = 0; 148 int i; 149 struct cpw_entry_data data; 150 int num; 151 krb5_key_data key_data[3]; 152 153 data.keepold = opt->keepold_flag; 154 data.random_key = opt->random_key_flag; 155 data.random_password = opt->random_password_flag; 156 data.password = opt->password_string; 157 data.key_data = NULL; 158 159 num = 0; 160 if (data.random_key) 161 ++num; 162 if (data.random_password) 163 ++num; 164 if (data.password) 165 ++num; 166 if (opt->key_string) 167 ++num; 168 169 if (num > 1) { 170 fprintf (stderr, "give only one of " 171 "--random-key, --random-password, --password, --key\n"); 172 return 1; 173 } 174 175 if (opt->key_string) { 176 const char *error; 177 178 if (parse_des_key (opt->key_string, key_data, &error)) { 179 fprintf (stderr, "failed parsing key \"%s\": %s\n", 180 opt->key_string, error); 181 return 1; 182 } 183 data.key_data = key_data; 184 } 185 186 for(i = 0; i < argc; i++) 187 ret = foreach_principal(argv[i], do_cpw_entry, "cpw", &data); 188 189 if (data.key_data) { 190 int16_t dummy; 191 kadm5_free_key_data (kadm_handle, &dummy, key_data); 192 } 193 194 return ret != 0; 195} 196