diff options
-rw-r--r-- | librpc/rpc/dcerpc_util.c | 64 | ||||
-rw-r--r-- | source3/include/proto.h | 6 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc_util.c | 67 |
3 files changed, 70 insertions, 67 deletions
diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c index c859bedf2d..a4bc096ddd 100644 --- a/librpc/rpc/dcerpc_util.c +++ b/librpc/rpc/dcerpc_util.c @@ -51,3 +51,67 @@ void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v) RSSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, v); } } + +/* + 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); + + /* paranoia check for pad size. This would be caught anyway by + the ndr_pull_advance() a few lines down, but it scared + Jeremy enough for him to call me, so we might as well check + it now, just to prevent someone posting a bogus YouTube + video in the future. + */ + if (pad > pkt_auth_blob->length) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + + *auth_length = pkt_auth_blob->length - pad; + + ndr = ndr_pull_init_blob(pkt_auth_blob, mem_ctx); + 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; +} diff --git a/source3/include/proto.h b/source3/include/proto.h index 302999ffbc..1b8aa485d5 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2936,6 +2936,12 @@ NTSTATUS dcerpc_fault_to_nt_status(uint32_t fault_code); void dcerpc_set_frag_length(DATA_BLOB *blob, uint16_t v); uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob); void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v); +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); /* The following definitions come from libsmb/dsgetdcname.c */ diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index 5873e9dd95..b2bd145d1a 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -795,70 +795,3 @@ _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); - - /* paranoia check for pad size. This would be caught anyway by - the ndr_pull_advance() a few lines down, but it scared - Jeremy enough for him to call me, so we might as well check - it now, just to prevent someone posting a bogus YouTube - video in the future. - */ - if (pad > pkt_auth_blob->length) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - - *auth_length = pkt_auth_blob->length - pad; - - ndr = ndr_pull_init_blob(pkt_auth_blob, mem_ctx); - 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; -} - - |