lib: Align an integer type
[vlendec/samba-autobuild/.git] / librpc / ndr / ndr_negoex.c
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
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
35 enum ndr_err_code ndr_push_negoex_BYTE_VECTOR(struct ndr_push *ndr, ndr_flags_type 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
57 enum ndr_err_code ndr_pull_negoex_BYTE_VECTOR(struct ndr_pull *ndr, ndr_flags_type 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_steal_array_size(ndr, (void*)&r->blob.data, r->blob.length));
103                 }
104 #endif
105         }
106         return NDR_ERR_SUCCESS;
107 }
108
109 enum ndr_err_code ndr_push_negoex_AUTH_SCHEME_VECTOR(struct ndr_push *ndr, ndr_flags_type 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
134 enum ndr_err_code ndr_pull_negoex_AUTH_SCHEME_VECTOR(struct ndr_pull *ndr, ndr_flags_type 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_steal_array_size(ndr, (void*)&r->array, r->count));
183                 }
184 #endif
185         }
186         return NDR_ERR_SUCCESS;
187 }
188
189 enum ndr_err_code ndr_push_negoex_EXTENSION_VECTOR(struct ndr_push *ndr, ndr_flags_type 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
217 enum ndr_err_code ndr_pull_negoex_EXTENSION_VECTOR(struct ndr_pull *ndr, ndr_flags_type 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_steal_array_size(ndr, (void*)&r->array, r->count));
269                 }
270 #endif
271         }
272         return NDR_ERR_SUCCESS;
273 }
274
275 enum ndr_err_code ndr_push_negoex_ALERT_VECTOR(struct ndr_push *ndr, ndr_flags_type 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
303 enum ndr_err_code ndr_pull_negoex_ALERT_VECTOR(struct ndr_pull *ndr, ndr_flags_type 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_steal_array_size(ndr, (void*)&r->array, r->count));
355                 }
356 #endif
357         }
358         return NDR_ERR_SUCCESS;
359 }
360
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
407 enum ndr_err_code ndr_pull_negoex_MESSAGE(struct ndr_pull *ndr, ndr_flags_type 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
451 enum ndr_err_code ndr_push_negoex_MESSAGE_ARRAY(struct ndr_push *ndr, ndr_flags_type ndr_flags, const struct negoex_MESSAGE_ARRAY *r)
452 {
453         uint32_t cntr_messages_0;
454         {
455                 libndr_flags _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
470 enum ndr_err_code ndr_pull_negoex_MESSAGE_ARRAY(struct ndr_pull *ndr, ndr_flags_type 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                 libndr_flags _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 }