diff options
author | Jeremy Allison <jra@samba.org> | 2010-02-18 16:12:04 -0800 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2010-02-18 16:12:04 -0800 |
commit | 91a4db635802a391a560b739c996b5599a3df1a4 (patch) | |
tree | b719e9ba391e317315dfd235d9499ca56e6dd45a /source3/rpc_server | |
parent | 13533e12fd33df5ac75839cf4cb145b247941205 (diff) | |
download | samba-91a4db635802a391a560b739c996b5599a3df1a4.tar.gz samba-91a4db635802a391a560b739c996b5599a3df1a4.tar.bz2 samba-91a4db635802a391a560b739c996b5599a3df1a4.zip |
More fixes for bug #7146 - Samba miss-parses authenticated RPC packets.
Alignment space calculations are tricky :-).
Jeremy.
Diffstat (limited to 'source3/rpc_server')
-rw-r--r-- | source3/rpc_server/srv_pipe.c | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 1c10525659..23f947f95b 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1,7 +1,7 @@ /* * Unix SMB/CIFS implementation. * RPC Pipe client / server routines - * Almost completely rewritten by (C) Jeremy Allison 2005. + * Almost completely rewritten by (C) Jeremy Allison 2005 - 2010 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -108,15 +108,9 @@ static bool create_next_pdu_ntlmssp(pipes_struct *p) return False; } - if (data_len_left % SERVER_NDR_PADDING_SIZE) { - ss_padding_len = SERVER_NDR_PADDING_SIZE - (data_len_left % SERVER_NDR_PADDING_SIZE); - DEBUG(10,("create_next_pdu_ntlmssp: adding sign/seal padding of %u\n", - ss_padding_len )); - } - + /* Space available - not including padding. */ data_space_available = RPC_MAX_PDU_FRAG_LEN - RPC_HEADER_LEN - - RPC_HDR_RESP_LEN - ss_padding_len - RPC_HDR_AUTH_LEN - - NTLMSSP_SIG_SIZE; + RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - NTLMSSP_SIG_SIZE; /* * The amount we send is the minimum of the available @@ -125,6 +119,19 @@ static bool create_next_pdu_ntlmssp(pipes_struct *p) data_len = MIN(data_len_left, data_space_available); + /* Work out any padding alignment requirements. */ + if ((RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len) % SERVER_NDR_PADDING_SIZE) { + ss_padding_len = SERVER_NDR_PADDING_SIZE - + ((RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len) % SERVER_NDR_PADDING_SIZE); + DEBUG(10,("create_next_pdu_ntlmssp: adding sign/seal padding of %u\n", + ss_padding_len )); + /* If we're over filling the packet, we need to make space + * for the padding at the end of the data. */ + if (data_len + ss_padding_len > data_space_available) { + data_len -= SERVER_NDR_PADDING_SIZE; + } + } + /* * Set up the alloc hint. This should be the data left to * send. @@ -329,14 +336,9 @@ static bool create_next_pdu_schannel(pipes_struct *p) return False; } - if (data_len_left % SERVER_NDR_PADDING_SIZE) { - ss_padding_len = SERVER_NDR_PADDING_SIZE - (data_len_left % SERVER_NDR_PADDING_SIZE); - DEBUG(10,("create_next_pdu_schannel: adding sign/seal padding of %u\n", - ss_padding_len )); - } - + /* Space available - not including padding. */ data_space_available = RPC_MAX_PDU_FRAG_LEN - RPC_HEADER_LEN - - RPC_HDR_RESP_LEN - ss_padding_len - RPC_HDR_AUTH_LEN + - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN; /* @@ -346,6 +348,19 @@ static bool create_next_pdu_schannel(pipes_struct *p) data_len = MIN(data_len_left, data_space_available); + /* Work out any padding alignment requirements. */ + if ((RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len) % SERVER_NDR_PADDING_SIZE) { + ss_padding_len = SERVER_NDR_PADDING_SIZE - + ((RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len) % SERVER_NDR_PADDING_SIZE); + DEBUG(10,("create_next_pdu_schannel: adding sign/seal padding of %u\n", + ss_padding_len )); + /* If we're over filling the packet, we need to make space + * for the padding at the end of the data. */ + if (data_len + ss_padding_len > data_space_available) { + data_len -= SERVER_NDR_PADDING_SIZE; + } + } + /* * Set up the alloc hint. This should be the data left to * send. |