1 /* $NetBSD: cpw.c,v 1.3 2019/12/15 22:50:46 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 39 struct 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 47 static int 48 set_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 65 static int 66 set_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 85 static int 86 set_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, 1); 104 free (prompt); 105 if(ret){ 106 return 0; /* XXX error code? */ 107 } 108 password = pwbuf; 109 } 110 if(ret == 0) 111 ret = kadm5_chpass_principal_3(kadm_handle, principal, keepold, 0, NULL, 112 password); 113 memset_s(pwbuf, sizeof(pwbuf), 0, sizeof(pwbuf)); 114 return ret; 115 } 116 117 static int 118 set_key_data (krb5_principal principal, krb5_key_data *key_data, int keepold) 119 { 120 krb5_error_code ret; 121 122 ret = kadm5_chpass_principal_with_key_3(kadm_handle, principal, keepold, 123 3, key_data); 124 return ret; 125 } 126 127 static int 128 do_cpw_entry(krb5_principal principal, void *data) 129 { 130 struct cpw_entry_data *e = data; 131 132 if (e->random_key) 133 return set_random_key (principal, e->keepold); 134 else if (e->random_password) 135 return set_random_password (principal, e->keepold); 136 else if (e->key_data) 137 return set_key_data (principal, e->key_data, e->keepold); 138 else 139 return set_password (principal, e->password, e->keepold); 140 } 141 142 int 143 cpw_entry(struct passwd_options *opt, int argc, char **argv) 144 { 145 krb5_error_code ret = 0; 146 int i; 147 struct cpw_entry_data data; 148 int num; 149 krb5_key_data key_data[3]; 150 151 data.keepold = opt->keepold_flag; 152 data.random_key = opt->random_key_flag; 153 data.random_password = opt->random_password_flag; 154 data.password = opt->password_string; 155 data.key_data = NULL; 156 157 num = 0; 158 if (data.random_key) 159 ++num; 160 if (data.random_password) 161 ++num; 162 if (data.password) 163 ++num; 164 if (opt->key_string) 165 ++num; 166 167 if (num > 1) { 168 fprintf (stderr, "give only one of " 169 "--random-key, --random-password, --password, --key\n"); 170 return 1; 171 } 172 173 if (opt->key_string) { 174 const char *error; 175 176 if (parse_des_key (opt->key_string, key_data, &error)) { 177 fprintf (stderr, "failed parsing key \"%s\": %s\n", 178 opt->key_string, error); 179 return 1; 180 } 181 data.key_data = key_data; 182 } 183 184 for(i = 0; i < argc; i++) 185 ret = foreach_principal(argv[i], do_cpw_entry, "cpw", &data); 186 187 if (data.key_data) { 188 int16_t dummy; 189 kadm5_free_key_data (kadm_handle, &dummy, key_data); 190 } 191 192 return ret != 0; 193 } 194