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_FIXLEN32
:
723 NDR_PULL_NEED_BYTES(ndr
, len1
*byte_mul
);
724 ret
= convert_string_talloc(ndr
, chset
, CH_UNIX
,
725 ndr
->data
+ndr
->offset
,
729 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
730 "Bad character conversion");
732 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
;
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_FIXLEN32
:
886 NDR_PUSH_NEED_BYTES(ndr
, byte_mul
*32);
887 ret
= convert_string(CH_UNIX
, chset
,
889 ndr
->data
+ndr
->offset
, byte_mul
*32);
891 return ndr_push_error(ndr
, NDR_ERR_CHARCNV
,
892 "Bad character conversion");
894 ndr
->offset
+= byte_mul
*32;
898 return ndr_push_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x\n",
899 ndr
->flags
& LIBNDR_STRING_FLAGS
);
906 push a general string onto the wire
908 size_t ndr_string_array_size(struct ndr_push
*ndr
, const char *s
)
911 unsigned flags
= ndr
->flags
;
912 unsigned byte_mul
= 2;
913 unsigned c_len_term
= 1;
915 if (flags
& LIBNDR_FLAG_STR_FIXLEN32
) {
919 c_len
= s
?strlen_m(s
):0;
921 if (flags
& (LIBNDR_FLAG_STR_ASCII
|LIBNDR_FLAG_STR_UTF8
)) {
925 if (flags
& LIBNDR_FLAG_STR_NOTERM
) {
929 c_len
= c_len
+ c_len_term
;
931 if (flags
& LIBNDR_FLAG_STR_BYTESIZE
) {
932 c_len
= c_len
* byte_mul
;
942 NTSTATUS
ndr_push_NTTIME(struct ndr_push
*ndr
, NTTIME t
)
944 NDR_CHECK(ndr_push_uint64(ndr
, t
));
951 NTSTATUS
ndr_pull_NTTIME(struct ndr_pull
*ndr
, NTTIME
*t
)
953 NDR_CHECK(ndr_pull_uint64(ndr
, t
));
960 NTSTATUS
ndr_push_NTTIME_1sec(struct ndr_push
*ndr
, NTTIME t
)
963 NDR_CHECK(ndr_push_HYPER_T(ndr
, t
));
970 NTSTATUS
ndr_pull_NTTIME_1sec(struct ndr_pull
*ndr
, NTTIME
*t
)
972 NDR_CHECK(ndr_pull_HYPER_T(ndr
, t
));
980 NTSTATUS
ndr_push_time_t(struct ndr_push
*ndr
, time_t t
)
982 return ndr_push_uint32(ndr
, t
);
988 NTSTATUS
ndr_pull_time_t(struct ndr_pull
*ndr
, time_t *t
)
991 NDR_CHECK(ndr_pull_uint32(ndr
, &tt
));
997 void ndr_print_struct(struct ndr_print
*ndr
, const char *name
, const char *type
)
999 ndr
->print(ndr
, "%s: struct %s", name
, type
);
1002 void ndr_print_enum(struct ndr_print
*ndr
, const char *name
, const char *type
,
1003 const char *val
, uint_t value
)
1005 if (ndr
->flags
& LIBNDR_PRINT_ARRAY_HEX
) {
1006 ndr
->print(ndr
, "%-25s: %s (0x%X)", name
, val
?val
:"UNKNOWN_ENUM_VALUE", value
);
1008 ndr
->print(ndr
, "%-25s: %s (%d)", name
, val
?val
:"UNKNOWN_ENUM_VALUE", value
);
1012 void ndr_print_bitmap_flag(struct ndr_print
*ndr
, size_t size
, const char *flag_name
, uint_t flag
, uint_t value
)
1014 /* size can be later used to print something like:
1015 * ...1.... .........: FLAG1_NAME
1016 * .....0.. .........: FLAG2_NAME
1018 ndr
->print(ndr
, "%s: %-25s", (flag
& value
)?"1":"0", flag_name
);
1021 void ndr_print_uint8(struct ndr_print
*ndr
, const char *name
, uint8_t v
)
1023 ndr
->print(ndr
, "%-25s: 0x%02x (%u)", name
, v
, v
);
1026 void ndr_print_uint16(struct ndr_print
*ndr
, const char *name
, uint16_t v
)
1028 ndr
->print(ndr
, "%-25s: 0x%04x (%u)", name
, v
, v
);
1031 void ndr_print_uint32(struct ndr_print
*ndr
, const char *name
, uint32_t v
)
1033 ndr
->print(ndr
, "%-25s: 0x%08x (%u)", name
, v
, v
);
1036 void ndr_print_int32(struct ndr_print
*ndr
, const char *name
, int32_t v
)
1038 ndr
->print(ndr
, "%-25s: %d", name
, v
);
1041 void ndr_print_uint64(struct ndr_print
*ndr
, const char *name
, uint64_t v
)
1043 ndr
->print(ndr
, "%-25s: 0x%08x%08x (%llu)", name
,
1044 (uint32_t)(v
>> 32),
1045 (uint32_t)(v
& 0xFFFFFFFF),
1049 void ndr_print_int64(struct ndr_print
*ndr
, const char *name
, int64_t v
)
1051 ndr
->print(ndr
, "%-25s: 0x%08x%08x (%lld)", name
,
1052 (uint32_t)(v
>> 32),
1053 (uint32_t)(v
& 0xFFFFFFFF),
1057 void ndr_print_HYPER_T(struct ndr_print
*ndr
, const char *name
, HYPER_T v
)
1059 ndr
->print(ndr
, "%-25s: 0x%08x%08x", name
, (uint32_t)(v
>> 32), (uint32_t)(v
& 0xFFFFFFFF));
1062 void ndr_print_ptr(struct ndr_print
*ndr
, const char *name
, const void *p
)
1065 ndr
->print(ndr
, "%-25s: *", name
);
1067 ndr
->print(ndr
, "%-25s: NULL", name
);
1071 void ndr_print_string(struct ndr_print
*ndr
, const char *name
, const char *s
)
1074 ndr
->print(ndr
, "%-25s: '%s'", name
, s
);
1076 ndr
->print(ndr
, "%-25s: NULL", name
);
1080 void ndr_print_NTTIME(struct ndr_print
*ndr
, const char *name
, NTTIME t
)
1082 ndr
->print(ndr
, "%-25s: %s", name
, nt_time_string(ndr
, t
));
1085 void ndr_print_NTTIME_1sec(struct ndr_print
*ndr
, const char *name
, NTTIME t
)
1087 ndr_print_NTTIME(ndr
, name
, t
);
1090 void ndr_print_time_t(struct ndr_print
*ndr
, const char *name
, time_t t
)
1092 if (t
== (time_t)-1 || t
== 0) {
1093 ndr
->print(ndr
, "%-25s: (time_t)%d", name
, (int)t
);
1095 ndr
->print(ndr
, "%-25s: %s", name
, timestring(ndr
, t
));
1099 void ndr_print_union(struct ndr_print
*ndr
, const char *name
, int level
, const char *type
)
1101 ndr
->print(ndr
, "%-25s: union %s(case %d)", name
, type
, level
);
1104 void ndr_print_bad_level(struct ndr_print
*ndr
, const char *name
, uint16_t level
)
1106 ndr
->print(ndr
, "UNKNOWN LEVEL %u", level
);
1109 void ndr_print_array_WERROR(struct ndr_print
*ndr
, const char *name
,
1110 const WERROR
*data
, uint32_t count
)
1114 ndr
->print(ndr
, "%s: ARRAY(%d)", name
, count
);
1116 for (i
=0;i
<count
;i
++) {
1118 asprintf(&idx
, "[%d]", i
);
1120 ndr_print_WERROR(ndr
, idx
, data
[i
]);
1127 void ndr_print_array_HYPER_T(struct ndr_print
*ndr
, const char *name
,
1128 const HYPER_T
*data
, uint32_t count
)
1132 ndr
->print(ndr
, "%s: ARRAY(%d)", name
, count
);
1134 for (i
=0;i
<count
;i
++) {
1136 asprintf(&idx
, "[%d]", i
);
1138 ndr_print_HYPER_T(ndr
, idx
, data
[i
]);
1145 void ndr_print_array_uint32(struct ndr_print
*ndr
, const char *name
,
1146 const uint32_t *data
, uint32_t count
)
1150 ndr
->print(ndr
, "%s: ARRAY(%d)", name
, count
);
1152 for (i
=0;i
<count
;i
++) {
1154 asprintf(&idx
, "[%d]", i
);
1156 ndr_print_uint32(ndr
, idx
, data
[i
]);
1163 void ndr_print_array_uint16(struct ndr_print
*ndr
, const char *name
,
1164 const uint16_t *data
, uint32_t count
)
1168 ndr
->print(ndr
, "%s: ARRAY(%d)", name
, count
);
1170 for (i
=0;i
<count
;i
++) {
1172 asprintf(&idx
, "[%d]", i
);
1174 ndr_print_uint16(ndr
, idx
, data
[i
]);
1181 void ndr_print_array_uint8(struct ndr_print
*ndr
, const char *name
,
1182 const uint8_t *data
, uint32_t count
)
1186 if (count
<= 600 && (ndr
->flags
& LIBNDR_PRINT_ARRAY_HEX
)) {
1188 for (i
=0;i
<count
;i
++) {
1189 snprintf(&s
[i
*2], 3, "%02x", data
[i
]);
1192 ndr
->print(ndr
, "%-25s: %s", name
, s
);
1196 ndr
->print(ndr
, "%s: ARRAY(%d)", name
, count
);
1198 for (i
=0;i
<count
;i
++) {
1200 asprintf(&idx
, "[%d]", i
);
1202 ndr_print_uint8(ndr
, idx
, data
[i
]);
1209 void ndr_print_DATA_BLOB(struct ndr_print
*ndr
, const char *name
, DATA_BLOB r
)
1211 ndr
->print(ndr
, "%-25s: DATA_BLOB length=%u", name
, r
.length
);
1213 dump_data(10, r
.data
, r
.length
);
1219 push a DATA_BLOB onto the wire.
1221 NTSTATUS
ndr_push_DATA_BLOB(struct ndr_push
*ndr
, DATA_BLOB blob
)
1223 if (ndr
->flags
& LIBNDR_ALIGN_FLAGS
) {
1224 if (ndr
->flags
& LIBNDR_FLAG_ALIGN2
) {
1225 blob
.length
= NDR_ALIGN(ndr
, 2);
1226 } else if (ndr
->flags
& LIBNDR_FLAG_ALIGN4
) {
1227 blob
.length
= NDR_ALIGN(ndr
, 4);
1228 } else if (ndr
->flags
& LIBNDR_FLAG_ALIGN8
) {
1229 blob
.length
= NDR_ALIGN(ndr
, 8);
1231 NDR_PUSH_ALLOC_SIZE(ndr
, blob
.data
, blob
.length
);
1232 data_blob_clear(&blob
);
1233 } else if (!(ndr
->flags
& LIBNDR_FLAG_REMAINING
)) {
1234 NDR_CHECK(ndr_push_uint32(ndr
, blob
.length
));
1236 NDR_CHECK(ndr_push_bytes(ndr
, blob
.data
, blob
.length
));
1237 return NT_STATUS_OK
;
1241 pull a DATA_BLOB from the wire.
1243 NTSTATUS
ndr_pull_DATA_BLOB(struct ndr_pull
*ndr
, DATA_BLOB
*blob
)
1247 if (ndr
->flags
& LIBNDR_ALIGN_FLAGS
) {
1248 if (ndr
->flags
& LIBNDR_FLAG_ALIGN2
) {
1249 length
= NDR_ALIGN(ndr
, 2);
1250 } else if (ndr
->flags
& LIBNDR_FLAG_ALIGN4
) {
1251 length
= NDR_ALIGN(ndr
, 4);
1252 } else if (ndr
->flags
& LIBNDR_FLAG_ALIGN8
) {
1253 length
= NDR_ALIGN(ndr
, 8);
1255 if (ndr
->data_size
- ndr
->offset
< length
) {
1256 length
= ndr
->data_size
- ndr
->offset
;
1258 } else if (ndr
->flags
& LIBNDR_FLAG_REMAINING
) {
1259 length
= ndr
->data_size
- ndr
->offset
;
1261 NDR_CHECK(ndr_pull_uint32(ndr
, &length
));
1263 NDR_PULL_NEED_BYTES(ndr
, length
);
1264 *blob
= data_blob_talloc(ndr
, ndr
->data
+ndr
->offset
, length
);
1265 ndr
->offset
+= length
;
1266 return NT_STATUS_OK
;
1269 uint32
ndr_size_DATA_BLOB(int ret
, const DATA_BLOB
*data
, int flags
)
1271 return ret
+ data
->length
;
1274 uint32
ndr_size_string(int ret
, const char * const* string
, int flags
)
1276 /* FIXME: Is this correct for all strings ? */
1277 if(!(*string
)) return ret
;
1278 return ret
+strlen(*string
)+1;