auth/credentials_krb5: fix memory leak in cli_credentials_failed_kerberos_login().
[Samba.git] / librpc / ndr / ndr_dcerpc.c
blobca09fb6d88edd8ab6a5140143ed270b0e052722e
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 "librpc/gen_ndr/ndr_dcerpc.h"
25 #include "librpc/gen_ndr/ndr_misc.h"
27 const uint8_t DCERPC_SEC_VT_MAGIC[] = {0x8a,0xe3,0x13,0x71,0x02,0xf4,0x36,0x71};
29 _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)
31 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
32 /* nothing */
33 return NDR_ERR_SUCCESS;
36 _PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_sec_vt_count(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_sec_vt_count *r)
38 uint32_t _saved_ofs = ndr->offset;
40 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
42 if (!(ndr_flags & NDR_SCALARS)) {
43 return NDR_ERR_SUCCESS;
46 r->count = 0;
48 while (true) {
49 uint16_t command;
50 uint16_t length;
52 NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &command));
53 NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &length));
54 NDR_CHECK(ndr_pull_advance(ndr, length));
56 r->count += 1;
58 if (command & DCERPC_SEC_VT_COMMAND_END) {
59 break;
63 ndr->offset = _saved_ofs;
64 return NDR_ERR_SUCCESS;
67 _PUBLIC_ enum ndr_err_code ndr_pop_dcerpc_sec_verification_trailer(
68 struct ndr_pull *ndr, TALLOC_CTX *mem_ctx,
69 struct dcerpc_sec_verification_trailer **_r)
71 enum ndr_err_code ndr_err;
72 uint32_t ofs;
73 uint32_t min_ofs = 0;
74 struct dcerpc_sec_verification_trailer *r;
75 DATA_BLOB sub_blob = data_blob_null;
76 struct ndr_pull *sub_ndr = NULL;
77 uint32_t remaining;
79 *_r = NULL;
81 r = talloc_zero(mem_ctx, struct dcerpc_sec_verification_trailer);
82 if (r == NULL) {
83 return NDR_ERR_ALLOC;
86 if (ndr->data_size < sizeof(DCERPC_SEC_VT_MAGIC)) {
88 * we return with r->count = 0
90 *_r = r;
91 return NDR_ERR_SUCCESS;
94 ofs = ndr->data_size - sizeof(DCERPC_SEC_VT_MAGIC);
95 /* the magic is 4 byte aligned */
96 ofs &= ~3;
98 if (ofs > DCERPC_SEC_VT_MAX_SIZE) {
100 * We just scan the last 1024 bytes.
102 min_ofs = ofs - DCERPC_SEC_VT_MAX_SIZE;
103 } else {
104 min_ofs = 0;
107 while (true) {
108 int ret;
110 ret = memcmp(&ndr->data[ofs],
111 DCERPC_SEC_VT_MAGIC,
112 sizeof(DCERPC_SEC_VT_MAGIC));
113 if (ret == 0) {
114 sub_blob = data_blob_const(&ndr->data[ofs],
115 ndr->data_size - ofs);
116 break;
119 if (ofs <= min_ofs) {
120 break;
123 ofs -= 4;
126 if (sub_blob.length == 0) {
128 * we return with r->count = 0
130 *_r = r;
131 return NDR_ERR_SUCCESS;
134 sub_ndr = ndr_pull_init_blob(&sub_blob, r);
135 if (sub_ndr == NULL) {
136 TALLOC_FREE(r);
137 return NDR_ERR_ALLOC;
140 ndr_err = ndr_pull_dcerpc_sec_verification_trailer(sub_ndr,
141 NDR_SCALARS | NDR_BUFFERS,
143 if (ndr_err == NDR_ERR_ALLOC) {
144 TALLOC_FREE(r);
145 return NDR_ERR_ALLOC;
148 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
149 goto ignore_error;
152 remaining = sub_ndr->data_size - sub_ndr->offset;
153 if (remaining > 16) {
155 * we expect not more than 16 byte of additional
156 * padding after the verification trailer.
158 goto ignore_error;
162 * We assume that we got a real verification trailer.
164 * We remove it from the available stub data.
166 ndr->data_size = ofs;
168 TALLOC_FREE(sub_ndr);
170 *_r = r;
171 return NDR_ERR_SUCCESS;
173 ignore_error:
174 TALLOC_FREE(sub_ndr);
176 * just ignore the error, it's likely
177 * that the magic we found belongs to
178 * the stub data.
180 * we return with r->count = 0
182 ZERO_STRUCTP(r);
183 *_r = r;
184 return NDR_ERR_SUCCESS;