librpc/ndr: add ndr_pop_dcerpc_sec_verification_trailer()
[Samba.git] / librpc / ndr / ndr_dcerpc.c
blob3cbcef044557163746f69f069149754f334cbb48
1 /*
2 Unix SMB/CIFS implementation.
4 Manually parsed structures found in the DCERPC protocol
6 Copyright (C) Stefan Metzmacher 2014
7 Copyright (C) Gregor Beck 2014
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
24 #include "bin/default/librpc/gen_ndr/ndr_dcerpc.h"
26 #include "librpc/gen_ndr/ndr_misc.h"
27 #include "lib/util/bitmap.h"
29 const uint8_t DCERPC_SEC_VT_MAGIC[] = {0x8a,0xe3,0x13,0x71,0x02,0xf4,0x36,0x71};
31 _PUBLIC_ enum ndr_err_code ndr_push_dcerpc_sec_vt_count(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_sec_vt_count *r)
33 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
34 /* nothing */
35 return NDR_ERR_SUCCESS;
38 _PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_sec_vt_count(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_sec_vt_count *r)
40 uint32_t _saved_ofs = ndr->offset;
42 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
44 if (!(ndr_flags & NDR_SCALARS)) {
45 return NDR_ERR_SUCCESS;
48 r->count = 0;
50 while (true) {
51 uint16_t command;
52 uint16_t length;
54 NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &command));
55 NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &length));
56 NDR_CHECK(ndr_pull_advance(ndr, length));
58 r->count += 1;
60 if (command & DCERPC_SEC_VT_COMMAND_END) {
61 break;
65 ndr->offset = _saved_ofs;
66 return NDR_ERR_SUCCESS;
69 _PUBLIC_ enum ndr_err_code ndr_pop_dcerpc_sec_verification_trailer(
70 struct ndr_pull *ndr, TALLOC_CTX *mem_ctx,
71 struct dcerpc_sec_verification_trailer **_r)
73 enum ndr_err_code ndr_err;
74 uint32_t ofs;
75 uint32_t min_ofs = 0;
76 struct dcerpc_sec_verification_trailer *r;
77 DATA_BLOB sub_blob = data_blob_null;
78 struct ndr_pull *sub_ndr = NULL;
79 uint32_t remaining;
81 *_r = NULL;
83 r = talloc_zero(mem_ctx, struct dcerpc_sec_verification_trailer);
84 if (r == NULL) {
85 return NDR_ERR_ALLOC;
88 if (ndr->data_size < sizeof(DCERPC_SEC_VT_MAGIC)) {
90 * we return with r->count = 0
92 *_r = r;
93 return NDR_ERR_SUCCESS;
96 ofs = ndr->data_size - sizeof(DCERPC_SEC_VT_MAGIC);
97 /* the magic is 4 byte aligned */
98 ofs &= ~3;
100 if (ofs > DCERPC_SEC_VT_MAX_SIZE) {
102 * We just scan the last 1024 bytes.
104 min_ofs = ofs - DCERPC_SEC_VT_MAX_SIZE;
105 } else {
106 min_ofs = 0;
109 while (true) {
110 int ret;
112 ret = memcmp(&ndr->data[ofs],
113 DCERPC_SEC_VT_MAGIC,
114 sizeof(DCERPC_SEC_VT_MAGIC));
115 if (ret == 0) {
116 sub_blob = data_blob_const(&ndr->data[ofs],
117 ndr->data_size - ofs);
118 break;
121 if (ofs <= min_ofs) {
122 break;
125 ofs -= 4;
128 if (sub_blob.length == 0) {
130 * we return with r->count = 0
132 *_r = r;
133 return NDR_ERR_SUCCESS;
136 sub_ndr = ndr_pull_init_blob(&sub_blob, r);
137 if (sub_ndr == NULL) {
138 TALLOC_FREE(r);
139 return NDR_ERR_ALLOC;
142 ndr_err = ndr_pull_dcerpc_sec_verification_trailer(sub_ndr,
143 NDR_SCALARS | NDR_BUFFERS,
145 if (ndr_err == NDR_ERR_ALLOC) {
146 TALLOC_FREE(r);
147 return NDR_ERR_ALLOC;
150 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
151 goto ignore_error;
154 remaining = sub_ndr->data_size - sub_ndr->offset;
155 if (remaining > 16) {
157 * we expect not more than 16 byte of additional
158 * padding after the verification trailer.
160 goto ignore_error;
164 * We assume that we got a real verification trailer.
166 * We remove it from the available stub data.
168 ndr->data_size = ofs;
170 TALLOC_FREE(sub_ndr);
172 *_r = r;
173 return NDR_ERR_SUCCESS;
175 ignore_error:
176 TALLOC_FREE(sub_ndr);
178 * just ignore the error, it's likely
179 * that the magic we found belongs to
180 * the stub data.
182 * we return with r->count = 0
184 ZERO_STRUCTP(r);
185 *_r = r;
186 return NDR_ERR_SUCCESS;