2 * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include "ktutil_locl.h"
38 static krb5_error_code
39 change_entry (krb5_keytab keytab,
40 krb5_principal principal, krb5_kvno kvno,
41 const char *realm, const char *admin_server, int server_port)
44 kadm5_config_params conf;
51 ret = krb5_unparse_name (context, principal, &client_name);
53 krb5_warn (context, ret, "krb5_unparse_name");
57 memset (&conf, 0, sizeof(conf));
60 realm = krb5_principal_get_realm(context, principal);
61 conf.realm = strdup(realm);
62 if (conf.realm == NULL) {
64 krb5_set_error_message(context, ENOMEM, "malloc failed");
67 conf.mask |= KADM5_CONFIG_REALM;
70 conf.admin_server = strdup(admin_server);
71 if (conf.admin_server == NULL) {
74 krb5_set_error_message(context, ENOMEM, "malloc failed");
77 conf.mask |= KADM5_CONFIG_ADMIN_SERVER;
81 conf.kadmind_port = htons(server_port);
82 conf.mask |= KADM5_CONFIG_KADMIND_PORT;
85 ret = kadm5_init_with_skey_ctx (context,
91 free(conf.admin_server);
94 krb5_warn (context, ret,
95 "kadm5_c_init_with_skey_ctx: %s:", client_name);
99 ret = kadm5_randkey_principal (kadm_handle, principal, &keys, &num_keys);
100 kadm5_destroy (kadm_handle);
102 krb5_warn(context, ret, "kadm5_randkey_principal: %s:", client_name);
107 for (i = 0; i < num_keys; ++i) {
108 krb5_keytab_entry new_entry;
110 new_entry.principal = principal;
111 new_entry.timestamp = time (NULL);
112 new_entry.vno = kvno + 1;
113 new_entry.keyblock = keys[i];
115 ret = krb5_kt_add_entry (context, keytab, &new_entry);
117 krb5_warn (context, ret, "krb5_kt_add_entry");
118 krb5_free_keyblock_contents (context, &keys[i]);
124 * loop over all the entries in the keytab (or those given) and change
125 * their keys, writing the new keys
129 krb5_principal principal;
134 kt_change (struct change_options *opt, int argc, char **argv)
138 krb5_kt_cursor cursor;
139 krb5_keytab_entry entry;
141 struct change_set *changeset;
144 if((keytab = ktutil_open_keytab()) == NULL)
151 ret = krb5_kt_start_seq_get(context, keytab, &cursor);
153 krb5_warn(context, ret, "%s", keytab_string);
157 while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) {
160 for (i = 0; i < j; ++i) {
161 if (krb5_principal_compare (context, changeset[i].principal,
163 if (changeset[i].kvno < entry.vno)
164 changeset[i].kvno = entry.vno;
169 krb5_kt_free_entry (context, &entry);
176 for (i = 0; i < argc; ++i) {
177 krb5_principal princ;
179 ret = krb5_parse_name (context, argv[i], &princ);
181 krb5_warn (context, ret, "%s", argv[i]);
184 if (krb5_principal_compare (context, princ, entry.principal))
187 krb5_free_principal (context, princ);
195 max = max(max * 2, 1);
196 tmp = realloc (changeset, max * sizeof(*changeset));
198 krb5_kt_free_entry (context, &entry);
199 krb5_warnx (context, "realloc: out of memory");
205 ret = krb5_copy_principal (context, entry.principal,
206 &changeset[j].principal);
208 krb5_warn (context, ret, "krb5_copy_principal");
209 krb5_kt_free_entry (context, &entry);
212 changeset[j].kvno = entry.vno;
215 krb5_kt_free_entry (context, &entry);
217 krb5_kt_end_seq_get(context, keytab, &cursor);
219 if (ret == KRB5_KT_END) {
220 for (i = 0; i < j; i++) {
224 ret = krb5_unparse_name (context, changeset[i].principal,
227 krb5_warn (context, ret, "krb5_unparse_name");
229 printf("Changing %s kvno %d\n",
230 client_name, changeset[i].kvno);
234 ret = change_entry (keytab,
235 changeset[i].principal, changeset[i].kvno,
237 opt->admin_server_string,
238 opt->server_port_integer);
244 for (i = 0; i < j; i++)
245 krb5_free_principal (context, changeset[i].principal);
249 krb5_kt_close(context, keytab);