2 Unix SMB/CIFS implementation.
5 Copyright (C) Andrew Tridgell 2003-2005
6 Copyright (C) Jelmer Vernooij 2004-2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "librpc/rpc/dcerpc.h"
24 #include "librpc/gen_ndr/ndr_dcerpc.h"
26 /* we need to be able to get/set the fragment length without doing a full
28 void dcerpc_set_frag_length(DATA_BLOB *blob, uint16_t v)
30 if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {
31 SSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, v);
33 RSSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, v);
37 uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob)
39 if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {
40 return SVAL(blob->data, DCERPC_FRAG_LEN_OFFSET);
42 return RSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET);
46 void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v)
48 if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {
49 SSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, v);
51 RSSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, v);
55 uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob)
57 return blob->data[DCERPC_DREP_OFFSET];
61 pull an dcerpc_auth structure, taking account of any auth padding in
62 the blob at the end of the structure
64 NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt,
66 DATA_BLOB *pkt_auth_blob,
67 struct dcerpc_auth *auth,
68 uint32_t *auth_length,
72 enum ndr_err_code ndr_err;
75 pad = pkt_auth_blob->length - (DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length);
77 /* paranoia check for pad size. This would be caught anyway by
78 the ndr_pull_advance() a few lines down, but it scared
79 Jeremy enough for him to call me, so we might as well check
80 it now, just to prevent someone posting a bogus YouTube
83 if (pad > pkt_auth_blob->length) {
84 return NT_STATUS_INFO_LENGTH_MISMATCH;
87 *auth_length = pkt_auth_blob->length - pad;
89 ndr = ndr_pull_init_blob(pkt_auth_blob, mem_ctx);
91 return NT_STATUS_NO_MEMORY;
94 if (!(pkt->drep[0] & DCERPC_DREP_LE)) {
95 ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
98 ndr_err = ndr_pull_advance(ndr, pad);
99 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
101 return ndr_map_error2ntstatus(ndr_err);
104 ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth);
105 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
107 return ndr_map_error2ntstatus(ndr_err);
110 if (check_pad && pad != auth->auth_pad_length) {
111 DEBUG(1,(__location__ ": WARNING: pad length mismatch. Calculated %u got %u\n",
112 (unsigned)pad, (unsigned)auth->auth_pad_length));
115 DEBUG(6,(__location__ ": auth_pad_length %u\n",
116 (unsigned)auth->auth_pad_length));
118 talloc_steal(mem_ctx, auth->credentials.data);