From b524f1a4817dadbf57d27b54621278a84afc830a Mon Sep 17 00:00:00 2001 From: Mitchell Berger Date: Tue, 16 Oct 2001 10:12:31 +0000 Subject: [PATCH] * svr_principal.c (add_to_history): If the policy a principal uses has been changed to hold a lesser number of history entries than it did before, extract the correct number and value of old keys from the history array into a newly allocated array of the proper size. Failing to do this made kadmind vulnerable to a crash upon changing such a principal's password. Original patch written by Matt Crawford, with a few changes. [Fixes krb5-admin/929] git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@13813 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/kadm5/srv/ChangeLog | 11 ++++++++++ src/lib/kadm5/srv/svr_principal.c | 35 +++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/lib/kadm5/srv/ChangeLog b/src/lib/kadm5/srv/ChangeLog index 57b9b10ee..df297ffdf 100644 --- a/src/lib/kadm5/srv/ChangeLog +++ b/src/lib/kadm5/srv/ChangeLog @@ -1,3 +1,14 @@ +2001-10-16 Mitchell Berger + Matt Crawford + + * svr_principal.c (add_to_history): If the policy a principal uses has + been changed to hold a lesser number of history entries than it did + before, extract the correct number and value of old keys from the + history array into a newly allocated array of the proper size. Failing + to do this made kadmind vulnerable to a crash upon changing such a + principal's password. Original patch written by Matt Crawford, with + a few changes. + 2001-10-09 Ken Raeburn * server_acl.h: Make prototypes unconditional. diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c index c0899aa38..933d3c1f7 100644 --- a/src/lib/kadm5/srv/svr_principal.c +++ b/src/lib/kadm5/srv/svr_principal.c @@ -986,6 +986,7 @@ void free_history_entry(krb5_context context, osa_pw_hist_ent *hist) * array where the next element should be written, and must be [0, * adb->old_key_len). */ +#define KADM_MOD(x) (x + adb->old_key_next) % adb->old_key_len static kadm5_ret_t add_to_history(krb5_context context, osa_princ_ent_t adb, kadm5_policy_ent_t pol, @@ -1013,6 +1014,39 @@ static kadm5_ret_t add_to_history(krb5_context context, memset(&adb->old_keys[adb->old_key_len],0,sizeof(osa_pw_hist_ent)); adb->old_key_len++; + } else if (adb->old_key_len > pol->pw_history_num-1) { + /* + * The policy must have changed! Shrink the array. + * Can't simply realloc() down, since it might be wrapped. + * To understand the arithmetic below, note that we are + * copying into new positions 0 .. N-1 from old positions + * old_key_next-N .. old_key_next-1, modulo old_key_len, + * where N = pw_history_num - 1 is the length of the + * shortened list. Matt Crawford, FNAL + */ + int j; + histp = (osa_pw_hist_ent *) + malloc((pol->pw_history_num - 1) * sizeof (osa_pw_hist_ent)); + if (histp) { + for (i = 0; i < pol->pw_history_num - 1; i++) { + /* We need the number we use the modulus operator on to be + positive, so after subtracting pol->pw_history_num-1, we + add back adb->old_key_len. */ + j = KADM_MOD(i - (pol->pw_history_num - 1) + adb->old_key_len); + histp[i] = adb->old_keys[j]; + } + /* Now free the ones we don't keep (the oldest ones) */ + for (i = 0; i < adb->old_key_len - (pol->pw_history_num - 1); i++) + for (j = 0; j < adb->old_keys[KADM_MOD(i)].n_key_data; j++) + krb5_free_key_data_contents(context, + &adb->old_keys[KADM_MOD(i)].key_data[j]); + free((void *)adb->old_keys); + adb->old_keys = histp; + adb->old_key_len = pol->pw_history_num - 1; + adb->old_key_next = 0; + } else { + return(ENOMEM); + } } /* free the old pw history entry if it contains data */ @@ -1029,6 +1063,7 @@ static kadm5_ret_t add_to_history(krb5_context context, return(0); } +#undef KADM_MOD kadm5_ret_t kadm5_chpass_principal(void *server_handle, -- 2.26.2