summaryrefslogtreecommitdiff
path: root/source4/librpc/rpc/dcerpc_util.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2010-02-13 15:32:23 +1100
committerAndrew Tridgell <tridge@samba.org>2010-02-13 23:12:29 +1100
commitda86f08605f8ec9fa6d3e1c122ec47309deef994 (patch)
tree52e249167a67d50ce6c76d4d38128d4fd25461c5 /source4/librpc/rpc/dcerpc_util.c
parent3ae75a424890fdeddd12535c9330186ec2fcd899 (diff)
downloadsamba-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.c60
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;
+}
+
+