diff --git a/kadmin/cpw.c b/kadmin/cpw.c index fb736fd85..a5ca9ff74 100644 --- a/kadmin/cpw.c +++ b/kadmin/cpw.c @@ -112,8 +112,8 @@ set_key_data (krb5_principal principal, krb5_key_data *key_data, int keepold) { krb5_error_code ret; - ret = kadm5_chpass_principal_with_key (kadm_handle, principal, - 3, key_data); + ret = kadm5_chpass_principal_with_key_3(kadm_handle, principal, keepold, + 3, key_data); return ret; } diff --git a/kadmin/server.c b/kadmin/server.c index 174714160..bd4ddff33 100644 --- a/kadmin/server.c +++ b/kadmin/server.c @@ -218,10 +218,15 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial, case kadm_chpass:{ op = "CHPASS"; ret = krb5_ret_principal(sp, &princ); - if(ret) + if (ret) goto fail; ret = krb5_ret_string(sp, &password); - if(ret){ + if (ret) { + krb5_free_principal(contextp->context, princ); + goto fail; + } + ret = krb5_ret_int32(sp, &keepold); + if (ret && ret != HEIM_ERR_EOF) { krb5_free_principal(contextp->context, princ); goto fail; } @@ -262,7 +267,8 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial, free(password); goto fail; } - ret = kadm5_chpass_principal(kadm_handlep, princ, password); + ret = kadm5_chpass_principal_3(kadm_handlep, princ, keepold, 0, NULL, + password); krb5_free_principal(contextp->context, princ); memset(password, 0, strlen(password)); free(password); @@ -285,6 +291,11 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial, krb5_free_principal(contextp->context, princ); goto fail; } + ret = krb5_ret_int32(sp, &keepold); + if (ret && ret != HEIM_ERR_EOF) { + krb5_free_principal(contextp->context, princ); + goto fail; + } /* n_key_data will be squeezed into an int16_t below. */ if (n_key_data < 0 || n_key_data >= 1 << 16 || (size_t)n_key_data > UINT_MAX/sizeof(*key_data)) { @@ -329,8 +340,8 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial, krb5_free_principal(contextp->context, princ); goto fail; } - ret = kadm5_chpass_principal_with_key(kadm_handlep, princ, - n_key_data, key_data); + ret = kadm5_chpass_principal_with_key_3(kadm_handlep, princ, keepold, + n_key_data, key_data); { int16_t dummy = n_key_data; kadm5_free_key_data (contextp, &dummy, key_data); diff --git a/lib/kadm5/ad.c b/lib/kadm5/ad.c index f98ee3c89..639766594 100644 --- a/lib/kadm5/ad.c +++ b/lib/kadm5/ad.c @@ -516,6 +516,9 @@ kadm5_ad_chpass_principal(void *server_handle, int result_code; kadm5_ret_t ret; + if (keepold) + return KADM5_KEEPOLD_NOSUPP; + ret = ad_get_cred(context, NULL); if (ret) return ret; @@ -1237,6 +1240,9 @@ kadm5_ad_randkey_principal(void *server_handle, { kadm5_ad_context *context = server_handle; + if (keepold) + return KADM5_KEEPOLD_NOSUPP; + /* * random key */ @@ -1326,6 +1332,7 @@ kadm5_ad_rename_principal(void *server_handle, static kadm5_ret_t kadm5_ad_chpass_principal_with_key(void *server_handle, krb5_principal princ, + int keepold, int n_key_data, krb5_key_data *key_data) { diff --git a/lib/kadm5/chpass_c.c b/lib/kadm5/chpass_c.c index 6445b570e..5bfec2e96 100644 --- a/lib/kadm5/chpass_c.c +++ b/lib/kadm5/chpass_c.c @@ -84,6 +84,7 @@ kadm5_c_chpass_principal(void *server_handle, kadm5_ret_t kadm5_c_chpass_principal_with_key(void *server_handle, krb5_principal princ, + int keepold, int n_key_data, krb5_key_data *key_data) { @@ -109,6 +110,7 @@ kadm5_c_chpass_principal_with_key(void *server_handle, krb5_store_int32(sp, n_key_data); for (i = 0; i < n_key_data; ++i) kadm5_store_key_data (sp, &key_data[i]); + krb5_store_int32(sp, keepold); /* extension */ ret = _kadm5_client_send(context, sp); krb5_storage_free(sp); if (ret) diff --git a/lib/kadm5/chpass_s.c b/lib/kadm5/chpass_s.c index 90eae4f2d..c8f71ba8a 100644 --- a/lib/kadm5/chpass_s.c +++ b/lib/kadm5/chpass_s.c @@ -182,6 +182,7 @@ kadm5_s_chpass_principal(void *server_handle, kadm5_ret_t kadm5_s_chpass_principal_with_key(void *server_handle, krb5_principal princ, + int keepold, int n_key_data, krb5_key_data *key_data) { @@ -197,9 +198,11 @@ kadm5_s_chpass_principal_with_key(void *server_handle, HDB_F_GET_ANY|HDB_F_ADMIN_DATA, &ent); if(ret == HDB_ERR_NOENTRY) goto out; - ret = hdb_add_current_keys_to_history(context->context, &ent.entry); - if (ret) - goto out2; + if (keepold) { + ret = hdb_add_current_keys_to_history(context->context, &ent.entry); + if (ret) + goto out2; + } ret = _kadm5_set_keys2(context, &ent.entry, n_key_data, key_data); if(ret) goto out2; @@ -211,9 +214,19 @@ kadm5_s_chpass_principal_with_key(void *server_handle, if (ret) goto out2; - ret = hdb_seal_keys(context->context, context->db, &ent.entry); - if (ret) - goto out2; + if (keepold) { + ret = hdb_seal_keys(context->context, context->db, &ent.entry); + if (ret) + goto out2; + } else { + HDB_extension ext; + + ext.data.element = choice_HDB_extension_data_hist_keys; + ext.data.u.hist_keys.len = 0; + ext.data.u.hist_keys.val = NULL; + hdb_replace_extension(context->context, &ent.entry, &ext); + } + ret = context->db->hdb_store(context->context, context->db, HDB_F_REPLACE, &ent); diff --git a/lib/kadm5/common_glue.c b/lib/kadm5/common_glue.c index a1752b169..7dad9175a 100644 --- a/lib/kadm5/common_glue.c +++ b/lib/kadm5/common_glue.c @@ -70,7 +70,18 @@ kadm5_chpass_principal_with_key(void *server_handle, krb5_key_data *key_data) { return __CALL(chpass_principal_with_key, - (server_handle, princ, n_key_data, key_data)); + (server_handle, princ, 0, n_key_data, key_data)); +} + +kadm5_ret_t +kadm5_chpass_principal_with_key_3(void *server_handle, + krb5_principal princ, + int keepold, + int n_key_data, + krb5_key_data *key_data) +{ + return __CALL(chpass_principal_with_key, + (server_handle, princ, keepold, n_key_data, key_data)); } kadm5_ret_t diff --git a/lib/kadm5/kadm5_err.et b/lib/kadm5/kadm5_err.et index b7b395412..1f12d0f8d 100644 --- a/lib/kadm5/kadm5_err.et +++ b/lib/kadm5/kadm5_err.et @@ -61,3 +61,4 @@ error_code KS_TUPLE_NOSUPP, "Key/salt tuples not supported by this function" error_code SETKEY3_ETYPE_MISMATCH, "Key/salt tuples don't match keys" error_code DECRYPT_USAGE_NOSUPP, "Given usage of kadm5_decrypt() not supported" error_code POLICY_OP_NOSUPP, "Policy operations not supported" +error_code KEEPOLD_NOSUPP, "Keep old keys option not supported" diff --git a/lib/kadm5/private.h b/lib/kadm5/private.h index 9fe8f4e70..168b473d4 100644 --- a/lib/kadm5/private.h +++ b/lib/kadm5/private.h @@ -52,7 +52,7 @@ struct kadm_func { krb5_key_salt_tuple*, krb5_keyblock**, int*); kadm5_ret_t (*rename_principal) (void*, krb5_principal, krb5_principal); - kadm5_ret_t (*chpass_principal_with_key) (void *, krb5_principal, + kadm5_ret_t (*chpass_principal_with_key) (void *, krb5_principal, int, int, krb5_key_data *); kadm5_ret_t (*lock) (void *); kadm5_ret_t (*unlock) (void *); diff --git a/lib/kadm5/randkey_c.c b/lib/kadm5/randkey_c.c index 4916cad64..4cb62010f 100644 --- a/lib/kadm5/randkey_c.c +++ b/lib/kadm5/randkey_c.c @@ -81,10 +81,6 @@ kadm5_c_randkey_principal(void *server_handle, */ krb5_store_int32(sp, kadm_randkey); krb5_store_principal(sp, princ); - ret = _kadm5_client_send(context, sp); - krb5_storage_free(sp); - if (ret) - return ret; if (keepold == TRUE || n_ks_tuple > 0) krb5_store_uint32(sp, keepold); @@ -94,8 +90,12 @@ kadm5_c_randkey_principal(void *server_handle, krb5_store_int32(sp, ks_tuple[i].ks_enctype); krb5_store_int32(sp, ks_tuple[i].ks_salttype); } - /* Future extensions go here */ + + ret = _kadm5_client_send(context, sp); + krb5_storage_free(sp); + if (ret) + return ret; ret = _kadm5_client_recv(context, &reply); if(ret) return ret; diff --git a/lib/kadm5/version-script.map b/lib/kadm5/version-script.map index 3ba0e6ebf..c16ea630d 100644 --- a/lib/kadm5/version-script.map +++ b/lib/kadm5/version-script.map @@ -9,6 +9,7 @@ HEIMDAL_KAMD5_SERVER_1.0 { kadm5_chpass_principal; kadm5_chpass_principal_3; kadm5_chpass_principal_with_key; + kadm5_chpass_principal_with_key_3; kadm5_create_principal; kadm5_delete_principal; kadm5_destroy;