diff --git a/kadmin/Makefile.am b/kadmin/Makefile.am index 74a2d5492..e7fe58f8d 100644 --- a/kadmin/Makefile.am +++ b/kadmin/Makefile.am @@ -26,6 +26,7 @@ dist_kadmin_SOURCES = \ kadmin.c \ load.c \ mod.c \ + prune.c \ rename.c \ stash.c \ util.c \ diff --git a/kadmin/NTMakefile b/kadmin/NTMakefile index 69680d0dc..80d05ec7a 100644 --- a/kadmin/NTMakefile +++ b/kadmin/NTMakefile @@ -59,6 +59,7 @@ KADMIN_OBJS= \ $(OBJ)\kadmin.obj \ $(OBJ)\load.obj \ $(OBJ)\mod.obj \ + $(OBJ)\prune.obj \ $(OBJ)\rename.obj \ $(OBJ)\stash.obj \ $(OBJ)\util.obj \ diff --git a/kadmin/kadmin-commands.in b/kadmin/kadmin-commands.in index c9c39ce14..2966b05d2 100644 --- a/kadmin/kadmin-commands.in +++ b/kadmin/kadmin-commands.in @@ -415,6 +415,19 @@ command = { max_args = "1" help = "Modifies some attributes of the specified principal." } +command = { + name = "prune" + argument = "principal" + option = { + long = "kvno" + type = "integer" + help = "key version number" + default = "0" + } + min_args = "1" + max_args = "1" + help = "Delete keys from history by max-ticket-life or kvno." +} command = { name = "privileges" name = "privs" diff --git a/kadmin/kadmin.1 b/kadmin/kadmin.1 index ef5c87e43..9390594a6 100644 --- a/kadmin/kadmin.1 +++ b/kadmin/kadmin.1 @@ -142,6 +142,19 @@ service belonging to the principal is known to not handle certain enctypes. .Ed .Pp +.Nm prune +.Ar principal [kvno] +.Bd -ragged -offset indent +Deletes the named principal's keys of the given kvno. If a kvno is +not given then this deletes all the named principals keys that are +too old to be needed for decrypting tickets issued using those keys +(i.e., any such tickets are necessarily expired). The determination +of "too old" is made using the max-ticket-life attribute of the +principal; though in practice that max ticket life is also constrained +by the max-ticket-life of the client principals and the krbtgt +principals, those are not consulted here. +.Ed +.Pp .Nm ext_keytab .Oo Fl k Ar string \*(Ba Xo .Fl Fl keytab= Ns Ar string diff --git a/kadmin/prune.c b/kadmin/prune.c new file mode 100644 index 000000000..69d14eb04 --- /dev/null +++ b/kadmin/prune.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018 Cesnet z.s.p.o. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "kadmin_locl.h" +#include "kadmin-commands.h" + +int +prune(struct prune_options *opt, int argc, char **argv) +{ + krb5_error_code ret = 0; + krb5_principal princ_ent = NULL; + + if (argc == 0) { + krb5_warnx(context, "prune: missing principal name argument"); + return 0; + } + if (argc > 1) { + krb5_warnx(context, "prune: too many arguments"); + return 0; + } + + ret = krb5_parse_name(context, argv[0], &princ_ent); + if (ret) { + krb5_warn(context, ret, "krb5_parse_name %s", argv[0]); + goto out2; + } + + ret = kadm5_prune_principal(kadm_handle, princ_ent, opt->kvno_integer); + if (ret) + krb5_warn(context, ret, "kadm5_prune_principal"); + +out2: + return ret != 0; +} diff --git a/kadmin/server.c b/kadmin/server.c index f8478deda..75d91dba3 100644 --- a/kadmin/server.c +++ b/kadmin/server.c @@ -43,7 +43,7 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial, krb5_data *in, krb5_data *out) { kadm5_ret_t ret; - int32_t cmd, mask, tmp; + int32_t cmd, mask, kvno, tmp; kadm5_server_context *contextp = kadm_handlep; char client[128], name[128], name2[128]; const char *op = ""; @@ -249,6 +249,36 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial, krb5_store_int32(sp, ret); break; } + case kadm_prune:{ + op = "PRUNE"; + ret = krb5_ret_principal(sp, &princ); + if (ret) + goto fail; + ret = krb5_ret_int32(sp, &kvno); + if (ret == HEIM_ERR_EOF) { + kvno = 0; + } else if (ret) { + krb5_free_principal(contextp->context, princ); + goto fail; + } + krb5_unparse_name_fixed(contextp->context, princ, name, sizeof(name)); + krb5_warnx(contextp->context, "%s: %s %s", client, op, name); + ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_CPW, princ); + if (ret) { + krb5_free_principal(contextp->context, princ); + goto fail; + } + ret = kadm5_prune_principal(kadm_handlep, princ, kvno); + krb5_free_principal(contextp->context, princ); + krb5_storage_free(sp); + sp = krb5_storage_emem(); + if (sp == NULL) { + ret = ENOMEM; + goto fail; + } + krb5_store_int32(sp, ret); + break; + } case kadm_rename:{ op = "RENAME"; ret = krb5_ret_principal(sp, &princ); diff --git a/lib/hdb/keys.c b/lib/hdb/keys.c index 96c221ed2..c9dc0b9c1 100644 --- a/lib/hdb/keys.c +++ b/lib/hdb/keys.c @@ -212,18 +212,21 @@ parse_key_set(krb5_context context, const char *key, } /** - * This function prunes an HDB entry's keys that are too old to have been used - * to mint still valid tickets (based on the entry's maximum ticket lifetime). - * + * This function prunes an HDB entry's historic keys by kvno. + * * @param context Context * @param entry HDB entry + * @param kvno Keyset kvno to prune, or zero to prune all too-old keys */ krb5_error_code -hdb_prune_keys(krb5_context context, hdb_entry *entry) +hdb_prune_keys_kvno(krb5_context context, hdb_entry *entry, int kvno) { HDB_extension *ext; HDB_Ext_KeySet *keys; + hdb_keyset *elem; + time_t keep_time = 0; size_t nelem; + size_t i; ext = hdb_find_extension(entry, choice_HDB_extension_data_hist_keys); if (ext == NULL) @@ -231,14 +234,12 @@ hdb_prune_keys(krb5_context context, hdb_entry *entry) keys = &ext->data.u.hist_keys; nelem = keys->len; - /* Optionally drop key history for keys older than now - max_life */ - if (entry->max_life != NULL && nelem > 0 - && krb5_config_get_bool_default(context, NULL, FALSE, - "kadmin", "prune-key-history", NULL)) { - hdb_keyset *elem; + /* + * Optionally drop key history for keys older than now - max_life, which is + * all the keys no longer needed to decrypt extant tickets. + */ + if (kvno == 0 && entry->max_life != NULL && nelem > 0) { time_t ceiling = time(NULL) - *entry->max_life; - time_t keep_time = 0; - size_t i; /* * Compute most recent key timestamp that predates the current time @@ -250,28 +251,45 @@ hdb_prune_keys(krb5_context context, hdb_entry *entry) && (keep_time == 0 || *elem->set_time > keep_time)) keep_time = *elem->set_time; } + } - /* Drop obsolete entries */ - if (keep_time) { - for (i = 0; i < nelem; /* see below */) { - elem = &keys->val[i]; - if (elem->set_time && *elem->set_time < keep_time) { - remove_HDB_Ext_KeySet(keys, i); - /* - * Removing the i'th element shifts the tail down, continue - * at same index with reduced upper bound. - */ - --nelem; - continue; - } - ++i; - } - } + if (kvno == 0 && keep_time == 0) + return 0; + + for (i = 0; i < nelem; /* see below */) { + elem = &keys->val[i]; + if ((kvno && kvno == elem->kvno) || + (keep_time && elem->set_time && *elem->set_time < keep_time)) { + remove_HDB_Ext_KeySet(keys, i); + /* + * Removing the i'th element shifts the tail down, continue + * at same index with reduced upper bound. + */ + --nelem; + continue; + } + ++i; } return 0; } +/** + * This function prunes an HDB entry's keys that are too old to have been used + * to mint still valid tickets (based on the entry's maximum ticket lifetime). + * + * @param context Context + * @param entry HDB entry + */ +krb5_error_code +hdb_prune_keys(krb5_context context, hdb_entry *entry) +{ + if (!krb5_config_get_bool_default(context, NULL, FALSE, + "kadmin", "prune-key-history", NULL)) + return 0; + return hdb_prune_keys_kvno(context, entry, 0); +} + /** * This function adds an HDB entry's current keyset to the entry's key * history. The current keyset is left alone; the caller is responsible diff --git a/lib/hdb/libhdb-exports.def b/lib/hdb/libhdb-exports.def index 67c0e33e0..df0a1cf9a 100644 --- a/lib/hdb/libhdb-exports.def +++ b/lib/hdb/libhdb-exports.def @@ -54,6 +54,7 @@ EXPORTS hdb_print_entry hdb_process_master_key hdb_prune_keys + hdb_prune_keys_kvno hdb_read_master_key hdb_replace_extension hdb_seal_key diff --git a/lib/hdb/version-script.map b/lib/hdb/version-script.map index 579a2efe7..eb409bec4 100644 --- a/lib/hdb/version-script.map +++ b/lib/hdb/version-script.map @@ -56,6 +56,7 @@ HEIMDAL_HDB_1.0 { hdb_print_entry; hdb_process_master_key; hdb_prune_keys; + hdb_prune_keys_kvno; hdb_read_master_key; hdb_replace_extension; hdb_seal_key; diff --git a/lib/kadm5/Makefile.am b/lib/kadm5/Makefile.am index 6f16ec6e8..95dc28d9c 100644 --- a/lib/kadm5/Makefile.am +++ b/lib/kadm5/Makefile.am @@ -74,6 +74,7 @@ dist_libkadm5clnt_la_SOURCES = \ modify_c.c \ private.h \ privs_c.c \ + prune_c.c \ randkey_c.c \ rename_c.c \ send_recv.c \ @@ -108,6 +109,7 @@ dist_libkadm5srv_la_SOURCES = \ password_quality.c \ private.h \ privs_s.c \ + prune_s.c \ randkey_s.c \ rename_s.c \ server_glue.c \ diff --git a/lib/kadm5/NTMakefile b/lib/kadm5/NTMakefile index 94d5d99fd..b9fd8400d 100644 --- a/lib/kadm5/NTMakefile +++ b/lib/kadm5/NTMakefile @@ -51,6 +51,7 @@ dist_libkadm5clnt_la_SOURCES = \ modify_c.c \ private.h \ privs_c.c \ + prune_c.c \ randkey_c.c \ rename_c.c \ send_recv.c \ @@ -83,6 +84,7 @@ dist_libkadm5srv_la_SOURCES = \ password_quality.c \ private.h \ privs_s.c \ + prune_s.c \ randkey_s.c \ rename_s.c \ server_glue.c \ @@ -110,6 +112,7 @@ LIBKADM5CLNT_OBJS= \ $(OBJ)\marshall.obj \ $(OBJ)\modify_c.obj \ $(OBJ)\privs_c.obj \ + $(OBJ)\prune_c.obj \ $(OBJ)\randkey_c.obj \ $(OBJ)\rename_c.obj \ $(OBJ)\send_recv.obj \ @@ -137,6 +140,7 @@ LIBKADM5SRV_OBJS= \ $(OBJ)\modify_s.obj \ $(OBJ)\password_quality.obj \ $(OBJ)\privs_s.obj \ + $(OBJ)\prune_s.obj \ $(OBJ)\randkey_s.obj \ $(OBJ)\rename_s.obj \ $(OBJ)\server_glue.obj \ diff --git a/lib/kadm5/common_glue.c b/lib/kadm5/common_glue.c index e7743640c..9993b0a34 100644 --- a/lib/kadm5/common_glue.c +++ b/lib/kadm5/common_glue.c @@ -428,3 +428,10 @@ kadm5_free_policy_ent(kadm5_policy_ent_t ent) return 0; } +kadm5_ret_t +kadm5_prune_principal(void *server_handle, + krb5_principal princ, + int kvno) +{ + return __CALL(prune_principal, (server_handle, princ, kvno)); +} diff --git a/lib/kadm5/context_s.c b/lib/kadm5/context_s.c index 55421b127..b5674f19a 100644 --- a/lib/kadm5/context_s.c +++ b/lib/kadm5/context_s.c @@ -106,6 +106,7 @@ set_funcs(kadm5_server_context *c) SET(c, get_principals); SET(c, get_privs); SET(c, modify_principal); + SET(c, prune_principal); SET(c, randkey_principal); SET(c, rename_principal); SET(c, lock); diff --git a/lib/kadm5/init_c.c b/lib/kadm5/init_c.c index c93060637..112ab9496 100644 --- a/lib/kadm5/init_c.c +++ b/lib/kadm5/init_c.c @@ -72,6 +72,7 @@ set_funcs(kadm5_client_context *c) SET(c, get_principals); SET(c, get_privs); SET(c, modify_principal); + SET(c, prune_principal); SET(c, randkey_principal); SET(c, rename_principal); SET(c, lock); diff --git a/lib/kadm5/libkadm5srv-exports.def b/lib/kadm5/libkadm5srv-exports.def index 51a2a44bd..9ca7b1511 100644 --- a/lib/kadm5/libkadm5srv-exports.def +++ b/lib/kadm5/libkadm5srv-exports.def @@ -34,6 +34,7 @@ EXPORTS kadm5_lock kadm5_modify_policy kadm5_modify_principal + kadm5_prune_principal kadm5_randkey_principal kadm5_randkey_principal_3 kadm5_rename_principal diff --git a/lib/kadm5/private.h b/lib/kadm5/private.h index 69d1bdc8b..ac3bb1d0f 100644 --- a/lib/kadm5/private.h +++ b/lib/kadm5/private.h @@ -67,6 +67,7 @@ struct kadm_func { kadm5_ret_t (*setkey_principal_3) (void *, krb5_principal, krb5_boolean, int, krb5_key_salt_tuple *, krb5_keyblock *, int); + kadm5_ret_t (*prune_principal) (void *, krb5_principal, int); }; typedef struct kadm5_hook_context { @@ -169,8 +170,9 @@ enum kadm_ops { kadm_get_princs, kadm_chpass_with_key, kadm_nop, + kadm_prune, kadm_first = kadm_get, - kadm_last = kadm_nop + kadm_last = kadm_prune }; /* FIXME nop types are currently not implemented */ diff --git a/lib/kadm5/prune_c.c b/lib/kadm5/prune_c.c new file mode 100644 index 000000000..13b68644f --- /dev/null +++ b/lib/kadm5/prune_c.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2018 Cesnet z.s.p.o. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "kadm5_locl.h" + +RCSID("$Id$"); + +kadm5_ret_t +kadm5_c_prune_principal(void *server_handle, krb5_principal princ, int kvno) +{ + kadm5_client_context *context = server_handle; + kadm5_ret_t ret, ret2; + krb5_storage *sp = NULL; + unsigned char buf[1024]; + krb5_data reply; + + krb5_data_zero(&reply); + ret = _kadm5_connect(server_handle); + if (ret == 0 && (sp = krb5_storage_from_mem(buf, sizeof(buf))) == NULL) + ret = krb5_enomem(context->context); + if (ret == 0) + ret = krb5_store_int32(sp, kadm_prune); + if (ret == 0) + ret = krb5_store_principal(sp, princ); + if (ret == 0) + ret = krb5_store_int32(sp, kvno); + if (ret == 0) + ret = _kadm5_client_send(context, sp); + if (ret == 0) + ret = _kadm5_client_recv(context, &reply); + krb5_storage_free(sp); + sp = NULL; + if (ret == 0 && (sp = krb5_storage_from_data(&reply)) == NULL) + ret = krb5_enomem(context->context); + if (ret == 0) + ret = krb5_ret_int32(sp, &ret2); + if (ret == 0) { + krb5_clear_error_message(context->context); + ret = ret2; + } + krb5_data_free(&reply); + krb5_storage_free(sp); + return ret; +} diff --git a/lib/kadm5/prune_s.c b/lib/kadm5/prune_s.c new file mode 100644 index 000000000..fd95af7cf --- /dev/null +++ b/lib/kadm5/prune_s.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018 Cesnet z.s.p.o. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "kadm5_locl.h" + +RCSID("$Id$"); + +kadm5_ret_t +kadm5_s_prune_principal(void *server_handle, + krb5_principal princ, + int kvno) +{ + kadm5_server_context *context = server_handle; + hdb_entry_ex ent; + kadm5_ret_t ret; + + memset(&ent, 0, sizeof(ent)); + if (!context->keep_open) { + ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); + if(ret) + return ret; + } + + ret = kadm5_log_init(context); + if (ret) + goto out; + + ret = context->db->hdb_fetch_kvno(context->context, context->db, princ, + HDB_F_GET_ANY|HDB_F_ADMIN_DATA, 0, &ent); + if (ret) + goto out2; + + ret = hdb_prune_keys_kvno(context->context, &ent.entry, kvno); + if (ret) + goto out3; + + ret = hdb_seal_keys(context->context, context->db, &ent.entry); + if (ret) + goto out3; + + ret = kadm5_log_modify(context, &ent.entry, KADM5_KEY_DATA); + +out3: + hdb_free_entry(context->context, &ent); +out2: + (void) kadm5_log_end(context); +out: + if (!context->keep_open) { + kadm5_ret_t ret2; + ret2 = context->db->hdb_close(context->context, context->db); + if (ret == 0 && ret2 != 0) + ret = ret2; + } + return _kadm5_error_code(ret); +} diff --git a/lib/kadm5/version-script-client.map b/lib/kadm5/version-script-client.map index de0ed6749..c45d1e7f9 100644 --- a/lib/kadm5/version-script-client.map +++ b/lib/kadm5/version-script-client.map @@ -22,6 +22,7 @@ HEIMDAL_KADM5_CLIENT_1.0 { kadm5_c_init_with_skey; kadm5_c_init_with_skey_ctx; kadm5_c_modify_principal; + kadm5_c_prune_principal; kadm5_c_randkey_principal; kadm5_c_rename_principal; kadm5_chpass_principal; diff --git a/lib/kadm5/version-script.map b/lib/kadm5/version-script.map index 88ec5155e..0331b182d 100644 --- a/lib/kadm5/version-script.map +++ b/lib/kadm5/version-script.map @@ -37,6 +37,7 @@ HEIMDAL_KAMD5_SERVER_1.0 { kadm5_lock; kadm5_modify_principal; kadm5_modify_policy; + kadm5_prune_principal; kadm5_randkey_principal; kadm5_randkey_principal_3; kadm5_rename_principal; diff --git a/tests/kdc/check-kadmin.in b/tests/kdc/check-kadmin.in index 106ef70c9..6f488fce9 100644 --- a/tests/kdc/check-kadmin.in +++ b/tests/kdc/check-kadmin.in @@ -87,6 +87,9 @@ ${kadmin} -l add -p "$foopassword" --use-defaults fez@${R} || exit 1 ${kadmin} -l add -p "$foopassword" --use-defaults hasalias@${R} || exit 1 ${kadmin} -l add -p "$foopassword" --use-defaults pkinit@${R} || exit 1 ${kadmin} -l modify --pkinit-acl="CN=baz,DC=test,DC=h5l,DC=se" pkinit@${R} || exit 1 +${kadmin} -l add -p foo --use-defaults prune@${R} || exit 1 +${kadmin} -l cpw --keepold --random-key prune@${R} || exit 1 +${kadmin} -l cpw --keepold --random-key prune@${R} || exit 1 echo "$foopassword" > ${objdir}/foopassword @@ -353,7 +356,33 @@ if test "`cat kadmin.tmp`" != "Attributes" ; then fi #---------------------------------- +${kadmind} -d & +kadmpid=$! +sleep 1 +echo "kadmin prune" +env KRB5CCNAME=${cache} \ +${kadmin} prune --kvno=2 prune@${R} \ + > kadmin.tmp 2>&1 || \ + { echo "kadmin failed $?"; cat messages.log ; exit 1; } +wait $kadmpid || { echo "kadmind failed $?"; cat messages.log ; exit 1; } + +${kadmind} -d & +kadmpid=$! +sleep 1 + +env KRB5CCNAME=${cache} \ +${kadmin} get prune@${R} \ + > kadmin.tmp 2>&1 || \ + { echo "kadmin failed $?"; cat messages.log ; exit 1; } +wait $kadmpid || { echo "kadmind failed $?"; cat messages.log ; exit 1; } + +cat kadmin.tmp | ${EGREP} Keytypes: | cut -d: -f2 | tr ' ' ' +' | sed 's/^.*[[]\(.*\)[]].*$/\1/' | grep '[0-9]' | sort -nu | tr -d ' +' | ${EGREP} '^13$' > /dev/null || \ + { echo "kadmin prune failed $?"; cat messages.log ; exit 1; } + +#---------------------------------- echo "killing kdc (${kdcpid} ${kadmpid})" sh ${leaks_kill} kdc $kdcpid || exit 1