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