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