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