2 Unix SMB/CIFS implementation.
4 routines for marshalling/unmarshalling basic types
6 Copyright (C) Andrew Tridgell 2003
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.
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.
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.
25 #define NDR_BE(ndr) (((ndr)->flags & (LIBNDR_FLAG_BIGENDIAN|LIBNDR_FLAG_LITTLE_ENDIAN)) == LIBNDR_FLAG_BIGENDIAN)
26 #define NDR_SVAL(ndr, ofs) (NDR_BE(ndr)?RSVAL(ndr->data,ofs):SVAL(ndr->data,ofs))
27 #define NDR_IVAL(ndr, ofs) (NDR_BE(ndr)?RIVAL(ndr->data,ofs):IVAL(ndr->data,ofs))
28 #define NDR_IVALS(ndr, ofs) (NDR_BE(ndr)?RIVALS(ndr->data,ofs):IVALS(ndr->data,ofs))
29 #define NDR_SSVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSSVAL(ndr->data,ofs,v); } else SSVAL(ndr->data,ofs,v); } while (0)
30 #define NDR_SIVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVAL(ndr->data,ofs,v); } else SIVAL(ndr->data,ofs,v); } while (0)
31 #define NDR_SIVALS(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVALS(ndr->data,ofs,v); } else SIVALS(ndr->data,ofs,v); } while (0)
35 check for data leaks from the server by looking for non-zero pad bytes
36 these could also indicate that real structure elements have been
37 mistaken for padding in the IDL
39 void ndr_check_padding(struct ndr_pull
*ndr
, size_t n
)
41 size_t ofs2
= (ndr
->offset
+ (n
-1)) & ~(n
-1);
43 for (i
=ndr
->offset
;i
<ofs2
;i
++) {
44 if (ndr
->data
[i
] != 0) {
49 DEBUG(0,("WARNING: Non-zero padding to %d: ", n
));
50 for (i
=ndr
->offset
;i
<ofs2
;i
++) {
51 DEBUG(0,("%02x ", ndr
->data
[i
]));
61 NTSTATUS
ndr_pull_uint8(struct ndr_pull
*ndr
, uint8_t *v
)
63 NDR_PULL_NEED_BYTES(ndr
, 1);
64 *v
= CVAL(ndr
->data
, ndr
->offset
);
73 NTSTATUS
ndr_pull_uint16(struct ndr_pull
*ndr
, uint16_t *v
)
75 NDR_PULL_ALIGN(ndr
, 2);
76 NDR_PULL_NEED_BYTES(ndr
, 2);
77 *v
= NDR_SVAL(ndr
, ndr
->offset
);
86 NTSTATUS
ndr_pull_uint32(struct ndr_pull
*ndr
, uint32_t *v
)
88 NDR_PULL_ALIGN(ndr
, 4);
89 NDR_PULL_NEED_BYTES(ndr
, 4);
90 *v
= NDR_IVAL(ndr
, ndr
->offset
);
98 NTSTATUS
ndr_pull_int32(struct ndr_pull
*ndr
, int32_t *v
)
100 NDR_PULL_ALIGN(ndr
, 4);
101 NDR_PULL_NEED_BYTES(ndr
, 4);
102 *v
= NDR_IVALS(ndr
, ndr
->offset
);
110 NTSTATUS
ndr_pull_ptr(struct ndr_pull
*ndr
, uint32_t *v
)
113 status
= ndr_pull_uint32(ndr
, v
);
123 NTSTATUS
ndr_pull_uint64(struct ndr_pull
*ndr
, uint64_t *v
)
125 NDR_PULL_ALIGN(ndr
, 4);
126 NDR_PULL_NEED_BYTES(ndr
, 8);
127 *v
= NDR_IVAL(ndr
, ndr
->offset
);
128 *v
|= (uint64_t)(NDR_IVAL(ndr
, ndr
->offset
+4)) << 32;
136 NTSTATUS
ndr_pull_int64(struct ndr_pull
*ndr
, int64_t *v
)
138 return ndr_pull_uint64(ndr
, (uint64_t *)v
);
144 NTSTATUS
ndr_pull_HYPER_T(struct ndr_pull
*ndr
, HYPER_T
*v
)
146 NDR_PULL_ALIGN(ndr
, 8);
147 return ndr_pull_uint64(ndr
, v
);
153 NTSTATUS
ndr_pull_NTSTATUS(struct ndr_pull
*ndr
, NTSTATUS
*status
)
156 NDR_CHECK(ndr_pull_uint32(ndr
, &v
));
157 *status
= NT_STATUS(v
);
164 NTSTATUS
ndr_push_NTSTATUS(struct ndr_push
*ndr
, NTSTATUS status
)
166 return ndr_push_uint32(ndr
, NT_STATUS_V(status
));
169 void ndr_print_NTSTATUS(struct ndr_print
*ndr
, const char *name
, NTSTATUS
*r
)
171 ndr
->print(ndr
, "%-25s: %s", name
, nt_errstr(*r
));
177 NTSTATUS
ndr_pull_WERROR(struct ndr_pull
*ndr
, WERROR
*status
)
180 NDR_CHECK(ndr_pull_uint32(ndr
, &v
));
181 *status
= W_ERROR(v
);
188 NTSTATUS
ndr_push_WERROR(struct ndr_push
*ndr
, WERROR status
)
190 return ndr_push_uint32(ndr
, W_ERROR_V(status
));
193 void ndr_print_WERROR(struct ndr_print
*ndr
, const char *name
, WERROR r
)
195 ndr
->print(ndr
, "%-25s: %s", name
, win_errstr(r
));
201 NTSTATUS
ndr_pull_bytes(struct ndr_pull
*ndr
, uint8_t *data
, uint32_t n
)
203 NDR_PULL_NEED_BYTES(ndr
, n
);
204 memcpy(data
, ndr
->data
+ ndr
->offset
, n
);
210 pull an array of uint8
212 NTSTATUS
ndr_pull_array_uint8(struct ndr_pull
*ndr
, int ndr_flags
, uint8_t *data
, uint32_t n
)
214 if (!(ndr_flags
& NDR_SCALARS
)) {
217 return ndr_pull_bytes(ndr
, data
, n
);
222 pull an array of uint16
224 NTSTATUS
ndr_pull_array_uint16(struct ndr_pull
*ndr
, int ndr_flags
, uint16_t *data
, uint32_t n
)
227 if (!(ndr_flags
& NDR_SCALARS
)) {
231 NDR_CHECK(ndr_pull_uint16(ndr
, &data
[i
]));
237 pull a const array of uint32_t
239 NTSTATUS
ndr_pull_array_uint32(struct ndr_pull
*ndr
, int ndr_flags
, uint32_t *data
, uint32_t n
)
242 if (!(ndr_flags
& NDR_SCALARS
)) {
246 NDR_CHECK(ndr_pull_uint32(ndr
, &data
[i
]));
252 pull a const array of HYPER_T
254 NTSTATUS
ndr_pull_array_HYPER_T(struct ndr_pull
*ndr
, int ndr_flags
, HYPER_T
*data
, uint32_t n
)
257 if (!(ndr_flags
& NDR_SCALARS
)) {
261 NDR_CHECK(ndr_pull_HYPER_T(ndr
, &data
[i
]));
267 pull a const array of WERROR
269 NTSTATUS
ndr_pull_array_WERROR(struct ndr_pull
*ndr
, int ndr_flags
, WERROR
*data
, uint32_t n
)
272 if (!(ndr_flags
& NDR_SCALARS
)) {
276 NDR_CHECK(ndr_pull_WERROR(ndr
, &data
[i
]));
286 NTSTATUS
ndr_push_uint8(struct ndr_push
*ndr
, uint8_t v
)
288 NDR_PUSH_NEED_BYTES(ndr
, 1);
289 SCVAL(ndr
->data
, ndr
->offset
, v
);
297 NTSTATUS
ndr_push_uint16(struct ndr_push
*ndr
, uint16_t v
)
299 NDR_PUSH_ALIGN(ndr
, 2);
300 NDR_PUSH_NEED_BYTES(ndr
, 2);
301 NDR_SSVAL(ndr
, ndr
->offset
, v
);
309 NTSTATUS
ndr_push_uint32(struct ndr_push
*ndr
, uint32_t v
)
311 NDR_PUSH_ALIGN(ndr
, 4);
312 NDR_PUSH_NEED_BYTES(ndr
, 4);
313 NDR_SIVAL(ndr
, ndr
->offset
, v
);
321 NTSTATUS
ndr_push_int32(struct ndr_push
*ndr
, int32_t v
)
323 NDR_PUSH_ALIGN(ndr
, 4);
324 NDR_PUSH_NEED_BYTES(ndr
, 4);
325 NDR_SIVALS(ndr
, ndr
->offset
, v
);
333 NTSTATUS
ndr_push_uint64(struct ndr_push
*ndr
, uint64_t v
)
335 NDR_PUSH_ALIGN(ndr
, 4);
336 NDR_PUSH_NEED_BYTES(ndr
, 8);
337 NDR_SIVAL(ndr
, ndr
->offset
, (v
& 0xFFFFFFFF));
338 NDR_SIVAL(ndr
, ndr
->offset
+4, (v
>>32));
346 NTSTATUS
ndr_push_int64(struct ndr_push
*ndr
, int64_t v
)
348 return ndr_push_uint64(ndr
, (uint64_t)v
);
354 NTSTATUS
ndr_push_HYPER_T(struct ndr_push
*ndr
, HYPER_T v
)
356 NDR_PUSH_ALIGN(ndr
, 8);
357 return ndr_push_uint64(ndr
, v
);
360 NTSTATUS
ndr_push_align(struct ndr_push
*ndr
, size_t size
)
362 NDR_PUSH_ALIGN(ndr
, size
);
366 NTSTATUS
ndr_pull_align(struct ndr_pull
*ndr
, size_t size
)
368 NDR_PULL_ALIGN(ndr
, size
);
375 NTSTATUS
ndr_push_bytes(struct ndr_push
*ndr
, const uint8_t *data
, uint32_t n
)
377 NDR_PUSH_NEED_BYTES(ndr
, n
);
378 memcpy(ndr
->data
+ ndr
->offset
, data
, n
);
386 NTSTATUS
ndr_push_zero(struct ndr_push
*ndr
, uint32_t n
)
388 NDR_PUSH_NEED_BYTES(ndr
, n
);
389 memset(ndr
->data
+ ndr
->offset
, 0, n
);
395 push an array of uint8
397 NTSTATUS
ndr_push_array_uint8(struct ndr_push
*ndr
, int ndr_flags
, const uint8_t *data
, uint32_t n
)
399 if (!(ndr_flags
& NDR_SCALARS
)) {
402 return ndr_push_bytes(ndr
, data
, n
);
406 push an array of uint16
408 NTSTATUS
ndr_push_array_uint16(struct ndr_push
*ndr
, int ndr_flags
, const uint16_t *data
, uint32_t n
)
411 if (!(ndr_flags
& NDR_SCALARS
)) {
415 NDR_CHECK(ndr_push_uint16(ndr
, data
[i
]));
421 push an array of uint32_t
423 NTSTATUS
ndr_push_array_uint32(struct ndr_push
*ndr
, int ndr_flags
, const uint32_t *data
, uint32_t n
)
426 if (!(ndr_flags
& NDR_SCALARS
)) {
430 NDR_CHECK(ndr_push_uint32(ndr
, data
[i
]));
436 push an array of HYPER_T
438 NTSTATUS
ndr_push_array_HYPER_T(struct ndr_push
*ndr
, int ndr_flags
, const HYPER_T
*data
, uint32_t n
)
441 if (!(ndr_flags
& NDR_SCALARS
)) {
445 NDR_CHECK(ndr_push_HYPER_T(ndr
, data
[i
]));
451 push an array of HYPER_T
453 NTSTATUS
ndr_push_array_WERROR(struct ndr_push
*ndr
, int ndr_flags
, const WERROR
*data
, uint32_t n
)
456 if (!(ndr_flags
& NDR_SCALARS
)) {
460 NDR_CHECK(ndr_push_WERROR(ndr
, data
[i
]));
466 save the current position
468 void ndr_push_save(struct ndr_push
*ndr
, struct ndr_push_save
*save
)
470 save
->offset
= ndr
->offset
;
476 void ndr_push_restore(struct ndr_push
*ndr
, struct ndr_push_save
*save
)
478 ndr
->offset
= save
->offset
;
482 push a 1 if a pointer is non-NULL, otherwise 0
484 NTSTATUS
ndr_push_ptr(struct ndr_push
*ndr
, const void *p
)
488 /* we do this to ensure that we generate unique ref ids,
489 which means we can handle the case where a MS programmer
490 forgot to mark a pointer as unique */
492 ptr
= ndr
->ptr_count
;
494 return ndr_push_uint32(ndr
, ptr
);
499 pull a general string from the wire
501 NTSTATUS
ndr_pull_string(struct ndr_pull
*ndr
, int ndr_flags
, const char **s
)
504 uint32_t len1
, ofs
, len2
;
507 int chset
= CH_UTF16
;
508 unsigned byte_mul
= 2;
509 unsigned flags
= ndr
->flags
;
510 unsigned c_len_term
= 0;
512 if (!(ndr_flags
& NDR_SCALARS
)) {
520 if (flags
& LIBNDR_FLAG_STR_ASCII
) {
523 flags
&= ~LIBNDR_FLAG_STR_ASCII
;
526 if (flags
& LIBNDR_FLAG_STR_UTF8
) {
529 flags
&= ~LIBNDR_FLAG_STR_UTF8
;
532 flags
&= ~LIBNDR_FLAG_STR_CONFORMANT
;
533 if (flags
& LIBNDR_FLAG_STR_CHARLEN
) {
535 flags
&= ~LIBNDR_FLAG_STR_CHARLEN
;
538 switch (flags
& LIBNDR_STRING_FLAGS
) {
539 case LIBNDR_FLAG_STR_LEN4
|LIBNDR_FLAG_STR_SIZE4
:
540 case LIBNDR_FLAG_STR_LEN4
|LIBNDR_FLAG_STR_SIZE4
|LIBNDR_FLAG_STR_NOTERM
:
541 NDR_CHECK(ndr_pull_uint32(ndr
, &len1
));
542 NDR_CHECK(ndr_pull_uint32(ndr
, &ofs
));
544 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "non-zero array offset with string flags 0x%x\n",
545 ndr
->flags
& LIBNDR_STRING_FLAGS
);
547 NDR_CHECK(ndr_pull_uint32(ndr
, &len2
));
549 return ndr_pull_error(ndr
, NDR_ERR_STRING
,
550 "Bad string lengths len1=%u ofs=%u len2=%u\n",
554 *s
= talloc_strdup(ndr
, "");
557 NDR_PULL_NEED_BYTES(ndr
, (len2
+ c_len_term
)*byte_mul
);
558 ret
= convert_string_talloc(ndr
, chset
, CH_UNIX
,
559 ndr
->data
+ndr
->offset
,
560 (len2
+ c_len_term
)*byte_mul
,
563 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
564 "Bad character conversion");
566 NDR_CHECK(ndr_pull_advance(ndr
, (len2
+ c_len_term
)*byte_mul
));
568 /* this is a way of detecting if a string is sent with the wrong
570 if (ndr
->flags
& LIBNDR_FLAG_STR_NOTERM
) {
571 if (strlen(as
) < (len2
+ c_len_term
)) {
572 DEBUG(6,("short string '%s'\n", as
));
575 if (strlen(as
) == (len2
+ c_len_term
)) {
576 DEBUG(6,("long string '%s'\n", as
));
582 case LIBNDR_FLAG_STR_SIZE4
:
583 case LIBNDR_FLAG_STR_SIZE4
|LIBNDR_FLAG_STR_NOTERM
:
584 NDR_CHECK(ndr_pull_uint32(ndr
, &len1
));
585 NDR_PULL_NEED_BYTES(ndr
, (len1
+ c_len_term
)*byte_mul
);
587 *s
= talloc_strdup(ndr
, "");
590 ret
= convert_string_talloc(ndr
, chset
, CH_UNIX
,
591 ndr
->data
+ndr
->offset
,
592 (len1
+ c_len_term
)*byte_mul
,
595 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
596 "Bad character conversion");
598 NDR_CHECK(ndr_pull_advance(ndr
, (len1
+ c_len_term
)*byte_mul
));
600 /* this is a way of detecting if a string is sent with the wrong
602 if (ndr
->flags
& LIBNDR_FLAG_STR_NOTERM
) {
603 if (strlen(as
) < (len1
+ c_len_term
)) {
604 DEBUG(6,("short string '%s'\n", as
));
607 if (strlen(as
) == (len1
+ c_len_term
)) {
608 DEBUG(6,("long string '%s'\n", as
));
614 case LIBNDR_FLAG_STR_LEN4
:
615 case LIBNDR_FLAG_STR_LEN4
|LIBNDR_FLAG_STR_NOTERM
:
616 NDR_CHECK(ndr_pull_uint32(ndr
, &ofs
));
618 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "non-zero array offset with string flags 0x%x\n",
619 ndr
->flags
& LIBNDR_STRING_FLAGS
);
621 NDR_CHECK(ndr_pull_uint32(ndr
, &len1
));
622 NDR_PULL_NEED_BYTES(ndr
, (len1
+ c_len_term
)*byte_mul
);
624 *s
= talloc_strdup(ndr
, "");
627 ret
= convert_string_talloc(ndr
, chset
, CH_UNIX
,
628 ndr
->data
+ndr
->offset
,
629 (len1
+ c_len_term
)*byte_mul
,
632 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
633 "Bad character conversion");
635 NDR_CHECK(ndr_pull_advance(ndr
, (len1
+ c_len_term
)*byte_mul
));
637 /* this is a way of detecting if a string is sent with the wrong
639 if (ndr
->flags
& LIBNDR_FLAG_STR_NOTERM
) {
640 if (strlen(as
) < (len1
+ c_len_term
)) {
641 DEBUG(6,("short string '%s'\n", as
));
644 if (strlen(as
) == (len1
+ c_len_term
)) {
645 DEBUG(6,("long string '%s'\n", as
));
652 case LIBNDR_FLAG_STR_SIZE2
:
653 case LIBNDR_FLAG_STR_SIZE2
|LIBNDR_FLAG_STR_NOTERM
:
654 NDR_CHECK(ndr_pull_uint16(ndr
, &len3
));
655 NDR_PULL_NEED_BYTES(ndr
, (len3
+ c_len_term
)*byte_mul
);
657 *s
= talloc_strdup(ndr
, "");
660 ret
= convert_string_talloc(ndr
, chset
, CH_UNIX
,
661 ndr
->data
+ndr
->offset
,
662 (len3
+ c_len_term
)*byte_mul
,
665 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
666 "Bad character conversion");
668 NDR_CHECK(ndr_pull_advance(ndr
, (len3
+ c_len_term
)*byte_mul
));
670 /* this is a way of detecting if a string is sent with the wrong
672 if (ndr
->flags
& LIBNDR_FLAG_STR_NOTERM
) {
673 if (strlen(as
) < (len3
+ c_len_term
)) {
674 DEBUG(6,("short string '%s'\n", as
));
677 if (strlen(as
) == (len3
+ c_len_term
)) {
678 DEBUG(6,("long string '%s'\n", as
));
684 case LIBNDR_FLAG_STR_SIZE2
|LIBNDR_FLAG_STR_NOTERM
|LIBNDR_FLAG_STR_BYTESIZE
:
685 NDR_CHECK(ndr_pull_uint16(ndr
, &len3
));
686 NDR_PULL_NEED_BYTES(ndr
, len3
);
688 *s
= talloc_strdup(ndr
, "");
691 ret
= convert_string_talloc(ndr
, chset
, CH_UNIX
,
692 ndr
->data
+ndr
->offset
,
696 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
697 "Bad character conversion");
699 NDR_CHECK(ndr_pull_advance(ndr
, len3
));
703 case LIBNDR_FLAG_STR_NULLTERM
:
705 len1
= ascii_len_n((const char *)(ndr
->data
+ndr
->offset
), ndr
->data_size
- ndr
->offset
);
707 len1
= utf16_len_n(ndr
->data
+ndr
->offset
, ndr
->data_size
- ndr
->offset
);
709 ret
= convert_string_talloc(ndr
, chset
, CH_UNIX
,
710 ndr
->data
+ndr
->offset
,
714 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
715 "Bad character conversion");
717 NDR_CHECK(ndr_pull_advance(ndr
, len1
));
721 case LIBNDR_FLAG_STR_FIXLEN15
:
722 case LIBNDR_FLAG_STR_FIXLEN32
:
723 len1
= (flags
& LIBNDR_FLAG_STR_FIXLEN32
)?32:15;
724 NDR_PULL_NEED_BYTES(ndr
, len1
*byte_mul
);
725 ret
= convert_string_talloc(ndr
, chset
, CH_UNIX
,
726 ndr
->data
+ndr
->offset
,
730 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
731 "Bad character conversion");
733 NDR_CHECK(ndr_pull_advance(ndr
, len1
*byte_mul
));
738 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x\n",
739 ndr
->flags
& LIBNDR_STRING_FLAGS
);
747 push a general string onto the wire
749 NTSTATUS
ndr_push_string(struct ndr_push
*ndr
, int ndr_flags
, const char *s
)
751 ssize_t s_len
, c_len
, d_len
;
753 int chset
= CH_UTF16
;
754 unsigned flags
= ndr
->flags
;
755 unsigned byte_mul
= 2;
756 unsigned c_len_term
= 1;
758 if (!(ndr_flags
& NDR_SCALARS
)) {
766 s_len
= s
?strlen(s
):0;
767 c_len
= s
?strlen_m(s
):0;
769 if (flags
& LIBNDR_FLAG_STR_ASCII
) {
772 flags
&= ~LIBNDR_FLAG_STR_ASCII
;
775 if (flags
& LIBNDR_FLAG_STR_UTF8
) {
778 flags
&= ~LIBNDR_FLAG_STR_UTF8
;
781 flags
&= ~LIBNDR_FLAG_STR_CONFORMANT
;
783 if (flags
& LIBNDR_FLAG_STR_CHARLEN
) {
785 flags
&= ~LIBNDR_FLAG_STR_CHARLEN
;
788 switch (flags
& LIBNDR_STRING_FLAGS
) {
789 case LIBNDR_FLAG_STR_LEN4
|LIBNDR_FLAG_STR_SIZE4
:
790 NDR_CHECK(ndr_push_uint32(ndr
, c_len
+c_len_term
));
791 NDR_CHECK(ndr_push_uint32(ndr
, 0));
792 NDR_CHECK(ndr_push_uint32(ndr
, c_len
+c_len_term
));
793 NDR_PUSH_NEED_BYTES(ndr
, byte_mul
*(c_len
+1));
794 ret
= convert_string(CH_UNIX
, chset
,
796 ndr
->data
+ndr
->offset
,
799 return ndr_push_error(ndr
, NDR_ERR_CHARCNV
,
800 "Bad character conversion");
802 ndr
->offset
+= byte_mul
*(c_len
+1);
805 case LIBNDR_FLAG_STR_LEN4
|LIBNDR_FLAG_STR_SIZE4
|LIBNDR_FLAG_STR_NOTERM
:
806 NDR_CHECK(ndr_push_uint32(ndr
, c_len
));
807 NDR_CHECK(ndr_push_uint32(ndr
, 0));
808 NDR_CHECK(ndr_push_uint32(ndr
, c_len
));
809 NDR_PUSH_NEED_BYTES(ndr
, c_len
*byte_mul
);
810 ret
= convert_string(CH_UNIX
, chset
,
812 ndr
->data
+ndr
->offset
, c_len
*byte_mul
);
814 return ndr_push_error(ndr
, NDR_ERR_CHARCNV
,
815 "Bad character conversion");
817 ndr
->offset
+= c_len
*byte_mul
;
820 case LIBNDR_FLAG_STR_LEN4
:
821 NDR_CHECK(ndr_push_uint32(ndr
, 0));
822 NDR_CHECK(ndr_push_uint32(ndr
, c_len
+ c_len_term
));
823 NDR_PUSH_NEED_BYTES(ndr
, byte_mul
*(c_len
+1));
824 ret
= convert_string(CH_UNIX
, chset
,
826 ndr
->data
+ndr
->offset
, byte_mul
*(c_len
+1));
828 return ndr_push_error(ndr
, NDR_ERR_CHARCNV
,
829 "Bad character conversion");
831 ndr
->offset
+= byte_mul
*(c_len
+1);
834 case LIBNDR_FLAG_STR_SIZE4
:
835 NDR_CHECK(ndr_push_uint32(ndr
, c_len
+ c_len_term
));
836 NDR_PUSH_NEED_BYTES(ndr
, byte_mul
*(c_len
+1));
837 ret
= convert_string(CH_UNIX
, chset
,
839 ndr
->data
+ndr
->offset
, byte_mul
*(c_len
+1));
841 return ndr_push_error(ndr
, NDR_ERR_CHARCNV
,
842 "Bad character conversion");
844 ndr
->offset
+= byte_mul
*(c_len
+1);
847 case LIBNDR_FLAG_STR_SIZE2
:
848 NDR_CHECK(ndr_push_uint16(ndr
, c_len
+ c_len_term
));
849 NDR_PUSH_NEED_BYTES(ndr
, byte_mul
*(c_len
+1));
850 ret
= convert_string(CH_UNIX
, chset
,
852 ndr
->data
+ndr
->offset
, byte_mul
*(c_len
+1));
854 return ndr_push_error(ndr
, NDR_ERR_CHARCNV
,
855 "Bad character conversion");
857 ndr
->offset
+= byte_mul
*(c_len
+1);
860 case LIBNDR_FLAG_STR_NULLTERM
:
861 NDR_PUSH_NEED_BYTES(ndr
, byte_mul
*(c_len
+1));
862 ret
= convert_string(CH_UNIX
, chset
,
864 ndr
->data
+ndr
->offset
, byte_mul
*(c_len
+1));
866 return ndr_push_error(ndr
, NDR_ERR_CHARCNV
,
867 "Bad character conversion");
869 ndr
->offset
+= byte_mul
*(c_len
+1);
872 case LIBNDR_FLAG_STR_SIZE2
|LIBNDR_FLAG_STR_NOTERM
|LIBNDR_FLAG_STR_BYTESIZE
:
873 NDR_CHECK(ndr_push_uint16(ndr
, c_len
*byte_mul
));
874 NDR_PUSH_NEED_BYTES(ndr
, c_len
*byte_mul
);
875 ret
= convert_string(CH_UNIX
, chset
,
877 ndr
->data
+ndr
->offset
, c_len
*byte_mul
);
879 return ndr_push_error(ndr
, NDR_ERR_CHARCNV
,
880 "Bad character conversion");
882 ndr
->offset
+= c_len
*byte_mul
;
885 case LIBNDR_FLAG_STR_FIXLEN15
:
886 case LIBNDR_FLAG_STR_FIXLEN32
:
887 d_len
= (flags
& LIBNDR_FLAG_STR_FIXLEN32
)?32:15;
888 NDR_PUSH_NEED_BYTES(ndr
, byte_mul
*d_len
);
889 ret
= convert_string(CH_UNIX
, chset
,
891 ndr
->data
+ndr
->offset
, byte_mul
*d_len
);
893 return ndr_push_error(ndr
, NDR_ERR_CHARCNV
,
894 "Bad character conversion");
896 ndr
->offset
+= byte_mul
*d_len
;
900 return ndr_push_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x\n",
901 ndr
->flags
& LIBNDR_STRING_FLAGS
);
908 push a general string onto the wire
910 size_t ndr_string_array_size(struct ndr_push
*ndr
, const char *s
)
913 unsigned flags
= ndr
->flags
;
914 unsigned byte_mul
= 2;
915 unsigned c_len_term
= 1;
917 if (flags
& LIBNDR_FLAG_STR_FIXLEN32
) {
920 if (flags
& LIBNDR_FLAG_STR_FIXLEN15
) {
924 c_len
= s
?strlen_m(s
):0;
926 if (flags
& (LIBNDR_FLAG_STR_ASCII
|LIBNDR_FLAG_STR_UTF8
)) {
930 if (flags
& LIBNDR_FLAG_STR_NOTERM
) {
934 c_len
= c_len
+ c_len_term
;
936 if (flags
& LIBNDR_FLAG_STR_BYTESIZE
) {
937 c_len
= c_len
* byte_mul
;
947 NTSTATUS
ndr_push_NTTIME(struct ndr_push
*ndr
, NTTIME t
)
949 NDR_CHECK(ndr_push_uint64(ndr
, t
));
956 NTSTATUS
ndr_pull_NTTIME(struct ndr_pull
*ndr
, NTTIME
*t
)
958 NDR_CHECK(ndr_pull_uint64(ndr
, t
));
965 NTSTATUS
ndr_push_NTTIME_1sec(struct ndr_push
*ndr
, NTTIME t
)
968 NDR_CHECK(ndr_push_HYPER_T(ndr
, t
));
975 NTSTATUS
ndr_pull_NTTIME_1sec(struct ndr_pull
*ndr
, NTTIME
*t
)
977 NDR_CHECK(ndr_pull_HYPER_T(ndr
, t
));
985 NTSTATUS
ndr_pull_NTTIME_hyper(struct ndr_pull
*ndr
, NTTIME_hyper
*t
)
987 NDR_CHECK(ndr_pull_HYPER_T(ndr
, t
));
994 NTSTATUS
ndr_push_NTTIME_hyper(struct ndr_push
*ndr
, NTTIME_hyper t
)
996 NDR_CHECK(ndr_push_HYPER_T(ndr
, t
));
1003 NTSTATUS
ndr_push_time_t(struct ndr_push
*ndr
, time_t t
)
1005 return ndr_push_uint32(ndr
, t
);
1011 NTSTATUS
ndr_pull_time_t(struct ndr_pull
*ndr
, time_t *t
)
1014 NDR_CHECK(ndr_pull_uint32(ndr
, &tt
));
1016 return NT_STATUS_OK
;
1020 void ndr_print_struct(struct ndr_print
*ndr
, const char *name
, const char *type
)
1022 ndr
->print(ndr
, "%s: struct %s", name
, type
);
1025 void ndr_print_enum(struct ndr_print
*ndr
, const char *name
, const char *type
,
1026 const char *val
, uint_t value
)
1028 if (ndr
->flags
& LIBNDR_PRINT_ARRAY_HEX
) {
1029 ndr
->print(ndr
, "%-25s: %s (0x%X)", name
, val
?val
:"UNKNOWN_ENUM_VALUE", value
);
1031 ndr
->print(ndr
, "%-25s: %s (%d)", name
, val
?val
:"UNKNOWN_ENUM_VALUE", value
);
1035 void ndr_print_bitmap_flag(struct ndr_print
*ndr
, size_t size
, const char *flag_name
, uint_t flag
, uint_t value
)
1037 /* this is an attempt to support multi-bit bitmap masks */
1040 while (!(flag
& 1)) {
1045 ndr
->print(ndr
, " %d: %-25s", value
, flag_name
);
1047 ndr
->print(ndr
, "0x%02x: %-25s (%d)", value
, flag_name
, value
);
1051 void ndr_print_uint8(struct ndr_print
*ndr
, const char *name
, uint8_t v
)
1053 ndr
->print(ndr
, "%-25s: 0x%02x (%u)", name
, v
, v
);
1056 void ndr_print_uint16(struct ndr_print
*ndr
, const char *name
, uint16_t v
)
1058 ndr
->print(ndr
, "%-25s: 0x%04x (%u)", name
, v
, v
);
1061 void ndr_print_uint32(struct ndr_print
*ndr
, const char *name
, uint32_t v
)
1063 ndr
->print(ndr
, "%-25s: 0x%08x (%u)", name
, v
, v
);
1066 void ndr_print_int32(struct ndr_print
*ndr
, const char *name
, int32_t v
)
1068 ndr
->print(ndr
, "%-25s: %d", name
, v
);
1071 void ndr_print_uint64(struct ndr_print
*ndr
, const char *name
, uint64_t v
)
1073 ndr
->print(ndr
, "%-25s: 0x%08x%08x (%llu)", name
,
1074 (uint32_t)(v
>> 32),
1075 (uint32_t)(v
& 0xFFFFFFFF),
1079 void ndr_print_int64(struct ndr_print
*ndr
, const char *name
, int64_t v
)
1081 ndr
->print(ndr
, "%-25s: 0x%08x%08x (%lld)", name
,
1082 (uint32_t)(v
>> 32),
1083 (uint32_t)(v
& 0xFFFFFFFF),
1087 void ndr_print_HYPER_T(struct ndr_print
*ndr
, const char *name
, HYPER_T v
)
1089 ndr
->print(ndr
, "%-25s: 0x%08x%08x", name
, (uint32_t)(v
>> 32), (uint32_t)(v
& 0xFFFFFFFF));
1092 void ndr_print_ptr(struct ndr_print
*ndr
, const char *name
, const void *p
)
1095 ndr
->print(ndr
, "%-25s: *", name
);
1097 ndr
->print(ndr
, "%-25s: NULL", name
);
1101 void ndr_print_string(struct ndr_print
*ndr
, const char *name
, const char *s
)
1104 ndr
->print(ndr
, "%-25s: '%s'", name
, s
);
1106 ndr
->print(ndr
, "%-25s: NULL", name
);
1110 void ndr_print_NTTIME(struct ndr_print
*ndr
, const char *name
, NTTIME t
)
1112 ndr
->print(ndr
, "%-25s: %s", name
, nt_time_string(ndr
, t
));
1115 void ndr_print_NTTIME_1sec(struct ndr_print
*ndr
, const char *name
, NTTIME_1sec t
)
1117 /* this is a standard NTTIME here
1118 * as it's already converted in the pull/push code
1120 ndr_print_NTTIME(ndr
, name
, t
);
1123 void ndr_print_NTTIME_hyper(struct ndr_print
*ndr
, const char *name
, NTTIME_hyper t
)
1125 ndr_print_NTTIME(ndr
, name
, t
);
1128 void ndr_print_time_t(struct ndr_print
*ndr
, const char *name
, time_t t
)
1130 if (t
== (time_t)-1 || t
== 0) {
1131 ndr
->print(ndr
, "%-25s: (time_t)%d", name
, (int)t
);
1133 ndr
->print(ndr
, "%-25s: %s", name
, timestring(ndr
, t
));
1137 void ndr_print_union(struct ndr_print
*ndr
, const char *name
, int level
, const char *type
)
1139 ndr
->print(ndr
, "%-25s: union %s(case %d)", name
, type
, level
);
1142 void ndr_print_bad_level(struct ndr_print
*ndr
, const char *name
, uint16_t level
)
1144 ndr
->print(ndr
, "UNKNOWN LEVEL %u", level
);
1147 void ndr_print_array_WERROR(struct ndr_print
*ndr
, const char *name
,
1148 const WERROR
*data
, uint32_t count
)
1152 ndr
->print(ndr
, "%s: ARRAY(%d)", name
, count
);
1154 for (i
=0;i
<count
;i
++) {
1156 asprintf(&idx
, "[%d]", i
);
1158 ndr_print_WERROR(ndr
, idx
, data
[i
]);
1165 void ndr_print_array_HYPER_T(struct ndr_print
*ndr
, const char *name
,
1166 const HYPER_T
*data
, uint32_t count
)
1170 ndr
->print(ndr
, "%s: ARRAY(%d)", name
, count
);
1172 for (i
=0;i
<count
;i
++) {
1174 asprintf(&idx
, "[%d]", i
);
1176 ndr_print_HYPER_T(ndr
, idx
, data
[i
]);
1183 void ndr_print_array_uint32(struct ndr_print
*ndr
, const char *name
,
1184 const uint32_t *data
, uint32_t count
)
1188 ndr
->print(ndr
, "%s: ARRAY(%d)", name
, count
);
1190 for (i
=0;i
<count
;i
++) {
1192 asprintf(&idx
, "[%d]", i
);
1194 ndr_print_uint32(ndr
, idx
, data
[i
]);
1201 void ndr_print_array_uint16(struct ndr_print
*ndr
, const char *name
,
1202 const uint16_t *data
, uint32_t count
)
1206 ndr
->print(ndr
, "%s: ARRAY(%d)", name
, count
);
1208 for (i
=0;i
<count
;i
++) {
1210 asprintf(&idx
, "[%d]", i
);
1212 ndr_print_uint16(ndr
, idx
, data
[i
]);
1219 void ndr_print_array_uint8(struct ndr_print
*ndr
, const char *name
,
1220 const uint8_t *data
, uint32_t count
)
1224 if (count
<= 600 && (ndr
->flags
& LIBNDR_PRINT_ARRAY_HEX
)) {
1226 for (i
=0;i
<count
;i
++) {
1227 snprintf(&s
[i
*2], 3, "%02x", data
[i
]);
1230 ndr
->print(ndr
, "%-25s: %s", name
, s
);
1234 ndr
->print(ndr
, "%s: ARRAY(%d)", name
, count
);
1236 for (i
=0;i
<count
;i
++) {
1238 asprintf(&idx
, "[%d]", i
);
1240 ndr_print_uint8(ndr
, idx
, data
[i
]);
1247 void ndr_print_DATA_BLOB(struct ndr_print
*ndr
, const char *name
, DATA_BLOB r
)
1249 ndr
->print(ndr
, "%-25s: DATA_BLOB length=%u", name
, r
.length
);
1251 dump_data(10, r
.data
, r
.length
);
1257 push a DATA_BLOB onto the wire.
1259 NTSTATUS
ndr_push_DATA_BLOB(struct ndr_push
*ndr
, DATA_BLOB blob
)
1261 if (ndr
->flags
& LIBNDR_ALIGN_FLAGS
) {
1262 if (ndr
->flags
& LIBNDR_FLAG_ALIGN2
) {
1263 blob
.length
= NDR_ALIGN(ndr
, 2);
1264 } else if (ndr
->flags
& LIBNDR_FLAG_ALIGN4
) {
1265 blob
.length
= NDR_ALIGN(ndr
, 4);
1266 } else if (ndr
->flags
& LIBNDR_FLAG_ALIGN8
) {
1267 blob
.length
= NDR_ALIGN(ndr
, 8);
1269 NDR_PUSH_ALLOC_SIZE(ndr
, blob
.data
, blob
.length
);
1270 data_blob_clear(&blob
);
1271 } else if (!(ndr
->flags
& LIBNDR_FLAG_REMAINING
)) {
1272 NDR_CHECK(ndr_push_uint32(ndr
, blob
.length
));
1274 NDR_CHECK(ndr_push_bytes(ndr
, blob
.data
, blob
.length
));
1275 return NT_STATUS_OK
;
1279 pull a DATA_BLOB from the wire.
1281 NTSTATUS
ndr_pull_DATA_BLOB(struct ndr_pull
*ndr
, DATA_BLOB
*blob
)
1285 if (ndr
->flags
& LIBNDR_ALIGN_FLAGS
) {
1286 if (ndr
->flags
& LIBNDR_FLAG_ALIGN2
) {
1287 length
= NDR_ALIGN(ndr
, 2);
1288 } else if (ndr
->flags
& LIBNDR_FLAG_ALIGN4
) {
1289 length
= NDR_ALIGN(ndr
, 4);
1290 } else if (ndr
->flags
& LIBNDR_FLAG_ALIGN8
) {
1291 length
= NDR_ALIGN(ndr
, 8);
1293 if (ndr
->data_size
- ndr
->offset
< length
) {
1294 length
= ndr
->data_size
- ndr
->offset
;
1296 } else if (ndr
->flags
& LIBNDR_FLAG_REMAINING
) {
1297 length
= ndr
->data_size
- ndr
->offset
;
1299 NDR_CHECK(ndr_pull_uint32(ndr
, &length
));
1301 NDR_PULL_NEED_BYTES(ndr
, length
);
1302 *blob
= data_blob_talloc(ndr
, ndr
->data
+ndr
->offset
, length
);
1303 ndr
->offset
+= length
;
1304 return NT_STATUS_OK
;
1307 uint32
ndr_size_DATA_BLOB(int ret
, const DATA_BLOB
*data
, int flags
)
1309 return ret
+ data
->length
;
1312 uint32
ndr_size_string(int ret
, const char * const* string
, int flags
)
1314 /* FIXME: Is this correct for all strings ? */
1315 if(!(*string
)) return ret
;
1316 return ret
+strlen(*string
)+1;