(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
This commit is contained in:
@@ -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).
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -37,7 +37,7 @@ RCSID("$Id$");
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
change_entry (krb5_context context, krb5_keytab keytab,
|
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)
|
const char *realm, const char *admin_server, int server_port)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
@@ -48,7 +48,7 @@ change_entry (krb5_context context, krb5_keytab keytab,
|
|||||||
int num_keys;
|
int num_keys;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ret = krb5_unparse_name (context, entry->principal, &client_name);
|
ret = krb5_unparse_name (context, principal, &client_name);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
krb5_warn (context, ret, "krb5_unparse_name");
|
krb5_warn (context, ret, "krb5_unparse_name");
|
||||||
return;
|
return;
|
||||||
@@ -59,7 +59,7 @@ change_entry (krb5_context context, krb5_keytab keytab,
|
|||||||
if(realm)
|
if(realm)
|
||||||
conf.realm = (char *)realm;
|
conf.realm = (char *)realm;
|
||||||
else
|
else
|
||||||
conf.realm = *krb5_princ_realm (context, entry->principal);
|
conf.realm = *krb5_princ_realm (context, principal);
|
||||||
conf.mask |= KADM5_CONFIG_REALM;
|
conf.mask |= KADM5_CONFIG_REALM;
|
||||||
|
|
||||||
if (admin_server) {
|
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");
|
krb5_warn (context, ret, "kadm5_c_init_with_skey_ctx");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ret = kadm5_randkey_principal (kadm_handle, entry->principal,
|
ret = kadm5_randkey_principal (kadm_handle, principal, &keys, &num_keys);
|
||||||
&keys, &num_keys);
|
|
||||||
kadm5_destroy (kadm_handle);
|
kadm5_destroy (kadm_handle);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
krb5_warn(context, ret, "kadm5_randkey_principal");
|
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) {
|
for (i = 0; i < num_keys; ++i) {
|
||||||
krb5_keytab_entry new_entry;
|
krb5_keytab_entry new_entry;
|
||||||
|
|
||||||
new_entry = *entry;
|
new_entry.principal = principal;
|
||||||
new_entry.timestamp = time (NULL);
|
new_entry.timestamp = time (NULL);
|
||||||
++new_entry.vno;
|
new_entry.vno = kvno + 1;
|
||||||
new_entry.keyblock = keys[i];
|
new_entry.keyblock = keys[i];
|
||||||
|
|
||||||
ret = krb5_kt_add_entry (context, keytab, &new_entry);
|
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
|
* their keys, writing the new keys
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct change_set {
|
||||||
|
krb5_principal principal;
|
||||||
|
krb5_kvno kvno;
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
kt_change (int argc, char **argv)
|
kt_change (int argc, char **argv)
|
||||||
{
|
{
|
||||||
@@ -122,8 +126,8 @@ kt_change (int argc, char **argv)
|
|||||||
int server_port = 0;
|
int server_port = 0;
|
||||||
int help_flag = 0;
|
int help_flag = 0;
|
||||||
int optind = 0;
|
int optind = 0;
|
||||||
int j, max;
|
int i, j, max;
|
||||||
krb5_principal *princs;
|
struct change_set *changeset;
|
||||||
|
|
||||||
struct getargs args[] = {
|
struct getargs args[] = {
|
||||||
{ "realm", 'r', arg_string, NULL,
|
{ "realm", 'r', arg_string, NULL,
|
||||||
@@ -154,12 +158,8 @@ kt_change (int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
max = 10;
|
max = 0;
|
||||||
princs = malloc (max * sizeof(*princs));
|
changeset = NULL;
|
||||||
if (princs == NULL) {
|
|
||||||
krb5_warnx (context, "malloc: out of memory");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = krb5_kt_start_seq_get(context, keytab, &cursor);
|
ret = krb5_kt_start_seq_get(context, keytab, &cursor);
|
||||||
if(ret){
|
if(ret){
|
||||||
@@ -168,20 +168,21 @@ kt_change (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) {
|
while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) {
|
||||||
int i;
|
int add = 0;
|
||||||
int done = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < j; ++i)
|
for (i = 0; i < j; ++i) {
|
||||||
if (krb5_principal_compare (context, princs[i],
|
if (krb5_principal_compare (context, changeset[i].principal,
|
||||||
entry.principal))
|
entry.principal)) {
|
||||||
|
if (changeset[i].kvno < entry.vno)
|
||||||
|
changeset[i].kvno = entry.vno;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (i < j)
|
if (i < j)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (optind == argc) {
|
if (optind == argc) {
|
||||||
change_entry (context, keytab, &entry, realm, admin_server,
|
add = 1;
|
||||||
server_port);
|
|
||||||
done = 1;
|
|
||||||
} else {
|
} else {
|
||||||
for (i = optind; i < argc; ++i) {
|
for (i = optind; i < argc; ++i) {
|
||||||
krb5_principal princ;
|
krb5_principal princ;
|
||||||
@@ -191,40 +192,64 @@ kt_change (int argc, char **argv)
|
|||||||
krb5_warn (context, ret, "krb5_parse_name %s", argv[i]);
|
krb5_warn (context, ret, "krb5_parse_name %s", argv[i]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (krb5_principal_compare (context, princ, entry.principal)) {
|
if (krb5_principal_compare (context, princ, entry.principal))
|
||||||
change_entry (context, keytab, &entry,
|
add = 1;
|
||||||
realm, admin_server, server_port);
|
|
||||||
done = 1;
|
|
||||||
}
|
|
||||||
krb5_free_principal (context, princ);
|
krb5_free_principal (context, princ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (done) {
|
|
||||||
|
if (add) {
|
||||||
if (j >= max) {
|
if (j >= max) {
|
||||||
void *tmp;
|
void *tmp;
|
||||||
|
|
||||||
max *= 2;
|
max = max(max * 2, 1);
|
||||||
tmp = realloc (princs, max * sizeof(*princs));
|
tmp = realloc (changeset, max * sizeof(*changeset));
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
krb5_kt_free_entry (context, &entry);
|
krb5_kt_free_entry (context, &entry);
|
||||||
krb5_warnx (context, "realloc: out of memory");
|
krb5_warnx (context, "realloc: out of memory");
|
||||||
|
ret = ENOMEM;
|
||||||
break;
|
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) {
|
if (ret) {
|
||||||
krb5_warn (context, ret, "krb5_copy_principal");
|
krb5_warn (context, ret, "krb5_copy_principal");
|
||||||
krb5_kt_free_entry (context, &entry);
|
krb5_kt_free_entry (context, &entry);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
changeset[j].kvno = entry.vno;
|
||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
krb5_kt_free_entry (context, &entry);
|
krb5_kt_free_entry (context, &entry);
|
||||||
}
|
}
|
||||||
while (j-- > 0)
|
|
||||||
krb5_free_principal (context, princs[j]);
|
if (ret == KRB5_KT_END) {
|
||||||
free (princs);
|
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);
|
ret = krb5_kt_end_seq_get(context, keytab, &cursor);
|
||||||
out:
|
out:
|
||||||
krb5_kt_close(context, keytab);
|
krb5_kt_close(context, keytab);
|
||||||
|
Reference in New Issue
Block a user