1b528cefcSMark Murray /* 2c19800e8SDoug Rabson * Copyright (c) 1997-2005 Kungliga Tekniska H�gskolan 3b528cefcSMark Murray * (Royal Institute of Technology, Stockholm, Sweden). 4b528cefcSMark Murray * All rights reserved. 5b528cefcSMark Murray * 6b528cefcSMark Murray * Redistribution and use in source and binary forms, with or without 7b528cefcSMark Murray * modification, are permitted provided that the following conditions 8b528cefcSMark Murray * are met: 9b528cefcSMark Murray * 10b528cefcSMark Murray * 1. Redistributions of source code must retain the above copyright 11b528cefcSMark Murray * notice, this list of conditions and the following disclaimer. 12b528cefcSMark Murray * 13b528cefcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright 14b528cefcSMark Murray * notice, this list of conditions and the following disclaimer in the 15b528cefcSMark Murray * documentation and/or other materials provided with the distribution. 16b528cefcSMark Murray * 17b528cefcSMark Murray * 3. Neither the name of the Institute nor the names of its contributors 18b528cefcSMark Murray * may be used to endorse or promote products derived from this software 19b528cefcSMark Murray * without specific prior written permission. 20b528cefcSMark Murray * 21b528cefcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22b528cefcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23b528cefcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24b528cefcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25b528cefcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26b528cefcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27b528cefcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28b528cefcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29b528cefcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30b528cefcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31b528cefcSMark Murray * SUCH DAMAGE. 32b528cefcSMark Murray */ 33b528cefcSMark Murray 34b528cefcSMark Murray #include "ktutil_locl.h" 35b528cefcSMark Murray 36c19800e8SDoug Rabson RCSID("$Id: change.c 15578 2005-07-07 20:44:48Z lha $"); 37b528cefcSMark Murray 38c19800e8SDoug Rabson static krb5_error_code 39c19800e8SDoug Rabson change_entry (krb5_keytab keytab, 40bbd80c28SJacques Vidrine krb5_principal principal, krb5_kvno kvno, 41b528cefcSMark Murray const char *realm, const char *admin_server, int server_port) 42b528cefcSMark Murray { 43b528cefcSMark Murray krb5_error_code ret; 44b528cefcSMark Murray kadm5_config_params conf; 45b528cefcSMark Murray void *kadm_handle; 46b528cefcSMark Murray char *client_name; 47b528cefcSMark Murray krb5_keyblock *keys; 48b528cefcSMark Murray int num_keys; 49b528cefcSMark Murray int i; 50b528cefcSMark Murray 51bbd80c28SJacques Vidrine ret = krb5_unparse_name (context, principal, &client_name); 52b528cefcSMark Murray if (ret) { 53adb0ddaeSAssar Westerlund krb5_warn (context, ret, "krb5_unparse_name"); 54c19800e8SDoug Rabson return ret; 55b528cefcSMark Murray } 56b528cefcSMark Murray 57b528cefcSMark Murray memset (&conf, 0, sizeof(conf)); 58b528cefcSMark Murray 59c19800e8SDoug Rabson if(realm == NULL) 60c19800e8SDoug Rabson realm = krb5_principal_get_realm(context, principal); 61c19800e8SDoug Rabson conf.realm = strdup(realm); 62c19800e8SDoug Rabson if (conf.realm == NULL) { 63c19800e8SDoug Rabson free (client_name); 64c19800e8SDoug Rabson krb5_set_error_string(context, "malloc failed"); 65c19800e8SDoug Rabson return ENOMEM; 66c19800e8SDoug Rabson } 67b528cefcSMark Murray conf.mask |= KADM5_CONFIG_REALM; 68b528cefcSMark Murray 69b528cefcSMark Murray if (admin_server) { 70c19800e8SDoug Rabson conf.admin_server = strdup(admin_server); 71c19800e8SDoug Rabson if (conf.admin_server == NULL) { 72c19800e8SDoug Rabson free(client_name); 73c19800e8SDoug Rabson free(conf.realm); 74c19800e8SDoug Rabson krb5_set_error_string(context, "malloc failed"); 75c19800e8SDoug Rabson return ENOMEM; 76c19800e8SDoug Rabson } 77b528cefcSMark Murray conf.mask |= KADM5_CONFIG_ADMIN_SERVER; 78b528cefcSMark Murray } 79b528cefcSMark Murray 80b528cefcSMark Murray if (server_port) { 81b528cefcSMark Murray conf.kadmind_port = htons(server_port); 82b528cefcSMark Murray conf.mask |= KADM5_CONFIG_KADMIND_PORT; 83b528cefcSMark Murray } 84b528cefcSMark Murray 85b528cefcSMark Murray ret = kadm5_init_with_skey_ctx (context, 86b528cefcSMark Murray client_name, 87b528cefcSMark Murray keytab_string, 88b528cefcSMark Murray KADM5_ADMIN_SERVICE, 89b528cefcSMark Murray &conf, 0, 0, 90b528cefcSMark Murray &kadm_handle); 91c19800e8SDoug Rabson free(conf.admin_server); 92c19800e8SDoug Rabson free(conf.realm); 93b528cefcSMark Murray if (ret) { 94c19800e8SDoug Rabson krb5_warn (context, ret, 95c19800e8SDoug Rabson "kadm5_c_init_with_skey_ctx: %s:", client_name); 96c19800e8SDoug Rabson free (client_name); 97c19800e8SDoug Rabson return ret; 98b528cefcSMark Murray } 99bbd80c28SJacques Vidrine ret = kadm5_randkey_principal (kadm_handle, principal, &keys, &num_keys); 100b528cefcSMark Murray kadm5_destroy (kadm_handle); 101b528cefcSMark Murray if (ret) { 102c19800e8SDoug Rabson krb5_warn(context, ret, "kadm5_randkey_principal: %s:", client_name); 103c19800e8SDoug Rabson free (client_name); 104c19800e8SDoug Rabson return ret; 105b528cefcSMark Murray } 106c19800e8SDoug Rabson free (client_name); 107b528cefcSMark Murray for (i = 0; i < num_keys; ++i) { 108b528cefcSMark Murray krb5_keytab_entry new_entry; 109b528cefcSMark Murray 110bbd80c28SJacques Vidrine new_entry.principal = principal; 111b528cefcSMark Murray new_entry.timestamp = time (NULL); 112bbd80c28SJacques Vidrine new_entry.vno = kvno + 1; 113b528cefcSMark Murray new_entry.keyblock = keys[i]; 114b528cefcSMark Murray 115b528cefcSMark Murray ret = krb5_kt_add_entry (context, keytab, &new_entry); 116b528cefcSMark Murray if (ret) 117b528cefcSMark Murray krb5_warn (context, ret, "krb5_kt_add_entry"); 118b528cefcSMark Murray krb5_free_keyblock_contents (context, &keys[i]); 119b528cefcSMark Murray } 120c19800e8SDoug Rabson return ret; 121b528cefcSMark Murray } 122b528cefcSMark Murray 123b528cefcSMark Murray /* 124b528cefcSMark Murray * loop over all the entries in the keytab (or those given) and change 125b528cefcSMark Murray * their keys, writing the new keys 126b528cefcSMark Murray */ 127b528cefcSMark Murray 128bbd80c28SJacques Vidrine struct change_set { 129bbd80c28SJacques Vidrine krb5_principal principal; 130bbd80c28SJacques Vidrine krb5_kvno kvno; 131bbd80c28SJacques Vidrine }; 132bbd80c28SJacques Vidrine 133b528cefcSMark Murray int 134c19800e8SDoug Rabson kt_change (struct change_options *opt, int argc, char **argv) 135b528cefcSMark Murray { 136b528cefcSMark Murray krb5_error_code ret; 137adb0ddaeSAssar Westerlund krb5_keytab keytab; 138b528cefcSMark Murray krb5_kt_cursor cursor; 139b528cefcSMark Murray krb5_keytab_entry entry; 140bbd80c28SJacques Vidrine int i, j, max; 141bbd80c28SJacques Vidrine struct change_set *changeset; 142c19800e8SDoug Rabson int errors = 0; 143b528cefcSMark Murray 1444137ff4cSJacques Vidrine if((keytab = ktutil_open_keytab()) == NULL) 145adb0ddaeSAssar Westerlund return 1; 146adb0ddaeSAssar Westerlund 147b528cefcSMark Murray j = 0; 148bbd80c28SJacques Vidrine max = 0; 149bbd80c28SJacques Vidrine changeset = NULL; 150b528cefcSMark Murray 151b528cefcSMark Murray ret = krb5_kt_start_seq_get(context, keytab, &cursor); 152b528cefcSMark Murray if(ret){ 153c19800e8SDoug Rabson krb5_warn(context, ret, "%s", keytab_string); 154adb0ddaeSAssar Westerlund goto out; 155b528cefcSMark Murray } 156b528cefcSMark Murray 157b528cefcSMark Murray while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) { 158bbd80c28SJacques Vidrine int add = 0; 159b528cefcSMark Murray 160bbd80c28SJacques Vidrine for (i = 0; i < j; ++i) { 161bbd80c28SJacques Vidrine if (krb5_principal_compare (context, changeset[i].principal, 162bbd80c28SJacques Vidrine entry.principal)) { 163bbd80c28SJacques Vidrine if (changeset[i].kvno < entry.vno) 164bbd80c28SJacques Vidrine changeset[i].kvno = entry.vno; 165b528cefcSMark Murray break; 166bbd80c28SJacques Vidrine } 167bbd80c28SJacques Vidrine } 168c19800e8SDoug Rabson if (i < j) { 169c19800e8SDoug Rabson krb5_kt_free_entry (context, &entry); 170b528cefcSMark Murray continue; 171c19800e8SDoug Rabson } 172b528cefcSMark Murray 173c19800e8SDoug Rabson if (argc == 0) { 174bbd80c28SJacques Vidrine add = 1; 175b528cefcSMark Murray } else { 176c19800e8SDoug Rabson for (i = 0; i < argc; ++i) { 177b528cefcSMark Murray krb5_principal princ; 178b528cefcSMark Murray 179b528cefcSMark Murray ret = krb5_parse_name (context, argv[i], &princ); 180b528cefcSMark Murray if (ret) { 181c19800e8SDoug Rabson krb5_warn (context, ret, "%s", argv[i]); 182b528cefcSMark Murray continue; 183b528cefcSMark Murray } 184bbd80c28SJacques Vidrine if (krb5_principal_compare (context, princ, entry.principal)) 185bbd80c28SJacques Vidrine add = 1; 186bbd80c28SJacques Vidrine 187b528cefcSMark Murray krb5_free_principal (context, princ); 188b528cefcSMark Murray } 189b528cefcSMark Murray } 190bbd80c28SJacques Vidrine 191bbd80c28SJacques Vidrine if (add) { 192b528cefcSMark Murray if (j >= max) { 193b528cefcSMark Murray void *tmp; 194b528cefcSMark Murray 195bbd80c28SJacques Vidrine max = max(max * 2, 1); 196bbd80c28SJacques Vidrine tmp = realloc (changeset, max * sizeof(*changeset)); 197b528cefcSMark Murray if (tmp == NULL) { 198b528cefcSMark Murray krb5_kt_free_entry (context, &entry); 199b528cefcSMark Murray krb5_warnx (context, "realloc: out of memory"); 200bbd80c28SJacques Vidrine ret = ENOMEM; 201b528cefcSMark Murray break; 202b528cefcSMark Murray } 203bbd80c28SJacques Vidrine changeset = tmp; 204b528cefcSMark Murray } 205bbd80c28SJacques Vidrine ret = krb5_copy_principal (context, entry.principal, 206bbd80c28SJacques Vidrine &changeset[j].principal); 207b528cefcSMark Murray if (ret) { 208b528cefcSMark Murray krb5_warn (context, ret, "krb5_copy_principal"); 209b528cefcSMark Murray krb5_kt_free_entry (context, &entry); 210b528cefcSMark Murray break; 211b528cefcSMark Murray } 212bbd80c28SJacques Vidrine changeset[j].kvno = entry.vno; 213b528cefcSMark Murray ++j; 214b528cefcSMark Murray } 215b528cefcSMark Murray krb5_kt_free_entry (context, &entry); 216b528cefcSMark Murray } 217c19800e8SDoug Rabson krb5_kt_end_seq_get(context, keytab, &cursor); 218bbd80c28SJacques Vidrine 219bbd80c28SJacques Vidrine if (ret == KRB5_KT_END) { 220c19800e8SDoug Rabson ret = 0; 221bbd80c28SJacques Vidrine for (i = 0; i < j; i++) { 222bbd80c28SJacques Vidrine if (verbose_flag) { 223bbd80c28SJacques Vidrine char *client_name; 224bbd80c28SJacques Vidrine 225bbd80c28SJacques Vidrine ret = krb5_unparse_name (context, changeset[i].principal, 226bbd80c28SJacques Vidrine &client_name); 227bbd80c28SJacques Vidrine if (ret) { 228bbd80c28SJacques Vidrine krb5_warn (context, ret, "krb5_unparse_name"); 229bbd80c28SJacques Vidrine } else { 230bbd80c28SJacques Vidrine printf("Changing %s kvno %d\n", 231bbd80c28SJacques Vidrine client_name, changeset[i].kvno); 232bbd80c28SJacques Vidrine free(client_name); 233bbd80c28SJacques Vidrine } 234bbd80c28SJacques Vidrine } 235c19800e8SDoug Rabson ret = change_entry (keytab, 236bbd80c28SJacques Vidrine changeset[i].principal, changeset[i].kvno, 237c19800e8SDoug Rabson opt->realm_string, 238c19800e8SDoug Rabson opt->admin_server_string, 239c19800e8SDoug Rabson opt->server_port_integer); 240c19800e8SDoug Rabson if (ret != 0) 241c19800e8SDoug Rabson errors = 1; 242bbd80c28SJacques Vidrine } 243c19800e8SDoug Rabson } else 244c19800e8SDoug Rabson errors = 1; 245bbd80c28SJacques Vidrine for (i = 0; i < j; i++) 246bbd80c28SJacques Vidrine krb5_free_principal (context, changeset[i].principal); 247bbd80c28SJacques Vidrine free (changeset); 248bbd80c28SJacques Vidrine 249adb0ddaeSAssar Westerlund out: 250adb0ddaeSAssar Westerlund krb5_kt_close(context, keytab); 251c19800e8SDoug Rabson return errors; 252b528cefcSMark Murray } 253