diff options
author | Andrew Tridgell <tridge@samba.org> | 2010-02-13 15:32:23 +1100 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2010-02-13 23:12:29 +1100 |
commit | da86f08605f8ec9fa6d3e1c122ec47309deef994 (patch) | |
tree | 52e249167a67d50ce6c76d4d38128d4fd25461c5 /source4/librpc/rpc/dcerpc_util.c | |
parent | 3ae75a424890fdeddd12535c9330186ec2fcd899 (diff) | |
download | samba-da86f08605f8ec9fa6d3e1c122ec47309deef994.tar.gz samba-da86f08605f8ec9fa6d3e1c122ec47309deef994.tar.bz2 samba-da86f08605f8ec9fa6d3e1c122ec47309deef994.zip |
s4-rpc: be more careful about DCERPC auth padding
Cope with a wider range of auth padding in dcerpc bind_ack and
alter_context packets. We now use a helper function that calculates
the right auth padding.
Diffstat (limited to 'source4/librpc/rpc/dcerpc_util.c')
-rw-r--r-- | source4/librpc/rpc/dcerpc_util.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index 86c91535e7..1985cb9e18 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -83,6 +83,10 @@ 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); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } 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); @@ -750,3 +754,59 @@ _PUBLIC_ NTSTATUS dcerpc_secondary_context(struct dcerpc_pipe *p, return NT_STATUS_OK; } + + +/* + pull an dcerpc_auth structure, taking account of any auth padding in + the blob at the end of the structure + */ +NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt, + TALLOC_CTX *mem_ctx, + DATA_BLOB *pkt_auth_blob, + struct dcerpc_auth *auth, + uint32_t *auth_length, + bool check_pad) +{ + struct ndr_pull *ndr; + enum ndr_err_code ndr_err; + uint32_t pad; + + pad = pkt_auth_blob->length - (DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length); + *auth_length = pkt_auth_blob->length - pad; + + ndr = ndr_pull_init_blob(pkt_auth_blob, mem_ctx, NULL); + if (!ndr) { + return NT_STATUS_NO_MEMORY; + } + + if (!(pkt->drep[0] & DCERPC_DREP_LE)) { + ndr->flags |= LIBNDR_FLAG_BIGENDIAN; + } + + ndr_err = ndr_pull_advance(ndr, pad); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(ndr); + return ndr_map_error2ntstatus(ndr_err); + } + + ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(ndr); + return ndr_map_error2ntstatus(ndr_err); + } + + if (check_pad && pad != auth->auth_pad_length) { + DEBUG(1,(__location__ ": WARNING: pad length mismatch. Calculated %u got %u\n", + (unsigned)pad, (unsigned)auth->auth_pad_length)); + } + + DEBUG(6,(__location__ ": auth_pad_length %u\n", + (unsigned)auth->auth_pad_length)); + + talloc_steal(mem_ctx, auth->credentials.data); + talloc_free(ndr); + + return NT_STATUS_OK; +} + + |