1 /*
2    Unix SMB/CIFS implementation.
3 
4    routines for marshalling/unmarshalling special NEGOEX structures
5 
6    Copyright (C) Stefan Metzmacher 2015
7 
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.
12 
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.
17 
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/>.
20 */
21 #include "includes.h"
22 #include "librpc/gen_ndr/ndr_negoex.h"
23 #include "librpc/gen_ndr/ndr_misc.h"
24 #include "librpc/ndr/ndr_negoex.h"
25 
ndr_print_negoex_BYTE_VECTOR(struct ndr_print * ndr,const char * name,const struct negoex_BYTE_VECTOR * r)26 void ndr_print_negoex_BYTE_VECTOR(struct ndr_print *ndr, const char *name, const struct negoex_BYTE_VECTOR *r)
27 {
28 	ndr_print_struct(ndr, name, "negoex_BYTE_VECTOR");
29 	if (r == NULL) { ndr_print_null(ndr); return; }
30 	ndr->depth++;
31 	ndr_print_DATA_BLOB(ndr, "blob", r->blob);
32 	ndr->depth--;
33 }
34 
ndr_push_negoex_BYTE_VECTOR(struct ndr_push * ndr,int ndr_flags,const struct negoex_BYTE_VECTOR * r)35 enum ndr_err_code ndr_push_negoex_BYTE_VECTOR(struct ndr_push *ndr, int ndr_flags, const struct negoex_BYTE_VECTOR *r)
36 {
37 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
38 	if (ndr_flags & NDR_SCALARS) {
39 		NDR_CHECK(ndr_push_align(ndr, 5));
40 		NDR_CHECK(ndr_push_relative_ptr1(ndr, r->blob.data));
41 		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->blob.length));
42 		NDR_CHECK(ndr_push_trailer_align(ndr, 5));
43 	}
44 	if (ndr_flags & NDR_BUFFERS) {
45 		if (r->blob.data) {
46 			NDR_CHECK(ndr_push_relative_ptr2_start(ndr, r->blob.data));
47 #if 0
48 			NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, r->blob.length));
49 #endif
50 			NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->blob.data, r->blob.length));
51 			NDR_CHECK(ndr_push_relative_ptr2_end(ndr, r->blob.data));
52 		}
53 	}
54 	return NDR_ERR_SUCCESS;
55 }
56 
ndr_pull_negoex_BYTE_VECTOR(struct ndr_pull * ndr,int ndr_flags,struct negoex_BYTE_VECTOR * r)57 enum ndr_err_code ndr_pull_negoex_BYTE_VECTOR(struct ndr_pull *ndr, int ndr_flags, struct negoex_BYTE_VECTOR *r)
58 {
59 	uint32_t _ptr_data;
60 	uint32_t size_data_1 = 0;
61 	TALLOC_CTX *_mem_save_data_0 = NULL;
62 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
63 	r->_dummy = NULL;
64 	if (ndr_flags & NDR_SCALARS) {
65 		NDR_CHECK(ndr_pull_align(ndr, 5));
66 		NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_data));
67 		if (_ptr_data) {
68 			NDR_PULL_ALLOC(ndr, r->blob.data);
69 			NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->blob.data, _ptr_data));
70 		} else {
71 			r->blob.data = NULL;
72 		}
73 		r->blob.length = 0;
74 		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &size_data_1));
75 		r->_length = size_data_1;
76 		NDR_CHECK(ndr_pull_trailer_align(ndr, 5));
77 	}
78 	if (ndr_flags & NDR_BUFFERS) {
79 		if (r->blob.data) {
80 			uint32_t _relative_save_offset;
81 			_relative_save_offset = ndr->offset;
82 			NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->blob.data));
83 			_mem_save_data_0 = NDR_PULL_GET_MEM_CTX(ndr);
84 			NDR_PULL_SET_MEM_CTX(ndr, r->blob.data, 0);
85 #if 0
86 			NDR_CHECK(ndr_pull_array_size(ndr, &r->blob.data));
87 			size_data_1 = ndr_get_array_size(ndr, &r->blob.data);
88 #else
89 			size_data_1 = r->_length;
90 #endif
91 			NDR_PULL_ALLOC_N(ndr, r->blob.data, size_data_1);
92 			NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->blob.data, size_data_1));
93 			r->blob.length = size_data_1;
94 			NDR_PULL_SET_MEM_CTX(ndr, _mem_save_data_0, 0);
95 			if (ndr->offset > ndr->relative_highest_offset) {
96 				ndr->relative_highest_offset = ndr->offset;
97 			}
98 			ndr->offset = _relative_save_offset;
99 		}
100 #if 0
101 		if (r->blob.data) {
102 			NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->blob.data, r->blob.length));
103 		}
104 #endif
105 	}
106 	return NDR_ERR_SUCCESS;
107 }
108 
ndr_push_negoex_AUTH_SCHEME_VECTOR(struct ndr_push * ndr,int ndr_flags,const struct negoex_AUTH_SCHEME_VECTOR * r)109 enum ndr_err_code ndr_push_negoex_AUTH_SCHEME_VECTOR(struct ndr_push *ndr, int ndr_flags, const struct negoex_AUTH_SCHEME_VECTOR *r)
110 {
111 	uint32_t cntr_array_1;
112 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
113 	if (ndr_flags & NDR_SCALARS) {
114 		NDR_CHECK(ndr_push_align(ndr, 5));
115 		NDR_CHECK(ndr_push_relative_ptr1(ndr, r->array));
116 		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count));
117 		NDR_CHECK(ndr_push_trailer_align(ndr, 5));
118 	}
119 	if (ndr_flags & NDR_BUFFERS) {
120 		if (r->array) {
121 			NDR_CHECK(ndr_push_relative_ptr2_start(ndr, r->array));
122 #if 0
123 			NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, r->count));
124 #endif
125 			for (cntr_array_1 = 0; cntr_array_1 < (r->count); cntr_array_1++) {
126 				NDR_CHECK(ndr_push_negoex_AUTH_SCHEME(ndr, NDR_SCALARS, &r->array[cntr_array_1]));
127 			}
128 			NDR_CHECK(ndr_push_relative_ptr2_end(ndr, r->array));
129 		}
130 	}
131 	return NDR_ERR_SUCCESS;
132 }
133 
ndr_pull_negoex_AUTH_SCHEME_VECTOR(struct ndr_pull * ndr,int ndr_flags,struct negoex_AUTH_SCHEME_VECTOR * r)134 enum ndr_err_code ndr_pull_negoex_AUTH_SCHEME_VECTOR(struct ndr_pull *ndr, int ndr_flags, struct negoex_AUTH_SCHEME_VECTOR *r)
135 {
136 	uint32_t _ptr_array;
137 	uint32_t size_array_1 = 0;
138 	uint32_t cntr_array_1;
139 	TALLOC_CTX *_mem_save_array_0 = NULL;
140 	TALLOC_CTX *_mem_save_array_1 = NULL;
141 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
142 	if (ndr_flags & NDR_SCALARS) {
143 		NDR_CHECK(ndr_pull_align(ndr, 5));
144 		NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_array));
145 		if (_ptr_array) {
146 			NDR_PULL_ALLOC(ndr, r->array);
147 			NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->array, _ptr_array));
148 		} else {
149 			r->array = NULL;
150 		}
151 		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count));
152 		NDR_CHECK(ndr_pull_trailer_align(ndr, 5));
153 	}
154 	if (ndr_flags & NDR_BUFFERS) {
155 		if (r->array) {
156 			uint32_t _relative_save_offset;
157 			_relative_save_offset = ndr->offset;
158 			NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->array));
159 			_mem_save_array_0 = NDR_PULL_GET_MEM_CTX(ndr);
160 			NDR_PULL_SET_MEM_CTX(ndr, r->array, 0);
161 #if 0
162 			NDR_CHECK(ndr_pull_array_size(ndr, &r->array));
163 			size_array_1 = ndr_get_array_size(ndr, &r->array);
164 #else
165 			size_array_1 = r->count;
166 #endif
167 			NDR_PULL_ALLOC_N(ndr, r->array, size_array_1);
168 			_mem_save_array_1 = NDR_PULL_GET_MEM_CTX(ndr);
169 			NDR_PULL_SET_MEM_CTX(ndr, r->array, 0);
170 			for (cntr_array_1 = 0; cntr_array_1 < (size_array_1); cntr_array_1++) {
171 				NDR_CHECK(ndr_pull_negoex_AUTH_SCHEME(ndr, NDR_SCALARS, &r->array[cntr_array_1]));
172 			}
173 			NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_1, 0);
174 			NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_0, 0);
175 			if (ndr->offset > ndr->relative_highest_offset) {
176 				ndr->relative_highest_offset = ndr->offset;
177 			}
178 			ndr->offset = _relative_save_offset;
179 		}
180 #if 0
181 		if (r->array) {
182 			NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->array, r->count));
183 		}
184 #endif
185 	}
186 	return NDR_ERR_SUCCESS;
187 }
188 
ndr_push_negoex_EXTENSION_VECTOR(struct ndr_push * ndr,int ndr_flags,const struct negoex_EXTENSION_VECTOR * r)189 enum ndr_err_code ndr_push_negoex_EXTENSION_VECTOR(struct ndr_push *ndr, int ndr_flags, const struct negoex_EXTENSION_VECTOR *r)
190 {
191 	uint32_t cntr_array_1;
192 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
193 	if (ndr_flags & NDR_SCALARS) {
194 		NDR_CHECK(ndr_push_align(ndr, 5));
195 		NDR_CHECK(ndr_push_relative_ptr1(ndr, r->array));
196 		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count));
197 		NDR_CHECK(ndr_push_trailer_align(ndr, 5));
198 	}
199 	if (ndr_flags & NDR_BUFFERS) {
200 		if (r->array) {
201 			NDR_CHECK(ndr_push_relative_ptr2_start(ndr, r->array));
202 #if 0
203 			NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, r->count));
204 #endif
205 			for (cntr_array_1 = 0; cntr_array_1 < (r->count); cntr_array_1++) {
206 				NDR_CHECK(ndr_push_negoex_EXTENSION(ndr, NDR_SCALARS, &r->array[cntr_array_1]));
207 			}
208 			for (cntr_array_1 = 0; cntr_array_1 < (r->count); cntr_array_1++) {
209 				NDR_CHECK(ndr_push_negoex_EXTENSION(ndr, NDR_BUFFERS, &r->array[cntr_array_1]));
210 			}
211 			NDR_CHECK(ndr_push_relative_ptr2_end(ndr, r->array));
212 		}
213 	}
214 	return NDR_ERR_SUCCESS;
215 }
216 
ndr_pull_negoex_EXTENSION_VECTOR(struct ndr_pull * ndr,int ndr_flags,struct negoex_EXTENSION_VECTOR * r)217 enum ndr_err_code ndr_pull_negoex_EXTENSION_VECTOR(struct ndr_pull *ndr, int ndr_flags, struct negoex_EXTENSION_VECTOR *r)
218 {
219 	uint32_t _ptr_array;
220 	uint32_t size_array_1 = 0;
221 	uint32_t cntr_array_1;
222 	TALLOC_CTX *_mem_save_array_0 = NULL;
223 	TALLOC_CTX *_mem_save_array_1 = NULL;
224 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
225 	if (ndr_flags & NDR_SCALARS) {
226 		NDR_CHECK(ndr_pull_align(ndr, 5));
227 		NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_array));
228 		if (_ptr_array) {
229 			NDR_PULL_ALLOC(ndr, r->array);
230 			NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->array, _ptr_array));
231 		} else {
232 			r->array = NULL;
233 		}
234 		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count));
235 		NDR_CHECK(ndr_pull_trailer_align(ndr, 5));
236 	}
237 	if (ndr_flags & NDR_BUFFERS) {
238 		if (r->array) {
239 			uint32_t _relative_save_offset;
240 			_relative_save_offset = ndr->offset;
241 			NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->array));
242 			_mem_save_array_0 = NDR_PULL_GET_MEM_CTX(ndr);
243 			NDR_PULL_SET_MEM_CTX(ndr, r->array, 0);
244 #if 0
245 			NDR_CHECK(ndr_pull_array_size(ndr, &r->array));
246 			size_array_1 = ndr_get_array_size(ndr, &r->array);
247 #else
248 			size_array_1 = r->count;
249 #endif
250 			NDR_PULL_ALLOC_N(ndr, r->array, size_array_1);
251 			_mem_save_array_1 = NDR_PULL_GET_MEM_CTX(ndr);
252 			NDR_PULL_SET_MEM_CTX(ndr, r->array, 0);
253 			for (cntr_array_1 = 0; cntr_array_1 < (size_array_1); cntr_array_1++) {
254 				NDR_CHECK(ndr_pull_negoex_EXTENSION(ndr, NDR_SCALARS, &r->array[cntr_array_1]));
255 			}
256 			for (cntr_array_1 = 0; cntr_array_1 < (size_array_1); cntr_array_1++) {
257 				NDR_CHECK(ndr_pull_negoex_EXTENSION(ndr, NDR_BUFFERS, &r->array[cntr_array_1]));
258 			}
259 			NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_1, 0);
260 			NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_0, 0);
261 			if (ndr->offset > ndr->relative_highest_offset) {
262 				ndr->relative_highest_offset = ndr->offset;
263 			}
264 			ndr->offset = _relative_save_offset;
265 		}
266 #if 0
267 		if (r->array) {
268 			NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->array, r->count));
269 		}
270 #endif
271 	}
272 	return NDR_ERR_SUCCESS;
273 }
274 
ndr_push_negoex_ALERT_VECTOR(struct ndr_push * ndr,int ndr_flags,const struct negoex_ALERT_VECTOR * r)275 enum ndr_err_code ndr_push_negoex_ALERT_VECTOR(struct ndr_push *ndr, int ndr_flags, const struct negoex_ALERT_VECTOR *r)
276 {
277 	uint32_t cntr_array_1;
278 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
279 	if (ndr_flags & NDR_SCALARS) {
280 		NDR_CHECK(ndr_push_align(ndr, 5));
281 		NDR_CHECK(ndr_push_relative_ptr1(ndr, r->array));
282 		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count));
283 		NDR_CHECK(ndr_push_trailer_align(ndr, 5));
284 	}
285 	if (ndr_flags & NDR_BUFFERS) {
286 		if (r->array) {
287 			NDR_CHECK(ndr_push_relative_ptr2_start(ndr, r->array));
288 #if 0
289 			NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, r->count));
290 #endif
291 			for (cntr_array_1 = 0; cntr_array_1 < (r->count); cntr_array_1++) {
292 				NDR_CHECK(ndr_push_negoex_ALERT(ndr, NDR_SCALARS, &r->array[cntr_array_1]));
293 			}
294 			for (cntr_array_1 = 0; cntr_array_1 < (r->count); cntr_array_1++) {
295 				NDR_CHECK(ndr_push_negoex_ALERT(ndr, NDR_BUFFERS, &r->array[cntr_array_1]));
296 			}
297 			NDR_CHECK(ndr_push_relative_ptr2_end(ndr, r->array));
298 		}
299 	}
300 	return NDR_ERR_SUCCESS;
301 }
302 
ndr_pull_negoex_ALERT_VECTOR(struct ndr_pull * ndr,int ndr_flags,struct negoex_ALERT_VECTOR * r)303 enum ndr_err_code ndr_pull_negoex_ALERT_VECTOR(struct ndr_pull *ndr, int ndr_flags, struct negoex_ALERT_VECTOR *r)
304 {
305 	uint32_t _ptr_array;
306 	uint32_t size_array_1 = 0;
307 	uint32_t cntr_array_1;
308 	TALLOC_CTX *_mem_save_array_0 = NULL;
309 	TALLOC_CTX *_mem_save_array_1 = NULL;
310 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
311 	if (ndr_flags & NDR_SCALARS) {
312 		NDR_CHECK(ndr_pull_align(ndr, 5));
313 		NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_array));
314 		if (_ptr_array) {
315 			NDR_PULL_ALLOC(ndr, r->array);
316 			NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->array, _ptr_array));
317 		} else {
318 			r->array = NULL;
319 		}
320 		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count));
321 		NDR_CHECK(ndr_pull_trailer_align(ndr, 5));
322 	}
323 	if (ndr_flags & NDR_BUFFERS) {
324 		if (r->array) {
325 			uint32_t _relative_save_offset;
326 			_relative_save_offset = ndr->offset;
327 			NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->array));
328 			_mem_save_array_0 = NDR_PULL_GET_MEM_CTX(ndr);
329 			NDR_PULL_SET_MEM_CTX(ndr, r->array, 0);
330 #if 0
331 			NDR_CHECK(ndr_pull_array_size(ndr, &r->array));
332 			size_array_1 = ndr_get_array_size(ndr, &r->array);
333 #else
334 			size_array_1 = r->count;
335 #endif
336 			NDR_PULL_ALLOC_N(ndr, r->array, size_array_1);
337 			_mem_save_array_1 = NDR_PULL_GET_MEM_CTX(ndr);
338 			NDR_PULL_SET_MEM_CTX(ndr, r->array, 0);
339 			for (cntr_array_1 = 0; cntr_array_1 < (size_array_1); cntr_array_1++) {
340 				NDR_CHECK(ndr_pull_negoex_ALERT(ndr, NDR_SCALARS, &r->array[cntr_array_1]));
341 			}
342 			for (cntr_array_1 = 0; cntr_array_1 < (size_array_1); cntr_array_1++) {
343 				NDR_CHECK(ndr_pull_negoex_ALERT(ndr, NDR_BUFFERS, &r->array[cntr_array_1]));
344 			}
345 			NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_1, 0);
346 			NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_0, 0);
347 			if (ndr->offset > ndr->relative_highest_offset) {
348 				ndr->relative_highest_offset = ndr->offset;
349 			}
350 			ndr->offset = _relative_save_offset;
351 		}
352 #if 0
353 		if (r->array) {
354 			NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->array, r->count));
355 		}
356 #endif
357 	}
358 	return NDR_ERR_SUCCESS;
359 }
360 
ndr_negoex_MESSAGE_header_length(const struct negoex_MESSAGE * r)361 size_t ndr_negoex_MESSAGE_header_length(const struct negoex_MESSAGE *r)
362 {
363 	size_t size = 0;
364 
365 	size += 8;  /* signature */
366 	size += 4;  /* type */
367 	size += 4;  /* sequence_number */
368 	size += 4;  /* header_length */
369 	size += 4;  /* message_length */
370 	size += 16; /* conversation_id */
371 
372 	switch (r->type) {
373 	case NEGOEX_MESSAGE_TYPE_INITIATOR_NEGO:
374 	case NEGOEX_MESSAGE_TYPE_ACCEPTOR_NEGO:
375 		size += 32; /* random */
376 		size += 8;  /* protocol_version */
377 		size += 8;  /* auth_schemes */
378 		size += 8;  /* extensions */
379 		break;
380 
381 	case NEGOEX_MESSAGE_TYPE_INITIATOR_META_DATA:
382 	case NEGOEX_MESSAGE_TYPE_ACCEPTOR_META_DATA:
383 	case NEGOEX_MESSAGE_TYPE_CHALLENGE:
384 	case NEGOEX_MESSAGE_TYPE_AP_REQUEST:
385 		size += 16; /* auth_scheme */
386 		size += 8;  /* exchange */
387 		break;
388 
389 	case NEGOEX_MESSAGE_TYPE_VERIFY:
390 		size += 16; /* auth_scheme */
391 		size += 4;  /* checksum.header_length */
392 		size += 4;  /* checksum.scheme */
393 		size += 4;  /* checksum.type */
394 		size += 8;  /* checksum.value */
395 		break;
396 
397 	case NEGOEX_MESSAGE_TYPE_ALERT:
398 		size += 16; /* auth_scheme */
399 		size += 4;  /* status */
400 		size += 8;  /* alerts */
401 		break;
402 	}
403 
404 	return size;
405 }
406 
ndr_pull_negoex_MESSAGE(struct ndr_pull * ndr,int ndr_flags,struct negoex_MESSAGE * r)407 enum ndr_err_code ndr_pull_negoex_MESSAGE(struct ndr_pull *ndr, int ndr_flags, struct negoex_MESSAGE *r)
408 {
409 	uint32_t _save_relative_base_offset = ndr_pull_get_relative_base_offset(ndr);
410 	uint32_t size_signature_0 = 0;
411 	uint32_t start_data_size = ndr->data_size;
412 	uint32_t saved_offset = 0;
413 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
414 	if (ndr_flags & NDR_SCALARS) {
415 		NDR_CHECK(ndr_pull_align(ndr, 5));
416 		NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset));
417 		size_signature_0 = 8;
418 		NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->signature, size_signature_0, sizeof(uint8_t), CH_DOS));
419 		NDR_CHECK(ndr_pull_negoex_MESSAGE_TYPE(ndr, NDR_SCALARS, &r->type));
420 		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sequence_number));
421 		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->header_length));
422 		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->message_length));
423 		saved_offset = ndr->offset;
424 		ndr->offset = ndr->relative_base_offset;
425 		NDR_PULL_NEED_BYTES(ndr, r->message_length);
426 		ndr->data_size = ndr->offset + r->message_length;
427 		ndr->offset = saved_offset;
428 		NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->conversation_id));
429 		NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->p, r->type));
430 		NDR_CHECK(ndr_pull_negoex_PAYLOAD(ndr, NDR_SCALARS, &r->p));
431 		NDR_CHECK(ndr_pull_trailer_align(ndr, 5));
432 		ndr->offset = ndr->data_size;
433 		ndr->data_size = start_data_size;
434 	}
435 	if (ndr_flags & NDR_BUFFERS) {
436 		NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, r));
437 		saved_offset = ndr->offset;
438 		ndr->offset = ndr->relative_base_offset;
439 		NDR_PULL_NEED_BYTES(ndr, r->message_length);
440 		ndr->data_size = ndr->offset + r->message_length;
441 		ndr->offset = saved_offset;
442 		NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->p, r->type));
443 		NDR_CHECK(ndr_pull_negoex_PAYLOAD(ndr, NDR_BUFFERS, &r->p));
444 		ndr->offset = ndr->data_size;
445 		ndr->data_size = start_data_size;
446 	}
447 	ndr_pull_restore_relative_base_offset(ndr, _save_relative_base_offset);
448 	return NDR_ERR_SUCCESS;
449 }
450 
ndr_push_negoex_MESSAGE_ARRAY(struct ndr_push * ndr,int ndr_flags,const struct negoex_MESSAGE_ARRAY * r)451 enum ndr_err_code ndr_push_negoex_MESSAGE_ARRAY(struct ndr_push *ndr, int ndr_flags, const struct negoex_MESSAGE_ARRAY *r)
452 {
453 	uint32_t cntr_messages_0;
454 	{
455 		uint32_t _flags_save_STRUCT = ndr->flags;
456 		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
457 		NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
458 		if (ndr_flags & NDR_SCALARS) {
459 			NDR_CHECK(ndr_push_align(ndr, 5));
460 			for (cntr_messages_0 = 0; cntr_messages_0 < (r->count); cntr_messages_0++) {
461 				NDR_CHECK(ndr_push_negoex_MESSAGE(ndr, NDR_SCALARS|NDR_BUFFERS, &r->messages[cntr_messages_0]));
462 			}
463 			NDR_CHECK(ndr_push_trailer_align(ndr, 5));
464 		}
465 		ndr->flags = _flags_save_STRUCT;
466 	}
467 	return NDR_ERR_SUCCESS;
468 }
469 
ndr_pull_negoex_MESSAGE_ARRAY(struct ndr_pull * ndr,int ndr_flags,struct negoex_MESSAGE_ARRAY * r)470 enum ndr_err_code ndr_pull_negoex_MESSAGE_ARRAY(struct ndr_pull *ndr, int ndr_flags, struct negoex_MESSAGE_ARRAY *r)
471 {
472 	uint32_t size_messages_0 = 0;
473 	uint32_t cntr_messages_0;
474 	TALLOC_CTX *_mem_save_messages_0 = NULL;
475 	{
476 		uint32_t _flags_save_STRUCT = ndr->flags;
477 		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
478 		NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
479 		if (ndr_flags & NDR_SCALARS) {
480 			uint32_t saved_offset = ndr->offset;
481 			uint32_t available = 0;
482 			NDR_CHECK(ndr_pull_align(ndr, 5));
483 			r->count = 0;
484 			available = ndr->data_size - ndr->offset;
485 			while (available > 0) {
486 				uint32_t length;
487 
488 				/*
489 				 * The common header is 40 bytes
490 				 * and message_length is at offset 20
491 				 */
492 				NDR_PULL_NEED_BYTES(ndr, 40);
493 				ndr->offset += 20;
494 				NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &length));
495 				ndr->offset -= 24;
496 				if (length < 40) {
497 					/*
498 					 * let the pull function catch the error
499 					 */
500 					length = 40;
501 				}
502 				NDR_PULL_NEED_BYTES(ndr, length);
503 				ndr->offset += length;
504 				available -= length;
505 				r->count++;
506 			}
507 			ndr->offset = saved_offset;
508 			size_messages_0 = r->count;
509 			NDR_PULL_ALLOC_N(ndr, r->messages, size_messages_0);
510 			_mem_save_messages_0 = NDR_PULL_GET_MEM_CTX(ndr);
511 			NDR_PULL_SET_MEM_CTX(ndr, r->messages, 0);
512 			for (cntr_messages_0 = 0; cntr_messages_0 < (size_messages_0); cntr_messages_0++) {
513 				NDR_CHECK(ndr_pull_negoex_MESSAGE(ndr, NDR_SCALARS|NDR_BUFFERS, &r->messages[cntr_messages_0]));
514 			}
515 			NDR_PULL_SET_MEM_CTX(ndr, _mem_save_messages_0, 0);
516 			NDR_CHECK(ndr_pull_trailer_align(ndr, 5));
517 		}
518 		ndr->flags = _flags_save_STRUCT;
519 	}
520 	return NDR_ERR_SUCCESS;
521 }
522