librpc:ndr: Give the optimizer hints for ndr_push_bytes()
[nivanova/samba-autobuild/.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         if (unlikely(n == 0)) {
723                 return NDR_ERR_SUCCESS;
724         }
725         if (unlikely(data == NULL)) {
726                 return NDR_ERR_INVALID_POINTER;
727         }
728         NDR_PUSH_NEED_BYTES(ndr, n);
729         memcpy(ndr->data + ndr->offset, data, n);
730         ndr->offset += n;
731         return NDR_ERR_SUCCESS;
732 }
733
734 /*
735   push some zero bytes
736 */
737 _PUBLIC_ enum ndr_err_code ndr_push_zero(struct ndr_push *ndr, uint32_t n)
738 {
739         NDR_PUSH_NEED_BYTES(ndr, n);
740         memset(ndr->data + ndr->offset, 0, n);
741         ndr->offset += n;
742         return NDR_ERR_SUCCESS;
743 }
744
745 /*
746   push an array of uint8
747 */
748 _PUBLIC_ enum ndr_err_code ndr_push_array_uint8(struct ndr_push *ndr, int ndr_flags, const uint8_t *data, uint32_t n)
749 {
750         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
751         if (!(ndr_flags & NDR_SCALARS)) {
752                 return NDR_ERR_SUCCESS;
753         }
754         return ndr_push_bytes(ndr, data, n);
755 }
756
757 /*
758   push a unique non-zero value if a pointer is non-NULL, otherwise 0
759 */
760 _PUBLIC_ enum ndr_err_code ndr_push_unique_ptr(struct ndr_push *ndr, const void *p)
761 {
762         uint32_t ptr = 0;
763         if (p) {
764                 ptr = ndr->ptr_count * 4;
765                 ptr |= 0x00020000;
766                 ndr->ptr_count++;
767         }
768         return ndr_push_uint3264(ndr, NDR_SCALARS, ptr);
769 }
770
771 /*
772   push a 'simple' full non-zero value if a pointer is non-NULL, otherwise 0
773 */
774 _PUBLIC_ enum ndr_err_code ndr_push_full_ptr(struct ndr_push *ndr, const void *p)
775 {
776         uint32_t ptr = 0;
777         if (p) {
778                 /* Check if the pointer already exists and has an id */
779                 ptr = ndr_token_peek(&ndr->full_ptr_list, p);
780                 if (ptr == 0) {
781                         ndr->ptr_count++;
782                         ptr = ndr->ptr_count;
783                         ndr_token_store(ndr, &ndr->full_ptr_list, p, ptr);
784                 }
785         }
786         return ndr_push_uint3264(ndr, NDR_SCALARS, ptr);
787 }
788
789 /*
790   push always a 0, if a pointer is NULL it's a fatal error
791 */
792 _PUBLIC_ enum ndr_err_code ndr_push_ref_ptr(struct ndr_push *ndr)
793 {
794         return ndr_push_uint3264(ndr, NDR_SCALARS, 0xAEF1AEF1);
795 }
796
797
798 /*
799   push a NTTIME
800 */
801 _PUBLIC_ enum ndr_err_code ndr_push_NTTIME(struct ndr_push *ndr, int ndr_flags, NTTIME t)
802 {
803         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
804         NDR_CHECK(ndr_push_udlong(ndr, ndr_flags, t));
805         return NDR_ERR_SUCCESS;
806 }
807
808 /*
809   pull a NTTIME
810 */
811 _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
812 {
813         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
814         NDR_CHECK(ndr_pull_udlong(ndr, ndr_flags, t));
815         return NDR_ERR_SUCCESS;
816 }
817
818 /*
819   push a NTTIME_1sec
820 */
821 _PUBLIC_ enum ndr_err_code ndr_push_NTTIME_1sec(struct ndr_push *ndr, int ndr_flags, NTTIME t)
822 {
823         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
824         t /= 10000000;
825         NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t));
826         return NDR_ERR_SUCCESS;
827 }
828
829 /*
830   pull a NTTIME_1sec
831 */
832 _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_1sec(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
833 {
834         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
835         NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t));
836         (*t) *= 10000000;
837         return NDR_ERR_SUCCESS;
838 }
839
840 /*
841   pull a NTTIME_hyper
842 */
843 _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_hyper(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
844 {
845         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
846         NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t));
847         return NDR_ERR_SUCCESS;
848 }
849
850 /*
851   push a NTTIME_hyper
852 */
853 _PUBLIC_ enum ndr_err_code ndr_push_NTTIME_hyper(struct ndr_push *ndr, int ndr_flags, NTTIME t)
854 {
855         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
856         NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t));
857         return NDR_ERR_SUCCESS;
858 }
859
860 /*
861   push a time_t
862 */
863 _PUBLIC_ enum ndr_err_code ndr_push_time_t(struct ndr_push *ndr, int ndr_flags, time_t t)
864 {
865         return ndr_push_uint32(ndr, ndr_flags, t);
866 }
867
868 /*
869   pull a time_t
870 */
871 _PUBLIC_ enum ndr_err_code ndr_pull_time_t(struct ndr_pull *ndr, int ndr_flags, time_t *t)
872 {
873         uint32_t tt;
874         NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &tt));
875         *t = tt;
876         return NDR_ERR_SUCCESS;
877 }
878
879
880 /*
881   push a uid_t
882 */
883 _PUBLIC_ enum ndr_err_code ndr_push_uid_t(struct ndr_push *ndr, int ndr_flags, uid_t u)
884 {
885         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
886         return ndr_push_hyper(ndr, NDR_SCALARS, (uint64_t)u);
887 }
888
889 /*
890   pull a uid_t
891 */
892 _PUBLIC_ enum ndr_err_code ndr_pull_uid_t(struct ndr_pull *ndr, int ndr_flags, uid_t *u)
893 {
894         uint64_t uu;
895         NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, &uu));
896         *u = (uid_t)uu;
897         if (unlikely(uu != *u)) {
898                 DEBUG(0,(__location__ ": uid_t pull doesn't fit 0x%016llx\n",
899                          (unsigned long long)uu));
900                 return NDR_ERR_NDR64;
901         }
902         return NDR_ERR_SUCCESS;
903 }
904
905
906 /*
907   push a gid_t
908 */
909 _PUBLIC_ enum ndr_err_code ndr_push_gid_t(struct ndr_push *ndr, int ndr_flags, gid_t g)
910 {
911         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
912         return ndr_push_hyper(ndr, NDR_SCALARS, (uint64_t)g);
913 }
914
915 /*
916   pull a gid_t
917 */
918 _PUBLIC_ enum ndr_err_code ndr_pull_gid_t(struct ndr_pull *ndr, int ndr_flags, gid_t *g)
919 {
920         uint64_t gg;
921         NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, &gg));
922         *g = (gid_t)gg;
923         if (unlikely(gg != *g)) {
924                 DEBUG(0,(__location__ ": gid_t pull doesn't fit 0x%016llx\n",
925                          (unsigned long long)gg));
926                 return NDR_ERR_NDR64;
927         }
928         return NDR_ERR_SUCCESS;
929 }
930
931
932 /*
933   pull a ipv4address
934 */
935 _PUBLIC_ enum ndr_err_code ndr_pull_ipv4address(struct ndr_pull *ndr, int ndr_flags, const char **address)
936 {
937         uint32_t addr;
938         struct in_addr in;
939         NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &addr));
940         in.s_addr = htonl(addr);
941         *address = talloc_strdup(ndr->current_mem_ctx, inet_ntoa(in));
942         NDR_ERR_HAVE_NO_MEMORY(*address);
943         return NDR_ERR_SUCCESS;
944 }
945
946 /*
947   push a ipv4address
948 */
949 _PUBLIC_ enum ndr_err_code ndr_push_ipv4address(struct ndr_push *ndr, int ndr_flags, const char *address)
950 {
951         uint32_t addr;
952         if (!is_ipaddress(address)) {
953                 return ndr_push_error(ndr, NDR_ERR_IPV4ADDRESS,
954                                       "Invalid IPv4 address: '%s'",
955                                       address);
956         }
957         addr = inet_addr(address);
958         NDR_CHECK(ndr_push_uint32(ndr, ndr_flags, htonl(addr)));
959         return NDR_ERR_SUCCESS;
960 }
961
962 /*
963   print a ipv4address
964 */
965 _PUBLIC_ void ndr_print_ipv4address(struct ndr_print *ndr, const char *name,
966                            const char *address)
967 {
968         ndr->print(ndr, "%-25s: %s", name, address);
969 }
970
971 /*
972   pull a ipv6address
973 */
974 #define IPV6_BYTES 16
975 #define IPV6_ADDR_STR_LEN 39
976 _PUBLIC_ enum ndr_err_code ndr_pull_ipv6address(struct ndr_pull *ndr, int ndr_flags, const char **address)
977 {
978         uint8_t addr[IPV6_BYTES];
979         char *addr_str = talloc_strdup(ndr->current_mem_ctx, "");
980         int i;
981         NDR_CHECK(ndr_pull_array_uint8(ndr, ndr_flags, addr, IPV6_BYTES));
982         for (i = 0; i < IPV6_BYTES; ++i) {
983                 addr_str = talloc_asprintf_append(addr_str, "%02x", addr[i]);
984                 /* We need a ':' every second byte but the last one */
985                 if (i%2 == 1 && i != (IPV6_BYTES - 1)) {
986                         addr_str = talloc_strdup_append(addr_str, ":");
987                 }
988         }
989         *address = addr_str;
990         NDR_ERR_HAVE_NO_MEMORY(*address);
991         return NDR_ERR_SUCCESS;
992 }
993
994 /*
995   push a ipv6address
996 */
997 _PUBLIC_ enum ndr_err_code ndr_push_ipv6address(struct ndr_push *ndr, int ndr_flags, const char *address)
998 {
999 #ifdef AF_INET6
1000         uint8_t addr[IPV6_BYTES];
1001         int ret;
1002
1003         if (!is_ipaddress(address)) {
1004                 return ndr_push_error(ndr, NDR_ERR_IPV6ADDRESS,
1005                                       "Invalid IPv6 address: '%s'",
1006                                       address);
1007         }
1008         ret = inet_pton(AF_INET6, address, addr);
1009         if (ret <= 0) {
1010                 return NDR_ERR_IPV6ADDRESS;
1011         }
1012
1013         NDR_CHECK(ndr_push_array_uint8(ndr, ndr_flags, addr, IPV6_BYTES));
1014
1015         return NDR_ERR_SUCCESS;
1016 #else
1017         return NDR_ERR_IPV6ADDRESS;
1018 #endif
1019 }
1020
1021 /*
1022   print a ipv6address
1023 */
1024 _PUBLIC_ void ndr_print_ipv6address(struct ndr_print *ndr, const char *name,
1025                            const char *address)
1026 {
1027         ndr->print(ndr, "%-25s: %s", name, address);
1028 }
1029 #undef IPV6_BYTES
1030
1031 _PUBLIC_ void ndr_print_struct(struct ndr_print *ndr, const char *name, const char *type)
1032 {
1033         ndr->print(ndr, "%s: struct %s", name, type);
1034 }
1035
1036 _PUBLIC_ void ndr_print_null(struct ndr_print *ndr)
1037 {
1038         ndr->print(ndr, "UNEXPECTED NULL POINTER");
1039 }
1040
1041 _PUBLIC_ void ndr_print_enum(struct ndr_print *ndr, const char *name, const char *type,
1042                     const char *val, uint32_t value)
1043 {
1044         if (ndr->flags & LIBNDR_PRINT_ARRAY_HEX) {
1045                 ndr->print(ndr, "%-25s: %s (0x%X)", name, val?val:"UNKNOWN_ENUM_VALUE", value);
1046         } else {
1047                 ndr->print(ndr, "%-25s: %s (%d)", name, val?val:"UNKNOWN_ENUM_VALUE", value);
1048         }
1049 }
1050
1051 _PUBLIC_ void ndr_print_bitmap_flag(struct ndr_print *ndr, size_t size, const char *flag_name, uint32_t flag, uint32_t value)
1052 {
1053         if (flag == 0) {
1054                 return;
1055         }
1056
1057         /* this is an attempt to support multi-bit bitmap masks */
1058         value &= flag;
1059
1060         while (!(flag & 1)) {
1061                 flag >>= 1;
1062                 value >>= 1;
1063         }
1064         if (flag == 1) {
1065                 ndr->print(ndr, "   %d: %-25s", value, flag_name);
1066         } else {
1067                 ndr->print(ndr, "0x%02x: %-25s (%d)", value, flag_name, value);
1068         }
1069 }
1070
1071 _PUBLIC_ void ndr_print_int8(struct ndr_print *ndr, const char *name, int8_t v)
1072 {
1073         if (NDR_HIDE_SECRET(ndr)) {
1074                 ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1075                 return;
1076         }
1077         ndr->print(ndr, "%-25s: %d", name, v);
1078 }
1079
1080 _PUBLIC_ void ndr_print_uint8(struct ndr_print *ndr, const char *name, uint8_t v)
1081 {
1082         if (NDR_HIDE_SECRET(ndr)) {
1083                 ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1084                 return;
1085         }
1086         ndr->print(ndr, "%-25s: 0x%02x (%u)", name, v, v);
1087 }
1088
1089 _PUBLIC_ void ndr_print_int16(struct ndr_print *ndr, const char *name, int16_t v)
1090 {
1091         if (NDR_HIDE_SECRET(ndr)) {
1092                 ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1093                 return;
1094         }
1095         ndr->print(ndr, "%-25s: %d", name, v);
1096 }
1097
1098 _PUBLIC_ void ndr_print_uint16(struct ndr_print *ndr, const char *name, uint16_t v)
1099 {
1100         if (NDR_HIDE_SECRET(ndr)) {
1101                 ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1102                 return;
1103         }
1104         ndr->print(ndr, "%-25s: 0x%04x (%u)", name, v, v);
1105 }
1106
1107 _PUBLIC_ void ndr_print_int32(struct ndr_print *ndr, const char *name, int32_t v)
1108 {
1109         if (NDR_HIDE_SECRET(ndr)) {
1110                 ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1111                 return;
1112         }
1113         ndr->print(ndr, "%-25s: %d", name, v);
1114 }
1115
1116 _PUBLIC_ void ndr_print_uint32(struct ndr_print *ndr, const char *name, uint32_t v)
1117 {
1118         if (NDR_HIDE_SECRET(ndr)) {
1119                 ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1120                 return;
1121         }
1122         ndr->print(ndr, "%-25s: 0x%08x (%u)", name, v, v);
1123 }
1124
1125 _PUBLIC_ void ndr_print_int3264(struct ndr_print *ndr, const char *name, int32_t v)
1126 {
1127         if (NDR_HIDE_SECRET(ndr)) {
1128                 ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1129                 return;
1130         }
1131         ndr->print(ndr, "%-25s: %d", name, v);
1132 }
1133
1134 _PUBLIC_ void ndr_print_uint3264(struct ndr_print *ndr, const char *name, uint32_t v)
1135 {
1136         if (NDR_HIDE_SECRET(ndr)) {
1137                 ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1138                 return;
1139         }
1140         ndr->print(ndr, "%-25s: 0x%08x (%u)", name, v, v);
1141 }
1142
1143 _PUBLIC_ void ndr_print_udlong(struct ndr_print *ndr, const char *name, uint64_t v)
1144 {
1145         ndr->print(ndr, "%-25s: 0x%016llx (%llu)", name, (unsigned long long)v, (unsigned long long)v);
1146 }
1147
1148 _PUBLIC_ void ndr_print_udlongr(struct ndr_print *ndr, const char *name, uint64_t v)
1149 {
1150         ndr_print_udlong(ndr, name, v);
1151 }
1152
1153 _PUBLIC_ void ndr_print_dlong(struct ndr_print *ndr, const char *name, int64_t v)
1154 {
1155         if (NDR_HIDE_SECRET(ndr)) {
1156                 ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1157                 return;
1158         }
1159         ndr->print(ndr, "%-25s: 0x%016llx (%lld)", name, (unsigned long long)v, (long long)v);
1160 }
1161
1162 _PUBLIC_ void ndr_print_double(struct ndr_print *ndr, const char *name, double v)
1163 {
1164         ndr->print(ndr, "%-25s: %f", name, v);
1165 }
1166
1167 _PUBLIC_ void ndr_print_hyper(struct ndr_print *ndr, const char *name, uint64_t v)
1168 {
1169         ndr_print_dlong(ndr, name, v);
1170 }
1171
1172 _PUBLIC_ void ndr_print_pointer(struct ndr_print *ndr, const char *name, void *v)
1173 {
1174         ndr->print(ndr, "%-25s: %p", name, v);
1175 }
1176
1177 _PUBLIC_ void ndr_print_ptr(struct ndr_print *ndr, const char *name, const void *p)
1178 {
1179         if (p) {
1180                 ndr->print(ndr, "%-25s: *", name);
1181         } else {
1182                 ndr->print(ndr, "%-25s: NULL", name);
1183         }
1184 }
1185
1186 _PUBLIC_ void ndr_print_NTTIME(struct ndr_print *ndr, const char *name, NTTIME t)
1187 {
1188         ndr->print(ndr, "%-25s: %s", name, nt_time_string(ndr, t));
1189 }
1190
1191 _PUBLIC_ void ndr_print_NTTIME_1sec(struct ndr_print *ndr, const char *name, NTTIME t)
1192 {
1193         /* this is a standard NTTIME here
1194          * as it's already converted in the pull/push code
1195          */
1196         ndr_print_NTTIME(ndr, name, t);
1197 }
1198
1199 _PUBLIC_ void ndr_print_NTTIME_hyper(struct ndr_print *ndr, const char *name, NTTIME t)
1200 {
1201         ndr_print_NTTIME(ndr, name, t);
1202 }
1203
1204 _PUBLIC_ void ndr_print_time_t(struct ndr_print *ndr, const char *name, time_t t)
1205 {
1206         if (t == (time_t)-1 || t == 0) {
1207                 ndr->print(ndr, "%-25s: (time_t)%d", name, (int)t);
1208         } else {
1209                 ndr->print(ndr, "%-25s: %s", name, timestring(ndr, t));
1210         }
1211 }
1212
1213 _PUBLIC_ void ndr_print_uid_t(struct ndr_print *ndr, const char *name, uid_t u)
1214 {
1215         ndr_print_dlong(ndr, name, u);
1216 }
1217
1218 _PUBLIC_ void ndr_print_gid_t(struct ndr_print *ndr, const char *name, gid_t g)
1219 {
1220         ndr_print_dlong(ndr, name, g);
1221 }
1222
1223 _PUBLIC_ void ndr_print_union(struct ndr_print *ndr, const char *name, int level, const char *type)
1224 {
1225         if (ndr->flags & LIBNDR_PRINT_ARRAY_HEX) {
1226                 ndr->print(ndr, "%-25s: union %s(case 0x%X)", name, type, level);
1227         } else {
1228                 ndr->print(ndr, "%-25s: union %s(case %d)", name, type, level);
1229         }
1230 }
1231
1232 _PUBLIC_ void ndr_print_bad_level(struct ndr_print *ndr, const char *name, uint16_t level)
1233 {
1234         ndr->print(ndr, "UNKNOWN LEVEL %u", level);
1235 }
1236
1237 _PUBLIC_ void ndr_print_array_uint8(struct ndr_print *ndr, const char *name,
1238                            const uint8_t *data, uint32_t count)
1239 {
1240         int i;
1241 #define _ONELINE_LIMIT 32
1242
1243         if (data == NULL) {
1244                 ndr->print(ndr, "%s: ARRAY(%d) : NULL", name, count);
1245                 return;
1246         }
1247
1248         if (NDR_HIDE_SECRET(ndr)) {
1249                 ndr->print(ndr, "%s: ARRAY(%d): <REDACTED SECRET VALUES>", name, count);
1250                 return;
1251         }
1252
1253         if (count <= _ONELINE_LIMIT && (ndr->flags & LIBNDR_PRINT_ARRAY_HEX)) {
1254                 char s[(_ONELINE_LIMIT + 1) * 2];
1255                 for (i=0;i<count;i++) {
1256                         snprintf(&s[i*2], 3, "%02x", data[i]);
1257                 }
1258                 s[i*2] = 0;
1259                 ndr->print(ndr, "%-25s: %s", name, s);
1260                 return;
1261         }
1262
1263         ndr->print(ndr, "%s: ARRAY(%d)", name, count);
1264         if (count > _ONELINE_LIMIT && (ndr->flags & LIBNDR_PRINT_ARRAY_HEX)) {
1265                 ndr_dump_data(ndr, data, count);
1266                 return;
1267         }
1268
1269         ndr->depth++;
1270         for (i=0;i<count;i++) {
1271                 char *idx=NULL;
1272                 if (asprintf(&idx, "[%d]", i) != -1) {
1273                         ndr_print_uint8(ndr, idx, data[i]);
1274                         free(idx);
1275                 }
1276         }
1277         ndr->depth--;
1278 #undef _ONELINE_LIMIT
1279 }
1280
1281 static void ndr_print_dump_data_cb(const char *buf, void *private_data)
1282 {
1283         struct ndr_print *ndr = (struct ndr_print *)private_data;
1284
1285         ndr->print(ndr, "%s", buf);
1286 }
1287
1288 /*
1289   ndr_print version of dump_data()
1290  */
1291 static void ndr_dump_data(struct ndr_print *ndr, const uint8_t *buf, int len)
1292 {
1293         if (NDR_HIDE_SECRET(ndr)) {
1294                 return;
1295         }
1296         ndr->no_newline = true;
1297         dump_data_cb(buf, len, true, ndr_print_dump_data_cb, ndr);
1298         ndr->no_newline = false;
1299 }
1300
1301
1302 _PUBLIC_ void ndr_print_DATA_BLOB(struct ndr_print *ndr, const char *name, DATA_BLOB r)
1303 {
1304         ndr->print(ndr, "%-25s: DATA_BLOB length=%u", name, (unsigned)r.length);
1305         if (r.length) {
1306                 ndr_dump_data(ndr, r.data, r.length);
1307         }
1308 }
1309
1310
1311 /*
1312  * Push a DATA_BLOB onto the wire.
1313  * 1) When called with LIBNDR_FLAG_ALIGN* alignment flags set, push padding
1314  *    bytes _only_. The length is determined by the alignment required and the
1315  *    current ndr offset.
1316  * 2) When called with the LIBNDR_FLAG_REMAINING flag, push the byte array to
1317  *    the ndr buffer.
1318  * 3) Otherwise, push a uint3264 length _and_ a corresponding byte array to the
1319  *    ndr buffer.
1320  */
1321 _PUBLIC_ enum ndr_err_code ndr_push_DATA_BLOB(struct ndr_push *ndr, int ndr_flags, DATA_BLOB blob)
1322 {
1323         if (ndr->flags & LIBNDR_FLAG_REMAINING) {
1324                 /* nothing to do */
1325         } else if (ndr->flags & (LIBNDR_ALIGN_FLAGS & ~LIBNDR_FLAG_NOALIGN)) {
1326                 if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
1327                         blob.length = NDR_ALIGN(ndr, 2);
1328                 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
1329                         blob.length = NDR_ALIGN(ndr, 4);
1330                 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
1331                         blob.length = NDR_ALIGN(ndr, 8);
1332                 }
1333                 NDR_PUSH_ALLOC_SIZE(ndr, blob.data, blob.length);
1334                 data_blob_clear(&blob);
1335         } else {
1336                 NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, blob.length));
1337         }
1338         NDR_CHECK(ndr_push_bytes(ndr, blob.data, blob.length));
1339         return NDR_ERR_SUCCESS;
1340 }
1341
1342 /*
1343  * Pull a DATA_BLOB from the wire.
1344  * 1) when called with LIBNDR_FLAG_ALIGN* alignment flags set, pull padding
1345  *    bytes _only_. The length is determined by the alignment required and the
1346  *    current ndr offset.
1347  * 2) When called with the LIBNDR_FLAG_REMAINING flag, pull all remaining bytes
1348  *    from the ndr buffer.
1349  * 3) Otherwise, pull a uint3264 length _and_ a corresponding byte array from the
1350  *    ndr buffer.
1351  */
1352 _PUBLIC_ enum ndr_err_code ndr_pull_DATA_BLOB(struct ndr_pull *ndr, int ndr_flags, DATA_BLOB *blob)
1353 {
1354         uint32_t length = 0;
1355
1356         if (ndr->flags & LIBNDR_FLAG_REMAINING) {
1357                 length = ndr->data_size - ndr->offset;
1358         } else if (ndr->flags & (LIBNDR_ALIGN_FLAGS & ~LIBNDR_FLAG_NOALIGN)) {
1359                 if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
1360                         length = NDR_ALIGN(ndr, 2);
1361                 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
1362                         length = NDR_ALIGN(ndr, 4);
1363                 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
1364                         length = NDR_ALIGN(ndr, 8);
1365                 }
1366                 if (ndr->data_size - ndr->offset < length) {
1367                         length = ndr->data_size - ndr->offset;
1368                 }
1369         } else {
1370                 NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &length));
1371         }
1372         NDR_PULL_NEED_BYTES(ndr, length);
1373         *blob = data_blob_talloc(ndr->current_mem_ctx, ndr->data+ndr->offset, length);
1374         ndr->offset += length;
1375         return NDR_ERR_SUCCESS;
1376 }
1377
1378 _PUBLIC_ uint32_t ndr_size_DATA_BLOB(int ret, const DATA_BLOB *data, int flags)
1379 {
1380         if (!data) return ret;
1381         return ret + data->length;
1382 }
1383
1384 _PUBLIC_ void ndr_print_bool(struct ndr_print *ndr, const char *name, const bool b)
1385 {
1386         ndr->print(ndr, "%-25s: %s", name, b?"true":"false");
1387 }
1388
1389 _PUBLIC_ NTSTATUS ndr_map_error2ntstatus(enum ndr_err_code ndr_err)
1390 {
1391         switch (ndr_err) {
1392         case NDR_ERR_SUCCESS:
1393                 return NT_STATUS_OK;
1394         case NDR_ERR_BUFSIZE:
1395                 return NT_STATUS_BUFFER_TOO_SMALL;
1396         case NDR_ERR_TOKEN:
1397                 return NT_STATUS_INTERNAL_ERROR;
1398         case NDR_ERR_ALLOC:
1399                 return NT_STATUS_NO_MEMORY;
1400         case NDR_ERR_ARRAY_SIZE:
1401                 return NT_STATUS_ARRAY_BOUNDS_EXCEEDED;
1402         case NDR_ERR_INVALID_POINTER:
1403                 return NT_STATUS_INVALID_PARAMETER_MIX;
1404         case NDR_ERR_UNREAD_BYTES:
1405                 return NT_STATUS_PORT_MESSAGE_TOO_LONG;
1406         default:
1407                 break;
1408         }
1409
1410         /* we should map all error codes to different status codes */
1411         return NT_STATUS_INVALID_PARAMETER;
1412 }
1413
1414 _PUBLIC_ int ndr_map_error2errno(enum ndr_err_code ndr_err)
1415 {
1416         switch (ndr_err) {
1417         case NDR_ERR_SUCCESS:
1418                 return 0;
1419         case NDR_ERR_BUFSIZE:
1420                 return ENOSPC;
1421         case NDR_ERR_TOKEN:
1422                 return EINVAL;
1423         case NDR_ERR_ALLOC:
1424                 return ENOMEM;
1425         case NDR_ERR_ARRAY_SIZE:
1426                 return EMSGSIZE;
1427         case NDR_ERR_INVALID_POINTER:
1428                 return EINVAL;
1429         case NDR_ERR_UNREAD_BYTES:
1430                 return EOVERFLOW;
1431         default:
1432                 break;
1433         }
1434
1435         /* we should map all error codes to different status codes */
1436         return EINVAL;
1437 }
1438
1439 _PUBLIC_ enum ndr_err_code ndr_push_timespec(struct ndr_push *ndr,
1440                                              int ndr_flags,
1441                                              const struct timespec *t)
1442 {
1443         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
1444         NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t->tv_sec));
1445         NDR_CHECK(ndr_push_uint32(ndr, ndr_flags, t->tv_nsec));
1446         return NDR_ERR_SUCCESS;
1447 }
1448
1449 _PUBLIC_ enum ndr_err_code ndr_pull_timespec(struct ndr_pull *ndr,
1450                                              int ndr_flags,
1451                                              struct timespec *t)
1452 {
1453         uint64_t secs;
1454         uint32_t nsecs;
1455         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
1456         NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, &secs));
1457         NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &nsecs));
1458         t->tv_sec = secs;
1459         t->tv_nsec = nsecs;
1460         return NDR_ERR_SUCCESS;
1461 }
1462
1463 _PUBLIC_ void ndr_print_timespec(struct ndr_print *ndr, const char *name,
1464                                  const struct timespec *t)
1465 {
1466         ndr->print(ndr, "%-25s: %s.%ld", name, timestring(ndr, t->tv_sec),
1467                    (long)t->tv_nsec);
1468 }
1469
1470 _PUBLIC_ enum ndr_err_code ndr_push_timeval(struct ndr_push *ndr,
1471                                             int ndr_flags,
1472                                             const struct timeval *t)
1473 {
1474         NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
1475         NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t->tv_sec));
1476         NDR_CHECK(ndr_push_uint32(ndr, ndr_flags, t->tv_usec));
1477         return NDR_ERR_SUCCESS;
1478 }
1479
1480 _PUBLIC_ enum ndr_err_code ndr_pull_timeval(struct ndr_pull *ndr,
1481                                             int ndr_flags,
1482                                             struct timeval *t)
1483 {
1484         uint64_t secs;
1485         uint32_t usecs;
1486         NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
1487         NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, &secs));
1488         NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &usecs));
1489         t->tv_sec = secs;
1490         t->tv_usec = usecs;
1491         return NDR_ERR_SUCCESS;
1492 }
1493
1494 _PUBLIC_ void ndr_print_timeval(struct ndr_print *ndr, const char *name,
1495                                 const struct timeval *t)
1496 {
1497         ndr->print(ndr, "%-25s: %s.%ld", name, timestring(ndr, t->tv_sec),
1498                    (long)t->tv_usec);
1499 }