From 52bf663c4d3c384fb8d0044f859a8ffddb2b6a54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Love=20H=C3=B6rnquist=20=C3=85strand?= Date: Tue, 1 Apr 2003 15:04:49 +0000 Subject: [PATCH] (kt_change): collect all principals we are going to change, and pick the highest kvno and use that to guess what kvno the resulting kvno is going to be. Now two ktutil change in a row works. XXX fix the protocol to pass the kvno back. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@11949 ec53bebd-3082-4978-b11e-865c3cabbd6b --- admin/change.c | 99 +++++++++++++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 37 deletions(-) diff --git a/admin/change.c b/admin/change.c index eea62d860..365b21499 100644 --- a/admin/change.c +++ b/admin/change.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,7 +37,7 @@ RCSID("$Id$"); static void change_entry (krb5_context context, krb5_keytab keytab, - krb5_keytab_entry *entry, + krb5_principal principal, krb5_kvno kvno, const char *realm, const char *admin_server, int server_port) { krb5_error_code ret; @@ -48,7 +48,7 @@ change_entry (krb5_context context, krb5_keytab keytab, int num_keys; int i; - ret = krb5_unparse_name (context, entry->principal, &client_name); + ret = krb5_unparse_name (context, principal, &client_name); if (ret) { krb5_warn (context, ret, "krb5_unparse_name"); return; @@ -59,7 +59,7 @@ change_entry (krb5_context context, krb5_keytab keytab, if(realm) conf.realm = (char *)realm; else - conf.realm = *krb5_princ_realm (context, entry->principal); + conf.realm = *krb5_princ_realm (context, principal); conf.mask |= KADM5_CONFIG_REALM; if (admin_server) { @@ -83,8 +83,7 @@ change_entry (krb5_context context, krb5_keytab keytab, krb5_warn (context, ret, "kadm5_c_init_with_skey_ctx"); return; } - ret = kadm5_randkey_principal (kadm_handle, entry->principal, - &keys, &num_keys); + ret = kadm5_randkey_principal (kadm_handle, principal, &keys, &num_keys); kadm5_destroy (kadm_handle); if (ret) { krb5_warn(context, ret, "kadm5_randkey_principal"); @@ -93,9 +92,9 @@ change_entry (krb5_context context, krb5_keytab keytab, for (i = 0; i < num_keys; ++i) { krb5_keytab_entry new_entry; - new_entry = *entry; + new_entry.principal = principal; new_entry.timestamp = time (NULL); - ++new_entry.vno; + new_entry.vno = kvno + 1; new_entry.keyblock = keys[i]; ret = krb5_kt_add_entry (context, keytab, &new_entry); @@ -110,6 +109,11 @@ change_entry (krb5_context context, krb5_keytab keytab, * their keys, writing the new keys */ +struct change_set { + krb5_principal principal; + krb5_kvno kvno; +}; + int kt_change (int argc, char **argv) { @@ -122,8 +126,8 @@ kt_change (int argc, char **argv) int server_port = 0; int help_flag = 0; int optind = 0; - int j, max; - krb5_principal *princs; + int i, j, max; + struct change_set *changeset; struct getargs args[] = { { "realm", 'r', arg_string, NULL, @@ -154,12 +158,8 @@ kt_change (int argc, char **argv) return 1; j = 0; - max = 10; - princs = malloc (max * sizeof(*princs)); - if (princs == NULL) { - krb5_warnx (context, "malloc: out of memory"); - goto out; - } + max = 0; + changeset = NULL; ret = krb5_kt_start_seq_get(context, keytab, &cursor); if(ret){ @@ -168,20 +168,21 @@ kt_change (int argc, char **argv) } while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) { - int i; - int done = 0; + int add = 0; - for (i = 0; i < j; ++i) - if (krb5_principal_compare (context, princs[i], - entry.principal)) + for (i = 0; i < j; ++i) { + if (krb5_principal_compare (context, changeset[i].principal, + entry.principal)) { + if (changeset[i].kvno < entry.vno) + changeset[i].kvno = entry.vno; break; + } + } if (i < j) continue; if (optind == argc) { - change_entry (context, keytab, &entry, realm, admin_server, - server_port); - done = 1; + add = 1; } else { for (i = optind; i < argc; ++i) { krb5_principal princ; @@ -191,40 +192,64 @@ kt_change (int argc, char **argv) krb5_warn (context, ret, "krb5_parse_name %s", argv[i]); continue; } - if (krb5_principal_compare (context, princ, entry.principal)) { - change_entry (context, keytab, &entry, - realm, admin_server, server_port); - done = 1; - } + if (krb5_principal_compare (context, princ, entry.principal)) + add = 1; + krb5_free_principal (context, princ); } } - if (done) { + + if (add) { if (j >= max) { void *tmp; - max *= 2; - tmp = realloc (princs, max * sizeof(*princs)); + max = max(max * 2, 1); + tmp = realloc (changeset, max * sizeof(*changeset)); if (tmp == NULL) { krb5_kt_free_entry (context, &entry); krb5_warnx (context, "realloc: out of memory"); + ret = ENOMEM; break; } - princs = tmp; + changeset = tmp; } - ret = krb5_copy_principal (context, entry.principal, &princs[j]); + ret = krb5_copy_principal (context, entry.principal, + &changeset[j].principal); if (ret) { krb5_warn (context, ret, "krb5_copy_principal"); krb5_kt_free_entry (context, &entry); break; } + changeset[j].kvno = entry.vno; ++j; } krb5_kt_free_entry (context, &entry); } - while (j-- > 0) - krb5_free_principal (context, princs[j]); - free (princs); + + if (ret == KRB5_KT_END) { + for (i = 0; i < j; i++) { + if (verbose_flag) { + char *client_name; + + ret = krb5_unparse_name (context, changeset[i].principal, + &client_name); + if (ret) { + krb5_warn (context, ret, "krb5_unparse_name"); + } else { + printf("Changing %s kvno %d\n", + client_name, changeset[i].kvno); + free(client_name); + } + } + change_entry (context, keytab, + changeset[i].principal, changeset[i].kvno, + realm, admin_server, server_port); + } + } + for (i = 0; i < j; i++) + krb5_free_principal (context, changeset[i].principal); + free (changeset); + ret = krb5_kt_end_seq_get(context, keytab, &cursor); out: krb5_kt_close(context, keytab);