librpc/ndr: make use of ndr_dump_data() in ndr_print_array_uint8()
[mat/samba.git] / librpc / ndr / ndr_basic.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    routines for marshalling/unmarshalling basic types
5
6    Copyright (C) Andrew Tridgell 2003
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
22 #include "includes.h"
23 #include "system/network.h"
24 #include "librpc/ndr/libndr.h"
25 #include "lib/util/util_net.h"
26
27 #define NDR_SVAL(ndr, ofs) (NDR_BE(ndr)?RSVAL(ndr->data,ofs):SVAL(ndr->data,ofs))
28 #define NDR_IVAL(ndr, ofs) (NDR_BE(ndr)?RIVAL(ndr->data,ofs):IVAL(ndr->data,ofs))
29 #define NDR_IVALS(ndr, ofs) (NDR_BE(ndr)?RIVALS(ndr->data,ofs):IVALS(ndr->data,ofs))
30 #define NDR_SSVAL(ndr, ofs, v) do { if (NDR_BE(ndr))  { RSSVAL(ndr->data,ofs,v); } else SSVAL(ndr->data,ofs,v); } while (0)
31 #define NDR_SIVAL(ndr, ofs, v) do { if (NDR_BE(ndr))  { RSIVAL(ndr->data,ofs,v); } else SIVAL(ndr->data,ofs,v); } while (0)
32 #define NDR_SIVALS(ndr, ofs, v) do { if (NDR_BE(ndr))  { RSIVALS(ndr->data,ofs,v); } else SIVALS(ndr->data,ofs,v); } while (0)
33
34
35 static void ndr_dump_data(struct ndr_print *ndr, const uint8_t *buf, int len);
36
37 /*
38   check for data leaks from the server by looking for non-zero pad bytes
39   these could also indicate that real structure elements have been
40   mistaken for padding in the IDL
41 */
42 _PUBLIC_ void ndr_check_padding(struct ndr_pull *ndr, size_t n)
43 {
44         size_t ofs2 = (ndr->offset + (n-1)) & ~(n-1);
45         int i;
46         for (i=ndr->offset;i<ofs2;i++) {
47                 if (ndr->data[i] != 0) {
48                         break;
49                 }
50         }
51         if (i<ofs2) {
52                 DEBUG(0,("WARNING: Non-zero padding to %d: ", (int)n));
53                 for (i=ndr->offset;i<ofs2;i++) {
54                         DEBUG(0,("%02x ", ndr->data[i]));
55                 }
56                 DEBUG(0,("\n"));
57         }
58
59 }
60
61 /*
62   parse a int8_t
63 */
64 _PUBLIC_ enum ndr_err_code ndr_pull_int8(struct ndr_pull *ndr, int ndr_flags, int8_t *v)
65 {
66         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
67         NDR_PULL_NEED_BYTES(ndr, 1);
68         *v = (int8_t)CVAL(ndr->data, ndr->offset);
69         ndr->offset += 1;
70         return NDR_ERR_SUCCESS;
71 }
72
73 /*
74   parse a uint8_t
75 */
76 _PUBLIC_ enum ndr_err_code ndr_pull_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *v)
77 {
78         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
79         NDR_PULL_NEED_BYTES(ndr, 1);
80         *v = CVAL(ndr->data, ndr->offset);
81         ndr->offset += 1;
82         return NDR_ERR_SUCCESS;
83 }
84
85 /*
86   parse a int16_t
87 */
88 _PUBLIC_ enum ndr_err_code ndr_pull_int16(struct ndr_pull *ndr, int ndr_flags, int16_t *v)
89 {
90         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
91         NDR_PULL_ALIGN(ndr, 2);
92         NDR_PULL_NEED_BYTES(ndr, 2);
93         *v = (uint16_t)NDR_SVAL(ndr, ndr->offset);
94         ndr->offset += 2;
95         return NDR_ERR_SUCCESS;
96 }
97
98 /*
99   parse a uint16_t
100 */
101 _PUBLIC_ enum ndr_err_code ndr_pull_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
102 {
103         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
104         NDR_PULL_ALIGN(ndr, 2);
105         NDR_PULL_NEED_BYTES(ndr, 2);
106         *v = NDR_SVAL(ndr, ndr->offset);
107         ndr->offset += 2;
108         return NDR_ERR_SUCCESS;
109 }
110
111 /*
112   parse a uint1632_t
113 */
114 _PUBLIC_ enum ndr_err_code ndr_pull_uint1632(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
115 {
116         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
117         if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
118                 uint32_t v32 = 0;
119                 enum ndr_err_code err = ndr_pull_uint32(ndr, ndr_flags, &v32);
120                 *v = v32;
121                 if (unlikely(v32 != *v)) {
122                         DEBUG(0,(__location__ ": non-zero upper 16 bits 0x%08x\n", (unsigned)v32));
123                         return NDR_ERR_NDR64;
124                 }
125                 return err;
126         }
127         return ndr_pull_uint16(ndr, ndr_flags, v);
128 }
129
130 /*
131   parse a int32_t
132 */
133 _PUBLIC_ enum ndr_err_code ndr_pull_int32(struct ndr_pull *ndr, int ndr_flags, int32_t *v)
134 {
135         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
136         NDR_PULL_ALIGN(ndr, 4);
137         NDR_PULL_NEED_BYTES(ndr, 4);
138         *v = NDR_IVALS(ndr, ndr->offset);
139         ndr->offset += 4;
140         return NDR_ERR_SUCCESS;
141 }
142
143 /*
144   parse a uint32_t
145 */
146 _PUBLIC_ enum ndr_err_code ndr_pull_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *v)
147 {
148         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
149         NDR_PULL_ALIGN(ndr, 4);
150         NDR_PULL_NEED_BYTES(ndr, 4);
151         *v = NDR_IVAL(ndr, ndr->offset);
152         ndr->offset += 4;
153         return NDR_ERR_SUCCESS;
154 }
155
156 /*
157   parse a arch dependent uint32/uint64
158 */
159 _PUBLIC_ enum ndr_err_code ndr_pull_uint3264(struct ndr_pull *ndr, int ndr_flags, uint32_t *v)
160 {
161         uint64_t v64;
162         enum ndr_err_code err;
163         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
164         if (likely(!(ndr->flags & LIBNDR_FLAG_NDR64))) {
165                 return ndr_pull_uint32(ndr, ndr_flags, v);
166         }
167         err = ndr_pull_hyper(ndr, ndr_flags, &v64);
168         *v = (uint32_t)v64;
169         if (unlikely(v64 != *v)) {
170                 DEBUG(0,(__location__ ": non-zero upper 32 bits 0x%016llx\n",
171                          (unsigned long long)v64));
172                 return NDR_ERR_NDR64;
173         }
174         return err;
175 }
176
177 /*
178   parse a double
179 */
180 _PUBLIC_ enum ndr_err_code ndr_pull_double(struct ndr_pull *ndr, int ndr_flags, double *v)
181 {
182         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
183         NDR_PULL_ALIGN(ndr, 8);
184         NDR_PULL_NEED_BYTES(ndr, 8);
185         memcpy(v, ndr->data+ndr->offset, 8);
186         ndr->offset += 8;
187         return NDR_ERR_SUCCESS;
188 }
189
190 /*
191   parse a pointer referent identifier stored in 2 bytes
192 */
193 _PUBLIC_ enum ndr_err_code ndr_pull_relative_ptr_short(struct ndr_pull *ndr, uint16_t *v)
194 {
195         NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, v));
196         if (*v != 0) {
197                 ndr->ptr_count++;
198         }
199         *(v) -= ndr->relative_rap_convert;
200         return NDR_ERR_SUCCESS;
201 }
202
203 /*
204   parse a pointer referent identifier
205 */
206 _PUBLIC_ enum ndr_err_code ndr_pull_generic_ptr(struct ndr_pull *ndr, uint32_t *v)
207 {
208         NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, v));
209         if (*v != 0) {
210                 ndr->ptr_count++;
211         }
212         return NDR_ERR_SUCCESS;
213 }
214
215 /*
216   parse a ref pointer referent identifier
217 */
218 _PUBLIC_ enum ndr_err_code ndr_pull_ref_ptr(struct ndr_pull *ndr, uint32_t *v)
219 {
220         NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, v));
221         /* ref pointers always point to data */
222         *v = 1;
223         return NDR_ERR_SUCCESS;
224 }
225
226 /*
227   parse a udlong
228 */
229 _PUBLIC_ enum ndr_err_code ndr_pull_udlong(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
230 {
231         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
232         NDR_PULL_ALIGN(ndr, 4);
233         NDR_PULL_NEED_BYTES(ndr, 8);
234         *v = NDR_IVAL(ndr, ndr->offset);
235         *v |= (uint64_t)(NDR_IVAL(ndr, ndr->offset+4)) << 32;
236         ndr->offset += 8;
237         return NDR_ERR_SUCCESS;
238 }
239
240 /*
241   parse a udlongr
242 */
243 _PUBLIC_ enum ndr_err_code ndr_pull_udlongr(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
244 {
245         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
246         NDR_PULL_ALIGN(ndr, 4);
247         NDR_PULL_NEED_BYTES(ndr, 8);
248         *v = ((uint64_t)NDR_IVAL(ndr, ndr->offset)) << 32;
249         *v |= NDR_IVAL(ndr, ndr->offset+4);
250         ndr->offset += 8;
251         return NDR_ERR_SUCCESS;
252 }
253
254 /*
255   parse a dlong
256 */
257 _PUBLIC_ enum ndr_err_code ndr_pull_dlong(struct ndr_pull *ndr, int ndr_flags, int64_t *v)
258 {
259         return ndr_pull_udlong(ndr, ndr_flags, (uint64_t *)v);
260 }
261
262 /*
263   parse a hyper
264 */
265 _PUBLIC_ enum ndr_err_code ndr_pull_hyper(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
266 {
267         NDR_PULL_ALIGN(ndr, 8);
268         if (NDR_BE(ndr)) {
269                 return ndr_pull_udlongr(ndr, ndr_flags, v);
270         }
271         return ndr_pull_udlong(ndr, ndr_flags, v);
272 }
273
274 /*
275   parse a pointer
276 */
277 _PUBLIC_ enum ndr_err_code ndr_pull_pointer(struct ndr_pull *ndr, int ndr_flags, void* *v)
278 {
279         uintptr_t h;
280         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
281         NDR_PULL_ALIGN(ndr, sizeof(h));
282         NDR_PULL_NEED_BYTES(ndr, sizeof(h));
283         memcpy(&h, ndr->data+ndr->offset, sizeof(h));
284         ndr->offset += sizeof(h);
285         *v = (void *)h;
286         return NDR_ERR_SUCCESS;
287 }
288
289 /*
290   pull a NTSTATUS
291 */
292 _PUBLIC_ enum ndr_err_code ndr_pull_NTSTATUS(struct ndr_pull *ndr, int ndr_flags, NTSTATUS *status)
293 {
294         uint32_t v;
295         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
296         NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
297         *status = NT_STATUS(v);
298         return NDR_ERR_SUCCESS;
299 }
300
301 /*
302   push a NTSTATUS
303 */
304 _PUBLIC_ enum ndr_err_code ndr_push_NTSTATUS(struct ndr_push *ndr, int ndr_flags, NTSTATUS status)
305 {
306         return ndr_push_uint32(ndr, ndr_flags, NT_STATUS_V(status));
307 }
308
309 _PUBLIC_ void ndr_print_NTSTATUS(struct ndr_print *ndr, const char *name, NTSTATUS r)
310 {
311         ndr->print(ndr, "%-25s: %s", name, nt_errstr(r));
312 }
313
314 /*
315   pull a WERROR
316 */
317 _PUBLIC_ enum ndr_err_code ndr_pull_WERROR(struct ndr_pull *ndr, int ndr_flags, WERROR *status)
318 {
319         uint32_t v;
320         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
321         NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
322         *status = W_ERROR(v);
323         return NDR_ERR_SUCCESS;
324 }
325
326
327 /*
328   parse a uint8_t enum
329 */
330 _PUBLIC_ enum ndr_err_code ndr_pull_enum_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *v)
331 {
332         return ndr_pull_uint8(ndr, ndr_flags, v);
333 }
334
335 /*
336   parse a uint16_t enum
337 */
338 _PUBLIC_ enum ndr_err_code ndr_pull_enum_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
339 {
340         return ndr_pull_uint16(ndr, ndr_flags, v);
341 }
342
343 /*
344   parse a uint1632_t enum (uint32_t on NDR64)
345 */
346 _PUBLIC_ enum ndr_err_code ndr_pull_enum_uint1632(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
347 {
348         if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
349                 uint32_t v32;
350                 NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &v32));
351                 *v = v32;
352                 if (v32 != *v) {
353                         DEBUG(0,(__location__ ": non-zero upper 16 bits 0x%08x\n", (unsigned)v32));
354                         return NDR_ERR_NDR64;
355                 }
356                 return NDR_ERR_SUCCESS;
357         }
358         return ndr_pull_uint16(ndr, ndr_flags, v);
359 }
360
361 /*
362   parse a uint32_t enum
363 */
364 _PUBLIC_ enum ndr_err_code ndr_pull_enum_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *v)
365 {
366         return ndr_pull_uint32(ndr, ndr_flags, v);
367 }
368
369 /*
370   push a uint8_t enum
371 */
372 _PUBLIC_ enum ndr_err_code ndr_push_enum_uint8(struct ndr_push *ndr, int ndr_flags, uint8_t v)
373 {
374         return ndr_push_uint8(ndr, ndr_flags, v);
375 }
376
377 /*
378   push a uint16_t enum
379 */
380 _PUBLIC_ enum ndr_err_code ndr_push_enum_uint16(struct ndr_push *ndr, int ndr_flags, uint16_t v)
381 {
382         return ndr_push_uint16(ndr, ndr_flags, v);
383 }
384
385 /*
386   push a uint32_t enum
387 */
388 _PUBLIC_ enum ndr_err_code ndr_push_enum_uint32(struct ndr_push *ndr, int ndr_flags, uint32_t v)
389 {
390         return ndr_push_uint32(ndr, ndr_flags, v);
391 }
392
393 /*
394   push a uint1632_t enum
395 */
396 _PUBLIC_ enum ndr_err_code ndr_push_enum_uint1632(struct ndr_push *ndr, int ndr_flags, uint16_t v)
397 {
398         if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
399                 return ndr_push_uint32(ndr, ndr_flags, v);
400         }
401         return ndr_push_uint16(ndr, ndr_flags, v);
402 }
403
404 /*
405   push a WERROR
406 */
407 _PUBLIC_ enum ndr_err_code ndr_push_WERROR(struct ndr_push *ndr, int ndr_flags, WERROR status)
408 {
409         return ndr_push_uint32(ndr, NDR_SCALARS, W_ERROR_V(status));
410 }
411
412 _PUBLIC_ void ndr_print_WERROR(struct ndr_print *ndr, const char *name, WERROR r)
413 {
414         ndr->print(ndr, "%-25s: %s", name, win_errstr(r));
415 }
416
417 /*
418   parse a set of bytes
419 */
420 _PUBLIC_ enum ndr_err_code ndr_pull_bytes(struct ndr_pull *ndr, uint8_t *data, uint32_t n)
421 {
422         NDR_PULL_NEED_BYTES(ndr, n);
423         memcpy(data, ndr->data + ndr->offset, n);
424         ndr->offset += n;
425         return NDR_ERR_SUCCESS;
426 }
427
428 /*
429   pull an array of uint8
430 */
431 _PUBLIC_ enum ndr_err_code ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *data, uint32_t n)
432 {
433         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
434         if (!(ndr_flags & NDR_SCALARS)) {
435                 return NDR_ERR_SUCCESS;
436         }
437         return ndr_pull_bytes(ndr, data, n);
438 }
439
440 /*
441   push a int8_t
442 */
443 _PUBLIC_ enum ndr_err_code ndr_push_int8(struct ndr_push *ndr, int ndr_flags, int8_t v)
444 {
445         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
446         NDR_PUSH_NEED_BYTES(ndr, 1);
447         SCVAL(ndr->data, ndr->offset, (uint8_t)v);
448         ndr->offset += 1;
449         return NDR_ERR_SUCCESS;
450 }
451
452 /*
453   push a uint8_t
454 */
455 _PUBLIC_ enum ndr_err_code ndr_push_uint8(struct ndr_push *ndr, int ndr_flags, uint8_t v)
456 {
457         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
458         NDR_PUSH_NEED_BYTES(ndr, 1);
459         SCVAL(ndr->data, ndr->offset, v);
460         ndr->offset += 1;
461         return NDR_ERR_SUCCESS;
462 }
463
464 /*
465   push a int16_t
466 */
467 _PUBLIC_ enum ndr_err_code ndr_push_int16(struct ndr_push *ndr, int ndr_flags, int16_t v)
468 {
469         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
470         NDR_PUSH_ALIGN(ndr, 2);
471         NDR_PUSH_NEED_BYTES(ndr, 2);
472         NDR_SSVAL(ndr, ndr->offset, (uint16_t)v);
473         ndr->offset += 2;
474         return NDR_ERR_SUCCESS;
475 }
476
477 /*
478   push a uint16_t
479 */
480 _PUBLIC_ enum ndr_err_code ndr_push_uint16(struct ndr_push *ndr, int ndr_flags, uint16_t v)
481 {
482         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
483         NDR_PUSH_ALIGN(ndr, 2);
484         NDR_PUSH_NEED_BYTES(ndr, 2);
485         NDR_SSVAL(ndr, ndr->offset, v);
486         ndr->offset += 2;
487         return NDR_ERR_SUCCESS;
488 }
489
490 /*
491   push a uint1632
492 */
493 _PUBLIC_ enum ndr_err_code ndr_push_uint1632(struct ndr_push *ndr, int ndr_flags, uint16_t v)
494 {
495         if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
496                 return ndr_push_uint32(ndr, ndr_flags, v);
497         }
498         return ndr_push_uint16(ndr, ndr_flags, v);
499 }
500
501 /*
502   push a int32_t
503 */
504 _PUBLIC_ enum ndr_err_code ndr_push_int32(struct ndr_push *ndr, int ndr_flags, int32_t v)
505 {
506         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
507         NDR_PUSH_ALIGN(ndr, 4);
508         NDR_PUSH_NEED_BYTES(ndr, 4);
509         NDR_SIVALS(ndr, ndr->offset, v);
510         ndr->offset += 4;
511         return NDR_ERR_SUCCESS;
512 }
513
514 /*
515   push a uint32_t
516 */
517 _PUBLIC_ enum ndr_err_code ndr_push_uint32(struct ndr_push *ndr, int ndr_flags, uint32_t v)
518 {
519         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
520         NDR_PUSH_ALIGN(ndr, 4);
521         NDR_PUSH_NEED_BYTES(ndr, 4);
522         NDR_SIVAL(ndr, ndr->offset, v);
523         ndr->offset += 4;
524         return NDR_ERR_SUCCESS;
525 }
526
527 /*
528   push a uint3264
529 */
530 _PUBLIC_ enum ndr_err_code ndr_push_uint3264(struct ndr_push *ndr, int ndr_flags, uint32_t v)
531 {
532         if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
533                 return ndr_push_hyper(ndr, ndr_flags, v);
534         }
535         return ndr_push_uint32(ndr, ndr_flags, v);
536 }
537
538 /*
539   push a udlong
540 */
541 _PUBLIC_ enum ndr_err_code ndr_push_udlong(struct ndr_push *ndr, int ndr_flags, uint64_t v)
542 {
543         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
544         NDR_PUSH_ALIGN(ndr, 4);
545         NDR_PUSH_NEED_BYTES(ndr, 8);
546         NDR_SIVAL(ndr, ndr->offset, (v & 0xFFFFFFFF));
547         NDR_SIVAL(ndr, ndr->offset+4, (v>>32));
548         ndr->offset += 8;
549         return NDR_ERR_SUCCESS;
550 }
551
552 /*
553   push a udlongr
554 */
555 _PUBLIC_ enum ndr_err_code ndr_push_udlongr(struct ndr_push *ndr, int ndr_flags, uint64_t v)
556 {
557         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
558         NDR_PUSH_ALIGN(ndr, 4);
559         NDR_PUSH_NEED_BYTES(ndr, 8);
560         NDR_SIVAL(ndr, ndr->offset, (v>>32));
561         NDR_SIVAL(ndr, ndr->offset+4, (v & 0xFFFFFFFF));
562         ndr->offset += 8;
563         return NDR_ERR_SUCCESS;
564 }
565
566 /*
567   push a dlong
568 */
569 _PUBLIC_ enum ndr_err_code ndr_push_dlong(struct ndr_push *ndr, int ndr_flags, int64_t v)
570 {
571         return ndr_push_udlong(ndr, NDR_SCALARS, (uint64_t)v);
572 }
573
574 /*
575   push a hyper
576 */
577 _PUBLIC_ enum ndr_err_code ndr_push_hyper(struct ndr_push *ndr, int ndr_flags, uint64_t v)
578 {
579         NDR_PUSH_ALIGN(ndr, 8);
580         if (NDR_BE(ndr)) {
581                 return ndr_push_udlongr(ndr, NDR_SCALARS, v);
582         }
583         return ndr_push_udlong(ndr, NDR_SCALARS, v);
584 }
585
586 /*
587   push a double
588 */
589 _PUBLIC_ enum ndr_err_code ndr_push_double(struct ndr_push *ndr, int ndr_flags, double v)
590 {
591         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
592         NDR_PUSH_ALIGN(ndr, 8);
593         NDR_PUSH_NEED_BYTES(ndr, 8);
594         memcpy(ndr->data+ndr->offset, &v, 8);
595         ndr->offset += 8;
596         return NDR_ERR_SUCCESS;
597 }
598
599 /*
600   push a pointer
601 */
602 _PUBLIC_ enum ndr_err_code ndr_push_pointer(struct ndr_push *ndr, int ndr_flags, void* v)
603 {
604         uintptr_t h = (intptr_t)v;
605         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
606         NDR_PUSH_ALIGN(ndr, sizeof(h));
607         NDR_PUSH_NEED_BYTES(ndr, sizeof(h));
608         memcpy(ndr->data+ndr->offset, &h, sizeof(h));
609         ndr->offset += sizeof(h);
610         return NDR_ERR_SUCCESS;
611 }
612
613 _PUBLIC_ enum ndr_err_code ndr_push_align(struct ndr_push *ndr, size_t size)
614 {
615         /* this is a nasty hack to make pidl work with NDR64 */
616         if (size == 5) {
617                 if (ndr->flags & LIBNDR_FLAG_NDR64) {
618                         size = 8;
619                 } else {
620                         size = 4;
621                 }
622         } else if (size == 3) {
623                 if (ndr->flags & LIBNDR_FLAG_NDR64) {
624                         size = 4;
625                 } else {
626                         size = 2;
627                 }
628         }
629         NDR_PUSH_ALIGN(ndr, size);
630         return NDR_ERR_SUCCESS;
631 }
632
633 _PUBLIC_ enum ndr_err_code ndr_pull_align(struct ndr_pull *ndr, size_t size)
634 {
635         /* this is a nasty hack to make pidl work with NDR64 */
636         if (size == 5) {
637                 if (ndr->flags & LIBNDR_FLAG_NDR64) {
638                         size = 8;
639                 } else {
640                         size = 4;
641                 }
642         } else if (size == 3) {
643                 if (ndr->flags & LIBNDR_FLAG_NDR64) {
644                         size = 4;
645                 } else {
646                         size = 2;
647                 }
648         }
649         NDR_PULL_ALIGN(ndr, size);
650         return NDR_ERR_SUCCESS;
651 }
652
653 _PUBLIC_ enum ndr_err_code ndr_push_union_align(struct ndr_push *ndr, size_t size)
654 {
655         /* MS-RPCE section 2.2.5.3.4.4 */
656         if (ndr->flags & LIBNDR_FLAG_NDR64) {
657                 return ndr_push_align(ndr, size);
658         }
659         return NDR_ERR_SUCCESS;
660 }
661
662 _PUBLIC_ enum ndr_err_code ndr_pull_union_align(struct ndr_pull *ndr, size_t size)
663 {
664         /* MS-RPCE section 2.2.5.3.4.4 */
665         if (ndr->flags & LIBNDR_FLAG_NDR64) {
666                 return ndr_pull_align(ndr, size);
667         }
668         return NDR_ERR_SUCCESS;
669 }
670
671 _PUBLIC_ enum ndr_err_code ndr_push_trailer_align(struct ndr_push *ndr, size_t size)
672 {
673         /* MS-RPCE section 2.2.5.3.4.1 */
674         if (ndr->flags & LIBNDR_FLAG_NDR64) {
675                 return ndr_push_align(ndr, size);
676         }
677         return NDR_ERR_SUCCESS;
678 }
679
680 _PUBLIC_ enum ndr_err_code ndr_pull_trailer_align(struct ndr_pull *ndr, size_t size)
681 {
682         /* MS-RPCE section 2.2.5.3.4.1 */
683         if (ndr->flags & LIBNDR_FLAG_NDR64) {
684                 return ndr_pull_align(ndr, size);
685         }
686         return NDR_ERR_SUCCESS;
687 }
688
689 /*
690   push some bytes
691 */
692 _PUBLIC_ enum ndr_err_code ndr_push_bytes(struct ndr_push *ndr, const uint8_t *data, uint32_t n)
693 {
694         NDR_PUSH_NEED_BYTES(ndr, n);
695         memcpy(ndr->data + ndr->offset, data, n);
696         ndr->offset += n;
697         return NDR_ERR_SUCCESS;
698 }
699
700 /*
701   push some zero bytes
702 */
703 _PUBLIC_ enum ndr_err_code ndr_push_zero(struct ndr_push *ndr, uint32_t n)
704 {
705         NDR_PUSH_NEED_BYTES(ndr, n);
706         memset(ndr->data + ndr->offset, 0, n);
707         ndr->offset += n;
708         return NDR_ERR_SUCCESS;
709 }
710
711 /*
712   push an array of uint8
713 */
714 _PUBLIC_ enum ndr_err_code ndr_push_array_uint8(struct ndr_push *ndr, int ndr_flags, const uint8_t *data, uint32_t n)
715 {
716         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
717         if (!(ndr_flags & NDR_SCALARS)) {
718                 return NDR_ERR_SUCCESS;
719         }
720         return ndr_push_bytes(ndr, data, n);
721 }
722
723 /*
724   push a unique non-zero value if a pointer is non-NULL, otherwise 0
725 */
726 _PUBLIC_ enum ndr_err_code ndr_push_unique_ptr(struct ndr_push *ndr, const void *p)
727 {
728         uint32_t ptr = 0;
729         if (p) {
730                 ptr = ndr->ptr_count * 4;
731                 ptr |= 0x00020000;
732                 ndr->ptr_count++;
733         }
734         return ndr_push_uint3264(ndr, NDR_SCALARS, ptr);
735 }
736
737 /*
738   push a 'simple' full non-zero value if a pointer is non-NULL, otherwise 0
739 */
740 _PUBLIC_ enum ndr_err_code ndr_push_full_ptr(struct ndr_push *ndr, const void *p)
741 {
742         uint32_t ptr = 0;
743         if (p) {
744                 /* Check if the pointer already exists and has an id */
745                 ptr = ndr_token_peek(&ndr->full_ptr_list, p);
746                 if (ptr == 0) {
747                         ndr->ptr_count++;
748                         ptr = ndr->ptr_count;
749                         ndr_token_store(ndr, &ndr->full_ptr_list, p, ptr);
750                 }
751         }
752         return ndr_push_uint3264(ndr, NDR_SCALARS, ptr);
753 }
754
755 /*
756   push always a 0, if a pointer is NULL it's a fatal error
757 */
758 _PUBLIC_ enum ndr_err_code ndr_push_ref_ptr(struct ndr_push *ndr)
759 {
760         return ndr_push_uint3264(ndr, NDR_SCALARS, 0xAEF1AEF1);
761 }
762
763
764 /*
765   push a NTTIME
766 */
767 _PUBLIC_ enum ndr_err_code ndr_push_NTTIME(struct ndr_push *ndr, int ndr_flags, NTTIME t)
768 {
769         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
770         NDR_CHECK(ndr_push_udlong(ndr, ndr_flags, t));
771         return NDR_ERR_SUCCESS;
772 }
773
774 /*
775   pull a NTTIME
776 */
777 _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
778 {
779         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
780         NDR_CHECK(ndr_pull_udlong(ndr, ndr_flags, t));
781         return NDR_ERR_SUCCESS;
782 }
783
784 /*
785   push a NTTIME_1sec
786 */
787 _PUBLIC_ enum ndr_err_code ndr_push_NTTIME_1sec(struct ndr_push *ndr, int ndr_flags, NTTIME t)
788 {
789         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
790         t /= 10000000;
791         NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t));
792         return NDR_ERR_SUCCESS;
793 }
794
795 /*
796   pull a NTTIME_1sec
797 */
798 _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_1sec(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
799 {
800         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
801         NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t));
802         (*t) *= 10000000;
803         return NDR_ERR_SUCCESS;
804 }
805
806 /*
807   pull a NTTIME_hyper
808 */
809 _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_hyper(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
810 {
811         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
812         NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t));
813         return NDR_ERR_SUCCESS;
814 }
815
816 /*
817   push a NTTIME_hyper
818 */
819 _PUBLIC_ enum ndr_err_code ndr_push_NTTIME_hyper(struct ndr_push *ndr, int ndr_flags, NTTIME t)
820 {
821         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
822         NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t));
823         return NDR_ERR_SUCCESS;
824 }
825
826 /*
827   push a time_t
828 */
829 _PUBLIC_ enum ndr_err_code ndr_push_time_t(struct ndr_push *ndr, int ndr_flags, time_t t)
830 {
831         return ndr_push_uint32(ndr, ndr_flags, t);
832 }
833
834 /*
835   pull a time_t
836 */
837 _PUBLIC_ enum ndr_err_code ndr_pull_time_t(struct ndr_pull *ndr, int ndr_flags, time_t *t)
838 {
839         uint32_t tt;
840         NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &tt));
841         *t = tt;
842         return NDR_ERR_SUCCESS;
843 }
844
845
846 /*
847   push a uid_t
848 */
849 _PUBLIC_ enum ndr_err_code ndr_push_uid_t(struct ndr_push *ndr, int ndr_flags, uid_t u)
850 {
851         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
852         return ndr_push_hyper(ndr, NDR_SCALARS, (uint64_t)u);
853 }
854
855 /*
856   pull a uid_t
857 */
858 _PUBLIC_ enum ndr_err_code ndr_pull_uid_t(struct ndr_pull *ndr, int ndr_flags, uid_t *u)
859 {
860         uint64_t uu;
861         NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, &uu));
862         *u = (uid_t)uu;
863         if (unlikely(uu != *u)) {
864                 DEBUG(0,(__location__ ": uid_t pull doesn't fit 0x%016llx\n",
865                          (unsigned long long)uu));
866                 return NDR_ERR_NDR64;
867         }
868         return NDR_ERR_SUCCESS;
869 }
870
871
872 /*
873   push a gid_t
874 */
875 _PUBLIC_ enum ndr_err_code ndr_push_gid_t(struct ndr_push *ndr, int ndr_flags, gid_t g)
876 {
877         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
878         return ndr_push_hyper(ndr, NDR_SCALARS, (uint64_t)g);
879 }
880
881 /*
882   pull a gid_t
883 */
884 _PUBLIC_ enum ndr_err_code ndr_pull_gid_t(struct ndr_pull *ndr, int ndr_flags, gid_t *g)
885 {
886         uint64_t gg;
887         NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, &gg));
888         *g = (gid_t)gg;
889         if (unlikely(gg != *g)) {
890                 DEBUG(0,(__location__ ": gid_t pull doesn't fit 0x%016llx\n",
891                          (unsigned long long)gg));
892                 return NDR_ERR_NDR64;
893         }
894         return NDR_ERR_SUCCESS;
895 }
896
897
898 /*
899   pull a ipv4address
900 */
901 _PUBLIC_ enum ndr_err_code ndr_pull_ipv4address(struct ndr_pull *ndr, int ndr_flags, const char **address)
902 {
903         uint32_t addr;
904         struct in_addr in;
905         NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &addr));
906         in.s_addr = htonl(addr);
907         *address = talloc_strdup(ndr->current_mem_ctx, inet_ntoa(in));
908         NDR_ERR_HAVE_NO_MEMORY(*address);
909         return NDR_ERR_SUCCESS;
910 }
911
912 /*
913   push a ipv4address
914 */
915 _PUBLIC_ enum ndr_err_code ndr_push_ipv4address(struct ndr_push *ndr, int ndr_flags, const char *address)
916 {
917         uint32_t addr;
918         if (!is_ipaddress(address)) {
919                 return ndr_push_error(ndr, NDR_ERR_IPV4ADDRESS,
920                                       "Invalid IPv4 address: '%s'",
921                                       address);
922         }
923         addr = inet_addr(address);
924         NDR_CHECK(ndr_push_uint32(ndr, ndr_flags, htonl(addr)));
925         return NDR_ERR_SUCCESS;
926 }
927
928 /*
929   print a ipv4address
930 */
931 _PUBLIC_ void ndr_print_ipv4address(struct ndr_print *ndr, const char *name,
932                            const char *address)
933 {
934         ndr->print(ndr, "%-25s: %s", name, address);
935 }
936
937 /*
938   pull a ipv6address
939 */
940 #define IPV6_BYTES 16
941 #define IPV6_ADDR_STR_LEN 39
942 _PUBLIC_ enum ndr_err_code ndr_pull_ipv6address(struct ndr_pull *ndr, int ndr_flags, const char **address)
943 {
944         uint8_t addr[IPV6_BYTES];
945         char *addr_str = talloc_strdup(ndr->current_mem_ctx, "");
946         int i;
947         NDR_CHECK(ndr_pull_array_uint8(ndr, ndr_flags, addr, IPV6_BYTES));
948         for (i = 0; i < IPV6_BYTES; ++i) {
949                 addr_str = talloc_asprintf_append(addr_str, "%02x", addr[i]);
950                 /* We need a ':' every second byte but the last one */
951                 if (i%2 == 1 && i != (IPV6_BYTES - 1)) {
952                         addr_str = talloc_strdup_append(addr_str, ":");
953                 }
954         }
955         *address = addr_str;
956         NDR_ERR_HAVE_NO_MEMORY(*address);
957         return NDR_ERR_SUCCESS;
958 }
959
960 /*
961   push a ipv6address
962 */
963 _PUBLIC_ enum ndr_err_code ndr_push_ipv6address(struct ndr_push *ndr, int ndr_flags, const char *address)
964 {
965 #ifdef AF_INET6
966         uint8_t addr[IPV6_BYTES];
967         int ret;
968
969         if (!is_ipaddress(address)) {
970                 return ndr_push_error(ndr, NDR_ERR_IPV6ADDRESS,
971                                       "Invalid IPv6 address: '%s'",
972                                       address);
973         }
974         ret = inet_pton(AF_INET6, address, addr);
975         if (ret <= 0) {
976                 return NDR_ERR_IPV6ADDRESS;
977         }
978
979         NDR_CHECK(ndr_push_array_uint8(ndr, ndr_flags, addr, IPV6_BYTES));
980
981         return NDR_ERR_SUCCESS;
982 #else
983         return NDR_ERR_IPV6ADDRESS;
984 #endif
985 }
986
987 /*
988   print a ipv6address
989 */
990 _PUBLIC_ void ndr_print_ipv6address(struct ndr_print *ndr, const char *name,
991                            const char *address)
992 {
993         ndr->print(ndr, "%-25s: %s", name, address);
994 }
995 #undef IPV6_BYTES
996
997 _PUBLIC_ void ndr_print_struct(struct ndr_print *ndr, const char *name, const char *type)
998 {
999         ndr->print(ndr, "%s: struct %s", name, type);
1000 }
1001
1002 _PUBLIC_ void ndr_print_null(struct ndr_print *ndr)
1003 {
1004         ndr->print(ndr, "UNEXPECTED NULL POINTER");
1005 }
1006
1007 _PUBLIC_ void ndr_print_enum(struct ndr_print *ndr, const char *name, const char *type, 
1008                     const char *val, uint32_t value)
1009 {
1010         if (ndr->flags & LIBNDR_PRINT_ARRAY_HEX) {
1011                 ndr->print(ndr, "%-25s: %s (0x%X)", name, val?val:"UNKNOWN_ENUM_VALUE", value);
1012         } else {
1013                 ndr->print(ndr, "%-25s: %s (%d)", name, val?val:"UNKNOWN_ENUM_VALUE", value);
1014         }
1015 }
1016
1017 _PUBLIC_ void ndr_print_bitmap_flag(struct ndr_print *ndr, size_t size, const char *flag_name, uint32_t flag, uint32_t value)
1018 {
1019         /* this is an attempt to support multi-bit bitmap masks */
1020         value &= flag;
1021
1022         while (!(flag & 1)) {
1023                 flag >>= 1;
1024                 value >>= 1;
1025         }       
1026         if (flag == 1) {
1027                 ndr->print(ndr, "   %d: %-25s", value, flag_name);
1028         } else {
1029                 ndr->print(ndr, "0x%02x: %-25s (%d)", value, flag_name, value);
1030         }
1031 }
1032
1033 _PUBLIC_ void ndr_print_int8(struct ndr_print *ndr, const char *name, int8_t v)
1034 {
1035         ndr->print(ndr, "%-25s: %d", name, v);
1036 }
1037
1038 _PUBLIC_ void ndr_print_uint8(struct ndr_print *ndr, const char *name, uint8_t v)
1039 {
1040         ndr->print(ndr, "%-25s: 0x%02x (%u)", name, v, v);
1041 }
1042
1043 _PUBLIC_ void ndr_print_int16(struct ndr_print *ndr, const char *name, int16_t v)
1044 {
1045         ndr->print(ndr, "%-25s: %d", name, v);
1046 }
1047
1048 _PUBLIC_ void ndr_print_uint16(struct ndr_print *ndr, const char *name, uint16_t v)
1049 {
1050         ndr->print(ndr, "%-25s: 0x%04x (%u)", name, v, v);
1051 }
1052
1053 _PUBLIC_ void ndr_print_int32(struct ndr_print *ndr, const char *name, int32_t v)
1054 {
1055         ndr->print(ndr, "%-25s: %d", name, v);
1056 }
1057
1058 _PUBLIC_ void ndr_print_uint32(struct ndr_print *ndr, const char *name, uint32_t v)
1059 {
1060         ndr->print(ndr, "%-25s: 0x%08x (%u)", name, v, v);
1061 }
1062
1063 _PUBLIC_ void ndr_print_int3264(struct ndr_print *ndr, const char *name, int32_t v)
1064 {
1065         ndr->print(ndr, "%-25s: %d", name, v);
1066 }
1067
1068 _PUBLIC_ void ndr_print_uint3264(struct ndr_print *ndr, const char *name, uint32_t v)
1069 {
1070         ndr->print(ndr, "%-25s: 0x%08x (%u)", name, v, v);
1071 }
1072
1073 _PUBLIC_ void ndr_print_udlong(struct ndr_print *ndr, const char *name, uint64_t v)
1074 {
1075         ndr->print(ndr, "%-25s: 0x%016llx (%llu)", name, (unsigned long long)v, (unsigned long long)v);
1076 }
1077
1078 _PUBLIC_ void ndr_print_udlongr(struct ndr_print *ndr, const char *name, uint64_t v)
1079 {
1080         ndr_print_udlong(ndr, name, v);
1081 }
1082
1083 _PUBLIC_ void ndr_print_dlong(struct ndr_print *ndr, const char *name, int64_t v)
1084 {
1085         ndr->print(ndr, "%-25s: 0x%016llx (%lld)", name, (unsigned long long)v, (long long)v);
1086 }
1087
1088 _PUBLIC_ void ndr_print_double(struct ndr_print *ndr, const char *name, double v)
1089 {
1090         ndr->print(ndr, "%-25s: %f", name, v);
1091 }
1092
1093 _PUBLIC_ void ndr_print_hyper(struct ndr_print *ndr, const char *name, uint64_t v)
1094 {
1095         ndr_print_dlong(ndr, name, v);
1096 }
1097
1098 _PUBLIC_ void ndr_print_pointer(struct ndr_print *ndr, const char *name, void *v)
1099 {
1100         ndr->print(ndr, "%-25s: %p", name, v);
1101 }
1102
1103 _PUBLIC_ void ndr_print_ptr(struct ndr_print *ndr, const char *name, const void *p)
1104 {
1105         if (p) {
1106                 ndr->print(ndr, "%-25s: *", name);
1107         } else {
1108                 ndr->print(ndr, "%-25s: NULL", name);
1109         }
1110 }
1111
1112 _PUBLIC_ void ndr_print_NTTIME(struct ndr_print *ndr, const char *name, NTTIME t)
1113 {
1114         ndr->print(ndr, "%-25s: %s", name, nt_time_string(ndr, t));
1115 }
1116
1117 _PUBLIC_ void ndr_print_NTTIME_1sec(struct ndr_print *ndr, const char *name, NTTIME t)
1118 {
1119         /* this is a standard NTTIME here
1120          * as it's already converted in the pull/push code
1121          */
1122         ndr_print_NTTIME(ndr, name, t);
1123 }
1124
1125 _PUBLIC_ void ndr_print_NTTIME_hyper(struct ndr_print *ndr, const char *name, NTTIME t)
1126 {
1127         ndr_print_NTTIME(ndr, name, t);
1128 }
1129
1130 _PUBLIC_ void ndr_print_time_t(struct ndr_print *ndr, const char *name, time_t t)
1131 {
1132         if (t == (time_t)-1 || t == 0) {
1133                 ndr->print(ndr, "%-25s: (time_t)%d", name, (int)t);
1134         } else {
1135                 ndr->print(ndr, "%-25s: %s", name, timestring(ndr, t));
1136         }
1137 }
1138
1139 _PUBLIC_ void ndr_print_uid_t(struct ndr_print *ndr, const char *name, uid_t u)
1140 {
1141         ndr_print_dlong(ndr, name, u);
1142 }
1143
1144 _PUBLIC_ void ndr_print_gid_t(struct ndr_print *ndr, const char *name, gid_t g)
1145 {
1146         ndr_print_dlong(ndr, name, g);
1147 }
1148
1149 _PUBLIC_ void ndr_print_union(struct ndr_print *ndr, const char *name, int level, const char *type)
1150 {
1151         if (ndr->flags & LIBNDR_PRINT_ARRAY_HEX) {
1152                 ndr->print(ndr, "%-25s: union %s(case 0x%X)", name, type, level);
1153         } else {
1154                 ndr->print(ndr, "%-25s: union %s(case %d)", name, type, level);
1155         }
1156 }
1157
1158 _PUBLIC_ void ndr_print_bad_level(struct ndr_print *ndr, const char *name, uint16_t level)
1159 {
1160         ndr->print(ndr, "UNKNOWN LEVEL %u", level);
1161 }
1162
1163 _PUBLIC_ void ndr_print_array_uint8(struct ndr_print *ndr, const char *name, 
1164                            const uint8_t *data, uint32_t count)
1165 {
1166         int i;
1167 #define _ONELINE_LIMIT 32
1168
1169         if (data == NULL) {
1170                 ndr->print(ndr, "%s: ARRAY(%d) : NULL", name, count);
1171                 return;
1172         }
1173
1174         if (count <= _ONELINE_LIMIT && (ndr->flags & LIBNDR_PRINT_ARRAY_HEX)) {
1175                 char s[(_ONELINE_LIMIT + 1) * 2];
1176                 for (i=0;i<count;i++) {
1177                         snprintf(&s[i*2], 3, "%02x", data[i]);
1178                 }
1179                 s[i*2] = 0;
1180                 ndr->print(ndr, "%-25s: %s", name, s);
1181                 return;
1182         }
1183
1184         ndr->print(ndr, "%s: ARRAY(%d)", name, count);
1185         if (count > _ONELINE_LIMIT && (ndr->flags & LIBNDR_PRINT_ARRAY_HEX)) {
1186                 ndr_dump_data(ndr, data, count);
1187                 return;
1188         }
1189
1190         ndr->depth++;
1191         for (i=0;i<count;i++) {
1192                 char *idx=NULL;
1193                 if (asprintf(&idx, "[%d]", i) != -1) {
1194                         ndr_print_uint8(ndr, idx, data[i]);
1195                         free(idx);
1196                 }
1197         }
1198         ndr->depth--;   
1199 #undef _ONELINE_LIMIT
1200 }
1201
1202 static void ndr_print_asc(struct ndr_print *ndr, const uint8_t *buf, int len)
1203 {
1204         int i;
1205         for (i=0;i<len;i++)
1206                 ndr->print(ndr, "%c", isprint(buf[i])?buf[i]:'.');
1207 }
1208
1209 /*
1210   ndr_print version of dump_data()
1211  */
1212 static void ndr_dump_data(struct ndr_print *ndr, const uint8_t *buf, int len)
1213 {
1214         int i=0;
1215
1216         ndr->no_newline = true;
1217
1218         for (i=0;i<len;) {
1219                 if (i%16 == 0 && i<len) {
1220                         ndr->print(ndr, "[%04X] ",i);
1221                 }
1222
1223                 ndr->print(ndr, "%02X ",(int)buf[i]);
1224                 i++;
1225                 if (i%8 == 0) ndr->print(ndr,"  ");
1226                 if (i%16 == 0) {
1227                         ndr_print_asc(ndr,&buf[i-16],8); ndr->print(ndr," ");
1228                         ndr_print_asc(ndr,&buf[i-8],8); ndr->print(ndr, "\n");
1229                 }
1230         }
1231
1232         if (i%16) {
1233                 int n;
1234                 n = 16 - (i%16);
1235                 ndr->print(ndr, " ");
1236                 if (n>8) ndr->print(ndr," ");
1237                 while (n--) ndr->print(ndr,"   ");
1238                 n = MIN(8,i%16);
1239                 ndr_print_asc(ndr,&buf[i-(i%16)],n); ndr->print(ndr, " ");
1240                 n = (i%16) - n;
1241                 if (n>0) ndr_print_asc(ndr,&buf[i-n],n);
1242                 ndr->print(ndr,"\n");
1243         }
1244
1245         ndr->no_newline = false;
1246 }
1247
1248
1249 _PUBLIC_ void ndr_print_DATA_BLOB(struct ndr_print *ndr, const char *name, DATA_BLOB r)
1250 {
1251         ndr->print(ndr, "%-25s: DATA_BLOB length=%u", name, (unsigned)r.length);
1252         if (r.length) {
1253                 ndr_dump_data(ndr, r.data, r.length);
1254         }
1255 }
1256
1257
1258 /*
1259  * Push a DATA_BLOB onto the wire.
1260  * 1) When called with LIBNDR_FLAG_ALIGN* alignment flags set, push padding
1261  *    bytes _only_. The length is determined by the alignment required and the
1262  *    current ndr offset.
1263  * 2) When called with the LIBNDR_FLAG_REMAINING flag, push the byte array to
1264  *    the ndr buffer.
1265  * 3) Otherwise, push a uint3264 length _and_ a corresponding byte array to the
1266  *    ndr buffer.
1267  */
1268 _PUBLIC_ enum ndr_err_code ndr_push_DATA_BLOB(struct ndr_push *ndr, int ndr_flags, DATA_BLOB blob)
1269 {
1270         if (ndr->flags & LIBNDR_FLAG_REMAINING) {
1271                 /* nothing to do */
1272         } else if (ndr->flags & (LIBNDR_ALIGN_FLAGS & ~LIBNDR_FLAG_NOALIGN)) {
1273                 if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
1274                         blob.length = NDR_ALIGN(ndr, 2);
1275                 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
1276                         blob.length = NDR_ALIGN(ndr, 4);
1277                 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
1278                         blob.length = NDR_ALIGN(ndr, 8);
1279                 }
1280                 NDR_PUSH_ALLOC_SIZE(ndr, blob.data, blob.length);
1281                 data_blob_clear(&blob);
1282         } else {
1283                 NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, blob.length));
1284         }
1285         NDR_CHECK(ndr_push_bytes(ndr, blob.data, blob.length));
1286         return NDR_ERR_SUCCESS;
1287 }
1288
1289 /*
1290  * Pull a DATA_BLOB from the wire.
1291  * 1) when called with LIBNDR_FLAG_ALIGN* alignment flags set, pull padding
1292  *    bytes _only_. The length is determined by the alignment required and the
1293  *    current ndr offset.
1294  * 2) When called with the LIBNDR_FLAG_REMAINING flag, pull all remaining bytes
1295  *    from the ndr buffer.
1296  * 3) Otherwise, pull a uint3264 length _and_ a corresponding byte array from the
1297  *    ndr buffer.
1298  */
1299 _PUBLIC_ enum ndr_err_code ndr_pull_DATA_BLOB(struct ndr_pull *ndr, int ndr_flags, DATA_BLOB *blob)
1300 {
1301         uint32_t length = 0;
1302
1303         if (ndr->flags & LIBNDR_FLAG_REMAINING) {
1304                 length = ndr->data_size - ndr->offset;
1305         } else if (ndr->flags & (LIBNDR_ALIGN_FLAGS & ~LIBNDR_FLAG_NOALIGN)) {
1306                 if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
1307                         length = NDR_ALIGN(ndr, 2);
1308                 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
1309                         length = NDR_ALIGN(ndr, 4);
1310                 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
1311                         length = NDR_ALIGN(ndr, 8);
1312                 }
1313                 if (ndr->data_size - ndr->offset < length) {
1314                         length = ndr->data_size - ndr->offset;
1315                 }
1316         } else {
1317                 NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &length));
1318         }
1319         NDR_PULL_NEED_BYTES(ndr, length);
1320         *blob = data_blob_talloc(ndr->current_mem_ctx, ndr->data+ndr->offset, length);
1321         ndr->offset += length;
1322         return NDR_ERR_SUCCESS;
1323 }
1324
1325 _PUBLIC_ uint32_t ndr_size_DATA_BLOB(int ret, const DATA_BLOB *data, int flags)
1326 {
1327         if (!data) return ret;
1328         return ret + data->length;
1329 }
1330
1331 _PUBLIC_ void ndr_print_bool(struct ndr_print *ndr, const char *name, const bool b)
1332 {
1333         ndr->print(ndr, "%-25s: %s", name, b?"true":"false");
1334 }
1335
1336 _PUBLIC_ NTSTATUS ndr_map_error2ntstatus(enum ndr_err_code ndr_err)
1337 {
1338         switch (ndr_err) {
1339         case NDR_ERR_SUCCESS:
1340                 return NT_STATUS_OK;
1341         case NDR_ERR_BUFSIZE:
1342                 return NT_STATUS_BUFFER_TOO_SMALL;
1343         case NDR_ERR_TOKEN:
1344                 return NT_STATUS_INTERNAL_ERROR;
1345         case NDR_ERR_ALLOC:
1346                 return NT_STATUS_NO_MEMORY;
1347         case NDR_ERR_ARRAY_SIZE:
1348                 return NT_STATUS_ARRAY_BOUNDS_EXCEEDED;
1349         case NDR_ERR_INVALID_POINTER:
1350                 return NT_STATUS_INVALID_PARAMETER_MIX;
1351         case NDR_ERR_UNREAD_BYTES:
1352                 return NT_STATUS_PORT_MESSAGE_TOO_LONG;
1353         default:
1354                 break;
1355         }
1356
1357         /* we should map all error codes to different status codes */
1358         return NT_STATUS_INVALID_PARAMETER;
1359 }
1360
1361 _PUBLIC_ int ndr_map_error2errno(enum ndr_err_code ndr_err)
1362 {
1363         switch (ndr_err) {
1364         case NDR_ERR_SUCCESS:
1365                 return 0;
1366         case NDR_ERR_BUFSIZE:
1367                 return ENOSPC;
1368         case NDR_ERR_TOKEN:
1369                 return EINVAL;
1370         case NDR_ERR_ALLOC:
1371                 return ENOMEM;
1372         case NDR_ERR_ARRAY_SIZE:
1373                 return EMSGSIZE;
1374         case NDR_ERR_INVALID_POINTER:
1375                 return EINVAL;
1376         case NDR_ERR_UNREAD_BYTES:
1377                 return EOVERFLOW;
1378         default:
1379                 break;
1380         }
1381
1382         /* we should map all error codes to different status codes */
1383         return EINVAL;
1384 }
1385
1386 _PUBLIC_ enum ndr_err_code ndr_push_timespec(struct ndr_push *ndr,
1387                                              int ndr_flags,
1388                                              const struct timespec *t)
1389 {
1390         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
1391         NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t->tv_sec));
1392         NDR_CHECK(ndr_push_uint32(ndr, ndr_flags, t->tv_nsec));
1393         return NDR_ERR_SUCCESS;
1394 }
1395
1396 _PUBLIC_ enum ndr_err_code ndr_pull_timespec(struct ndr_pull *ndr,
1397                                              int ndr_flags,
1398                                              struct timespec *t)
1399 {
1400         uint64_t secs;
1401         uint32_t nsecs;
1402         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
1403         NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, &secs));
1404         NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &nsecs));
1405         t->tv_sec = secs;
1406         t->tv_nsec = nsecs;
1407         return NDR_ERR_SUCCESS;
1408 }
1409
1410 _PUBLIC_ void ndr_print_timespec(struct ndr_print *ndr, const char *name,
1411                                  const struct timespec *t)
1412 {
1413         ndr->print(ndr, "%-25s: %s.%ld", name, timestring(ndr, t->tv_sec),
1414                    (long)t->tv_nsec);
1415 }
1416
1417 _PUBLIC_ enum ndr_err_code ndr_push_timeval(struct ndr_push *ndr,
1418                                             int ndr_flags,
1419                                             const struct timeval *t)
1420 {
1421         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
1422         NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t->tv_sec));
1423         NDR_CHECK(ndr_push_uint32(ndr, ndr_flags, t->tv_usec));
1424         return NDR_ERR_SUCCESS;
1425 }
1426
1427 _PUBLIC_ enum ndr_err_code ndr_pull_timeval(struct ndr_pull *ndr,
1428                                             int ndr_flags,
1429                                             struct timeval *t)
1430 {
1431         uint64_t secs;
1432         uint32_t usecs;
1433         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
1434         NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, &secs));
1435         NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &usecs));
1436         t->tv_sec = secs;
1437         t->tv_usec = usecs;
1438         return NDR_ERR_SUCCESS;
1439 }
1440
1441 _PUBLIC_ void ndr_print_timeval(struct ndr_print *ndr, const char *name,
1442                                 const struct timeval *t)
1443 {
1444         ndr->print(ndr, "%-25s: %s.%ld", name, timestring(ndr, t->tv_sec),
1445                    (long)t->tv_usec);
1446 }