diff options
author | Andrew Bartlett <abartlet@samba.org> | 2010-09-16 14:37:20 +1000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2010-09-16 21:09:17 +1000 |
commit | 6832d5e9334f93d2b41fa50580379a2381311748 (patch) | |
tree | c4cb065d6ca93f4f367a2329b14a6eac90d163af /source3/auth | |
parent | d5a4e53ad8dd572b9469530dfcd37601e2905a88 (diff) | |
download | samba-6832d5e9334f93d2b41fa50580379a2381311748.tar.gz samba-6832d5e9334f93d2b41fa50580379a2381311748.tar.bz2 samba-6832d5e9334f93d2b41fa50580379a2381311748.zip |
libcli/auth/ntlmssp Be clear about talloc parents for session keys
The previous API was not clear as to who owned the returned session key.
This fixes a valgrind-found use-after-free in the NTLMSSP key derivation code,
and avoids making allocations - we steal and zero instead.
Andrew Bartlett
Signed-off-by: Andrew Tridgell <tridge@samba.org>
Diffstat (limited to 'source3/auth')
-rw-r--r-- | source3/auth/auth_ntlmssp.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c index aa7998cf63..af3a6f3827 100644 --- a/source3/auth/auth_ntlmssp.c +++ b/source3/auth/auth_ntlmssp.c @@ -26,12 +26,13 @@ #include "../librpc/gen_ndr/netlogon.h" NTSTATUS auth_ntlmssp_steal_server_info(TALLOC_CTX *mem_ctx, - struct auth_ntlmssp_state *auth_ntlmssp_state, - struct auth_serversupplied_info **server_info) + struct auth_ntlmssp_state *auth_ntlmssp_state, + struct auth_serversupplied_info **server_info) { /* Free the current server_info user_session_key and reset it from the * current ntlmssp_state session_key */ data_blob_free(&auth_ntlmssp_state->server_info->user_session_key); + /* Set up the final session key for the connection */ auth_ntlmssp_state->server_info->user_session_key = data_blob_talloc( auth_ntlmssp_state->server_info, @@ -105,7 +106,8 @@ static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, * Return the session keys used on the connection. */ -static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) +static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *mem_ctx, + DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) { struct auth_ntlmssp_state *auth_ntlmssp_state = (struct auth_ntlmssp_state *)ntlmssp_state->callback_private; @@ -160,19 +162,24 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, return nt_status; } + /* Clear out the session keys, and pass them to the caller. + * They will not be used in this form again - instead the + * NTLMSSP code will decide on the final correct session key, + * and put it back here at the end of + * auth_ntlmssp_steal_server_info */ if (auth_ntlmssp_state->server_info->user_session_key.length) { DEBUG(10, ("Got NT session key of length %u\n", (unsigned int)auth_ntlmssp_state->server_info->user_session_key.length)); - *user_session_key = data_blob_talloc(auth_ntlmssp_state, - auth_ntlmssp_state->server_info->user_session_key.data, - auth_ntlmssp_state->server_info->user_session_key.length); + *user_session_key = auth_ntlmssp_state->server_info->user_session_key; + talloc_steal(mem_ctx, auth_ntlmssp_state->server_info->user_session_key.data); + auth_ntlmssp_state->server_info->user_session_key = data_blob_null; } if (auth_ntlmssp_state->server_info->lm_session_key.length) { DEBUG(10, ("Got LM session key of length %u\n", (unsigned int)auth_ntlmssp_state->server_info->lm_session_key.length)); - *lm_session_key = data_blob_talloc(auth_ntlmssp_state, - auth_ntlmssp_state->server_info->lm_session_key.data, - auth_ntlmssp_state->server_info->lm_session_key.length); + *lm_session_key = auth_ntlmssp_state->server_info->lm_session_key; + talloc_steal(mem_ctx, auth_ntlmssp_state->server_info->lm_session_key.data); + auth_ntlmssp_state->server_info->lm_session_key = data_blob_null; } return nt_status; } |