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_SSVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSSVAL(ndr->data,ofs,v); } else SSVAL(ndr->data,ofs,v); } while (0)
29 #define NDR_SIVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVAL(ndr->data,ofs,v); } else SIVAL(ndr->data,ofs,v); } while (0)
34 NTSTATUS ndr_pull_uint8(struct ndr_pull *ndr, uint8 *v)
36 NDR_PULL_NEED_BYTES(ndr, 1);
37 *v = CVAL(ndr->data, ndr->offset);
46 NTSTATUS ndr_pull_uint16(struct ndr_pull *ndr, uint16 *v)
48 NDR_PULL_ALIGN(ndr, 2);
49 NDR_PULL_NEED_BYTES(ndr, 2);
50 *v = NDR_SVAL(ndr, ndr->offset);
59 NTSTATUS ndr_pull_uint32(struct ndr_pull *ndr, uint32 *v)
61 NDR_PULL_ALIGN(ndr, 4);
62 NDR_PULL_NEED_BYTES(ndr, 4);
63 *v = NDR_IVAL(ndr, ndr->offset);
71 NTSTATUS ndr_pull_HYPER_T(struct ndr_pull *ndr, HYPER_T *v)
73 NDR_PULL_ALIGN(ndr, 8);
74 NDR_PULL_NEED_BYTES(ndr, 8);
75 v->low = NDR_IVAL(ndr, ndr->offset);
76 v->high = NDR_IVAL(ndr, ndr->offset+4);
84 NTSTATUS ndr_pull_NTSTATUS(struct ndr_pull *ndr, NTSTATUS *status)
87 NDR_CHECK(ndr_pull_uint32(ndr, &v));
88 *status = NT_STATUS(v);
95 NTSTATUS ndr_push_NTSTATUS(struct ndr_push *ndr, NTSTATUS status)
97 return ndr_push_uint32(ndr, NT_STATUS_V(status));
100 void ndr_print_NTSTATUS(struct ndr_print *ndr, const char *name, NTSTATUS *r)
102 ndr->print(ndr, "%-25s: %s", name, nt_errstr(*r));
108 NTSTATUS ndr_pull_WERROR(struct ndr_pull *ndr, WERROR *status)
111 NDR_CHECK(ndr_pull_uint32(ndr, &v));
112 *status = W_ERROR(v);
119 NTSTATUS ndr_push_WERROR(struct ndr_push *ndr, WERROR status)
121 return ndr_push_uint32(ndr, W_ERROR_V(status));
124 void ndr_print_WERROR(struct ndr_print *ndr, const char *name, WERROR *r)
126 ndr->print(ndr, "%-25s: %s", name, win_errstr(*r));
132 NTSTATUS ndr_pull_bytes(struct ndr_pull *ndr, char *data, uint32 n)
134 NDR_PULL_NEED_BYTES(ndr, n);
135 memcpy(data, ndr->data + ndr->offset, n);
141 pull an array of uint8
143 NTSTATUS ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, char *data, uint32 n)
145 if (!(ndr_flags & NDR_SCALARS)) {
148 return ndr_pull_bytes(ndr, data, n);
153 pull an array of uint16
155 NTSTATUS ndr_pull_array_uint16(struct ndr_pull *ndr, int ndr_flags, uint16 *data, uint32 n)
158 if (!(ndr_flags & NDR_SCALARS)) {
162 NDR_CHECK(ndr_pull_uint16(ndr, &data[i]));
168 pull a const array of uint32
170 NTSTATUS ndr_pull_array_uint32(struct ndr_pull *ndr, int ndr_flags, uint32 *data, uint32 n)
173 if (!(ndr_flags & NDR_SCALARS)) {
177 NDR_CHECK(ndr_pull_uint32(ndr, &data[i]));
185 NTSTATUS ndr_push_uint8(struct ndr_push *ndr, uint8 v)
187 NDR_PUSH_NEED_BYTES(ndr, 1);
188 SCVAL(ndr->data, ndr->offset, v);
196 NTSTATUS ndr_push_uint16(struct ndr_push *ndr, uint16 v)
198 NDR_PUSH_ALIGN(ndr, 2);
199 NDR_PUSH_NEED_BYTES(ndr, 2);
200 NDR_SSVAL(ndr, ndr->offset, v);
208 NTSTATUS ndr_push_uint32(struct ndr_push *ndr, uint32 v)
210 NDR_PUSH_ALIGN(ndr, 4);
211 NDR_PUSH_NEED_BYTES(ndr, 4);
212 NDR_SIVAL(ndr, ndr->offset, v);
220 NTSTATUS ndr_push_HYPER_T(struct ndr_push *ndr, HYPER_T v)
222 NDR_PUSH_ALIGN(ndr, 8);
223 NDR_PUSH_NEED_BYTES(ndr, 8);
224 NDR_SIVAL(ndr, ndr->offset, v.low);
225 NDR_SIVAL(ndr, ndr->offset+4, v.high);
230 NTSTATUS ndr_push_align(struct ndr_push *ndr, size_t size)
232 NDR_PUSH_ALIGN(ndr, size);
236 NTSTATUS ndr_pull_align(struct ndr_pull *ndr, size_t size)
238 NDR_PULL_ALIGN(ndr, size);
245 NTSTATUS ndr_push_bytes(struct ndr_push *ndr, const char *data, uint32 n)
247 NDR_PUSH_NEED_BYTES(ndr, n);
248 memcpy(ndr->data + ndr->offset, data, n);
256 NTSTATUS ndr_push_zero(struct ndr_push *ndr, uint32 n)
258 NDR_PUSH_NEED_BYTES(ndr, n);
259 memset(ndr->data + ndr->offset, 0, n);
265 push an array of uint8
267 NTSTATUS ndr_push_array_uint8(struct ndr_push *ndr, int ndr_flags, const char *data, uint32 n)
269 if (!(ndr_flags & NDR_SCALARS)) {
272 return ndr_push_bytes(ndr, data, n);
276 push an array of uint16
278 NTSTATUS ndr_push_array_uint16(struct ndr_push *ndr, int ndr_flags, const uint16 *data, uint32 n)
281 if (!(ndr_flags & NDR_SCALARS)) {
285 NDR_CHECK(ndr_push_uint16(ndr, data[i]));
291 push an array of uint32
293 NTSTATUS ndr_push_array_uint32(struct ndr_push *ndr, int ndr_flags, const uint32 *data, uint32 n)
296 if (!(ndr_flags & NDR_SCALARS)) {
300 NDR_CHECK(ndr_push_uint32(ndr, data[i]));
306 save the current position
308 void ndr_push_save(struct ndr_push *ndr, struct ndr_push_save *save)
310 save->offset = ndr->offset;
316 void ndr_push_restore(struct ndr_push *ndr, struct ndr_push_save *save)
318 ndr->offset = save->offset;
322 push a 1 if a pointer is non-NULL, otherwise 0
324 NTSTATUS ndr_push_ptr(struct ndr_push *ndr, const void *p)
328 /* we do this to ensure that we generate unique ref ids,
329 which means we can handle the case where a MS programmer
330 forgot to mark a pointer as unique */
332 ptr = ndr->ptr_count;
334 return ndr_push_uint32(ndr, ptr);
339 pull a general string from the wire
341 NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
344 uint32 len1, ofs, len2;
349 if (!(ndr_flags & NDR_SCALARS)) {
357 switch (ndr->flags & LIBNDR_STRING_FLAGS) {
358 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
359 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
360 NDR_CHECK(ndr_pull_uint32(ndr, &len1));
361 NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
362 NDR_CHECK(ndr_pull_uint32(ndr, &len2));
364 return ndr_pull_error(ndr, NDR_ERR_STRING,
365 "Bad string lengths len1=%u ofs=%u len2=%u\n",
369 *s = talloc_strdup(ndr->mem_ctx, "");
372 NDR_PULL_NEED_BYTES(ndr, len2*2);
373 ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX,
374 ndr->data+ndr->offset,
378 return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
379 "Bad character conversion");
381 NDR_CHECK(ndr_pull_advance(ndr, len2*2));
385 case LIBNDR_FLAG_STR_SIZE4:
386 NDR_CHECK(ndr_pull_uint32(ndr, &len1));
387 NDR_PULL_NEED_BYTES(ndr, len1*2);
389 *s = talloc_strdup(ndr->mem_ctx, "");
392 ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX,
393 ndr->data+ndr->offset,
397 return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
398 "Bad character conversion");
400 NDR_CHECK(ndr_pull_advance(ndr, len1*2));
404 case LIBNDR_FLAG_STR_NULLTERM:
405 len1 = strnlen_w(ndr->data+ndr->offset,
406 (ndr->data_size - ndr->offset)/2);
407 if (len1*2+2 <= ndr->data_size - ndr->offset) {
410 ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX,
411 ndr->data+ndr->offset,
415 return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
416 "Bad character conversion");
418 NDR_CHECK(ndr_pull_advance(ndr, len1*2));
421 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
422 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
423 NDR_CHECK(ndr_pull_uint32(ndr, &len1));
424 NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
425 NDR_CHECK(ndr_pull_uint32(ndr, &len2));
427 return ndr_pull_error(ndr, NDR_ERR_STRING,
428 "Bad ascii string lengths len1=%u ofs=%u len2=%u\n",
431 NDR_ALLOC_N(ndr, as, (len2+1));
432 NDR_CHECK(ndr_pull_bytes(ndr, as, len2));
437 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4:
438 NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
439 NDR_CHECK(ndr_pull_uint32(ndr, &len2));
440 NDR_ALLOC_N(ndr, as, (len2+1));
441 NDR_CHECK(ndr_pull_bytes(ndr, as, len2));
446 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2:
447 NDR_CHECK(ndr_pull_uint16(ndr, &len3));
448 NDR_ALLOC_N(ndr, as, (len3+1));
449 NDR_CHECK(ndr_pull_bytes(ndr, as, len3));
455 return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
456 ndr->flags & LIBNDR_STRING_FLAGS);
464 push a general string onto the wire
466 NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
468 ssize_t s_len, c_len;
472 if (!(ndr_flags & NDR_SCALARS)) {
480 s_len = s?strlen(s):0;
481 c_len = s?strlen_m(s):0;
483 switch (ndr->flags & LIBNDR_STRING_FLAGS) {
484 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
485 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
486 NDR_CHECK(ndr_push_uint32(ndr, 0));
487 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
488 NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
489 ret = convert_string(CH_UNIX, chset,
491 ndr->data+ndr->offset, c_len*2 + 2);
493 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
494 "Bad character conversion");
496 ndr->offset += c_len*2 + 2;
499 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
500 NDR_CHECK(ndr_push_uint32(ndr, c_len));
501 NDR_CHECK(ndr_push_uint32(ndr, 0));
502 NDR_CHECK(ndr_push_uint32(ndr, c_len));
503 NDR_PUSH_NEED_BYTES(ndr, c_len*2);
504 ret = convert_string(CH_UNIX, chset,
506 ndr->data+ndr->offset, c_len*2);
508 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
509 "Bad character conversion");
511 ndr->offset += c_len*2;
514 case LIBNDR_FLAG_STR_SIZE4:
515 NDR_CHECK(ndr_push_uint32(ndr, c_len + 1));
516 NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
517 ret = convert_string(CH_UNIX, chset,
519 ndr->data+ndr->offset, c_len*2 + 2);
521 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
522 "Bad character conversion");
524 ndr->offset += c_len*2 + 2;
527 case LIBNDR_FLAG_STR_NULLTERM:
528 NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
529 ret = convert_string(CH_UNIX, chset,
531 ndr->data+ndr->offset, c_len*2 + 2);
533 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
534 "Bad character conversion");
536 ndr->offset += c_len*2 + 2;
539 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
540 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
541 NDR_CHECK(ndr_push_uint32(ndr, 0));
542 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
543 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
544 ret = convert_string(CH_UNIX, CH_DOS,
546 ndr->data+ndr->offset, c_len + 1);
548 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
549 "Bad character conversion");
551 ndr->offset += c_len + 1;
554 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
555 NDR_CHECK(ndr_push_uint32(ndr, c_len));
556 NDR_CHECK(ndr_push_uint32(ndr, 0));
557 NDR_CHECK(ndr_push_uint32(ndr, c_len));
558 NDR_PUSH_NEED_BYTES(ndr, c_len);
559 ret = convert_string(CH_UNIX, CH_DOS,
561 ndr->data+ndr->offset, c_len);
563 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
564 "Bad character conversion");
566 ndr->offset += c_len;
569 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4:
570 NDR_CHECK(ndr_push_uint32(ndr, 0));
571 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
572 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
573 ret = convert_string(CH_UNIX, CH_DOS,
575 ndr->data+ndr->offset, c_len + 1);
577 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
578 "Bad character conversion");
580 ndr->offset += c_len + 1;
583 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2:
584 NDR_CHECK(ndr_push_uint16(ndr, c_len+1));
585 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
586 ret = convert_string(CH_UNIX, CH_DOS,
588 ndr->data+ndr->offset, c_len + 1);
590 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
591 "Bad character conversion");
593 ndr->offset += c_len + 1;
597 return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
598 ndr->flags & LIBNDR_STRING_FLAGS);
607 NTSTATUS ndr_push_NTTIME(struct ndr_push *ndr, NTTIME t)
609 NDR_CHECK(ndr_push_uint32(ndr, t.low));
610 NDR_CHECK(ndr_push_uint32(ndr, t.high));
617 NTSTATUS ndr_pull_NTTIME(struct ndr_pull *ndr, NTTIME *t)
619 NDR_CHECK(ndr_pull_uint32(ndr, &t->low));
620 NDR_CHECK(ndr_pull_uint32(ndr, &t->high));
627 NTSTATUS ndr_push_time_t(struct ndr_push *ndr, time_t t)
629 return ndr_push_uint32(ndr, t);
635 NTSTATUS ndr_pull_time_t(struct ndr_pull *ndr, time_t *t)
638 NDR_CHECK(ndr_pull_uint32(ndr, &tt));
644 void ndr_print_struct(struct ndr_print *ndr, const char *name, const char *type)
646 ndr->print(ndr, "%s: struct %s", name, type);
649 void ndr_print_uint8(struct ndr_print *ndr, const char *name, uint8 v)
651 ndr->print(ndr, "%-25s: 0x%02x (%u)", name, v, v);
654 void ndr_print_uint16(struct ndr_print *ndr, const char *name, uint16 v)
656 ndr->print(ndr, "%-25s: 0x%04x (%u)", name, v, v);
659 void ndr_print_uint32(struct ndr_print *ndr, const char *name, uint32 v)
661 ndr->print(ndr, "%-25s: 0x%08x (%u)", name, v, v);
664 void ndr_print_HYPER_T(struct ndr_print *ndr, const char *name, HYPER_T v)
666 ndr->print(ndr, "%-25s: 0x%08x%08x", name, v.high, v.low);
669 void ndr_print_ptr(struct ndr_print *ndr, const char *name, const void *p)
672 ndr->print(ndr, "%-25s: *", name);
674 ndr->print(ndr, "%-25s: NULL", name);
678 void ndr_print_string(struct ndr_print *ndr, const char *name, const char *s)
681 ndr->print(ndr, "%-25s: '%s'", name, s);
683 ndr->print(ndr, "%-25s: NULL", name);
687 void ndr_print_NTTIME(struct ndr_print *ndr, const char *name, NTTIME t)
689 ndr->print(ndr, "%-25s: %s", name, nt_time_string(ndr->mem_ctx, &t));
692 void ndr_print_time_t(struct ndr_print *ndr, const char *name, time_t t)
694 if (t == (time_t)-1 || t == 0) {
695 ndr->print(ndr, "%-25s: (time_t)%d", name, (int)t);
697 ndr->print(ndr, "%-25s: %s", name, timestring(ndr->mem_ctx, t));
701 void ndr_print_union(struct ndr_print *ndr, const char *name, uint16 level, const char *type)
703 ndr->print(ndr, "%-25s: union %s(case %u)", name, type, level);
706 void ndr_print_bad_level(struct ndr_print *ndr, const char *name, uint16 level)
708 ndr->print(ndr, "UNKNOWN LEVEL %u", level);
711 void ndr_print_array_uint32(struct ndr_print *ndr, const char *name,
712 const uint32 *data, uint32 count)
716 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
718 for (i=0;i<count;i++) {
720 asprintf(&idx, "[%d]", i);
722 ndr_print_uint32(ndr, idx, data[i]);
729 void ndr_print_array_uint16(struct ndr_print *ndr, const char *name,
730 const uint16 *data, uint32 count)
734 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
736 for (i=0;i<count;i++) {
738 asprintf(&idx, "[%d]", i);
740 ndr_print_uint16(ndr, idx, data[i]);
747 void ndr_print_array_uint8(struct ndr_print *ndr, const char *name,
748 const uint8 *data, uint32 count)
752 if (count <= 600 && (ndr->flags & LIBNDR_PRINT_ARRAY_HEX)) {
754 for (i=0;i<count;i++) {
755 snprintf(&s[i*2], 3, "%02x", data[i]);
758 ndr->print(ndr, "%-25s: %s", name, s);
762 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
764 for (i=0;i<count;i++) {
766 asprintf(&idx, "[%d]", i);
768 ndr_print_uint8(ndr, idx, data[i]);
776 build a GUID from a string
778 NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
781 uint32 time_mid, time_hi_and_version;
786 if (11 != sscanf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
787 &time_low, &time_mid, &time_hi_and_version,
788 &clock_seq[0], &clock_seq[1],
789 &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
790 return NT_STATUS_INVALID_PARAMETER;
793 guid->time_low = time_low;
794 guid->time_mid = time_mid;
795 guid->time_hi_and_version = time_hi_and_version;
796 guid->clock_seq[0] = clock_seq[0];
797 guid->clock_seq[1] = clock_seq[1];
799 guid->node[i] = node[i];
806 its useful to be able to display these in debugging messages
808 const char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
810 return talloc_asprintf(mem_ctx,
811 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
812 guid->time_low, guid->time_mid,
813 guid->time_hi_and_version,
816 guid->node[0], guid->node[1],
817 guid->node[2], guid->node[3],
818 guid->node[4], guid->node[5]);
821 void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid)
823 ndr->print(ndr, "%-25s: %s", name, GUID_string(ndr->mem_ctx, guid));
826 void ndr_print_DATA_BLOB(struct ndr_print *ndr, const char *name, DATA_BLOB r)
828 ndr->print(ndr, "%-25s: DATA_BLOB length=%u", name, r.length);
830 dump_data(10, r.data, r.length);
836 push a DATA_BLOB onto the wire.
838 NTSTATUS ndr_push_DATA_BLOB(struct ndr_push *ndr, DATA_BLOB blob)
840 if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
841 if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
842 blob.length = NDR_ALIGN(ndr, 2);
843 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
844 blob.length = NDR_ALIGN(ndr, 4);
845 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
846 blob.length = NDR_ALIGN(ndr, 8);
848 NDR_PUSH_ALLOC_SIZE(ndr, blob.data, blob.length);
849 data_blob_clear(&blob);
850 } else if (!(ndr->flags & LIBNDR_FLAG_REMAINING)) {
851 NDR_CHECK(ndr_push_uint32(ndr, blob.length));
853 NDR_CHECK(ndr_push_bytes(ndr, blob.data, blob.length));
858 pull a DATA_BLOB from the wire.
860 NTSTATUS ndr_pull_DATA_BLOB(struct ndr_pull *ndr, DATA_BLOB *blob)
864 if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
865 if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
866 length = NDR_ALIGN(ndr, 2);
867 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
868 length = NDR_ALIGN(ndr, 4);
869 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
870 length = NDR_ALIGN(ndr, 8);
872 if (ndr->data_size - ndr->offset < length) {
873 length = ndr->data_size - ndr->offset;
875 } else if (ndr->flags & LIBNDR_FLAG_REMAINING) {
876 length = ndr->data_size - ndr->offset;
878 NDR_CHECK(ndr_pull_uint32(ndr, &length));
880 NDR_PULL_NEED_BYTES(ndr, length);
881 *blob = data_blob_talloc(ndr->mem_ctx, ndr->data+ndr->offset, length);
882 ndr->offset += length;