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