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