summaryrefslogtreecommitdiff
path: root/source4/librpc/rpc
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2010-02-14 11:56:28 +1100
committerAndrew Tridgell <tridge@samba.org>2010-02-14 18:44:21 +1100
commit259129e8f4bc8cacd1850eba3f6551134835d079 (patch)
treec260895bc44323820cee72a8eaf6a77433090d5d /source4/librpc/rpc
parentccfa40fdc3eb785b71a4d2d59933a2fdc352fb24 (diff)
downloadsamba-259129e8f4bc8cacd1850eba3f6551134835d079.tar.gz
samba-259129e8f4bc8cacd1850eba3f6551134835d079.tar.bz2
samba-259129e8f4bc8cacd1850eba3f6551134835d079.zip
a4-dcerpc: another attempt at dcerpc auth padding
The last change broke net vampire against w2k8r2
Diffstat (limited to 'source4/librpc/rpc')
-rw-r--r--source4/librpc/rpc/dcerpc.c19
-rw-r--r--source4/librpc/rpc/dcerpc_util.c8
2 files changed, 16 insertions, 11 deletions
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
index e7b181c50b..ccafe070ab 100644
--- a/source4/librpc/rpc/dcerpc.c
+++ b/source4/librpc/rpc/dcerpc.c
@@ -318,6 +318,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c,
size_t payload_length;
enum ndr_err_code ndr_err;
size_t hdr_size = DCERPC_REQUEST_LENGTH;
+ uint32_t offset;
/* non-signed packets are simpler */
if (sig_size == 0) {
@@ -362,17 +363,15 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c,
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
return ndr_map_error2ntstatus(ndr_err);
}
- status = NT_STATUS_OK;
/* pad to 16 byte multiple in the payload portion of the
packet. This matches what w2k3 does */
- c->security_state.auth_info->auth_pad_length =
- (16 - (pkt->u.request.stub_and_verifier.length & 15)) & 15;
- ndr_err = ndr_push_zero(ndr, c->security_state.auth_info->auth_pad_length);
+ offset = ndr->offset;
+ ndr_err = ndr_push_align(ndr, 16);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
return ndr_map_error2ntstatus(ndr_err);
}
- status = NT_STATUS_OK;
+ c->security_state.auth_info->auth_pad_length = ndr->offset - offset;
payload_length = pkt->u.request.stub_and_verifier.length +
c->security_state.auth_info->auth_pad_length;
@@ -385,7 +384,6 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c,
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
return ndr_map_error2ntstatus(ndr_err);
}
- status = NT_STATUS_OK;
/* extract the whole packet as a blob */
*blob = ndr_push_blob(ndr);
@@ -433,12 +431,17 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c,
}
if (creds2.length != sig_size) {
- DEBUG(0,("ncacn_push_request_sign: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n",
+ /* this means the sig_size estimate for the signature
+ was incorrect. We have to correct the packet
+ sizes. That means we could go over the max fragment
+ length */
+ DEBUG(3,("ncacn_push_request_sign: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n",
(unsigned) creds2.length,
(unsigned) sig_size,
(unsigned) c->security_state.auth_info->auth_pad_length,
(unsigned) pkt->u.request.stub_and_verifier.length));
- return NT_STATUS_INTERNAL_ERROR;
+ dcerpc_set_frag_length(blob, blob->length + creds2.length);
+ dcerpc_set_auth_length(blob, creds2.length);
}
if (!data_blob_append(mem_ctx, blob, creds2.data, creds2.length)) {
diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c
index 1985cb9e18..f41236148a 100644
--- a/source4/librpc/rpc/dcerpc_util.c
+++ b/source4/librpc/rpc/dcerpc_util.c
@@ -52,8 +52,8 @@ const struct ndr_interface_call *dcerpc_iface_find_call(const struct ndr_interfa
*/
NTSTATUS ncacn_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
struct smb_iconv_convenience *iconv_convenience,
- struct ncacn_packet *pkt,
- struct dcerpc_auth *auth_info)
+ struct ncacn_packet *pkt,
+ struct dcerpc_auth *auth_info)
{
struct ndr_push *ndr;
enum ndr_err_code ndr_err;
@@ -83,10 +83,12 @@ NTSTATUS ncacn_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
}
if (auth_info) {
- ndr_err = ndr_push_zero(ndr, auth_info->auth_pad_length);
+ uint32_t offset = ndr->offset;
+ ndr_err = ndr_push_align(ndr, 16);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
return ndr_map_error2ntstatus(ndr_err);
}
+ auth_info->auth_pad_length = ndr->offset - offset;
ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth_info);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
return ndr_map_error2ntstatus(ndr_err);