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)
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)) {
353 if (ndr->flags & LIBNDR_FLAG_BIGENDIAN) {
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 NDR_CHECK(ndr_pull_uint32(ndr, &len1));
423 NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
424 NDR_CHECK(ndr_pull_uint32(ndr, &len2));
426 return ndr_pull_error(ndr, NDR_ERR_STRING,
427 "Bad ascii string lengths len1=%u ofs=%u len2=%u\n",
430 NDR_ALLOC_N(ndr, as, (len2+1));
431 NDR_CHECK(ndr_pull_bytes(ndr, as, len2));
436 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4:
437 NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
438 NDR_CHECK(ndr_pull_uint32(ndr, &len2));
439 NDR_ALLOC_N(ndr, as, (len2+1));
440 NDR_CHECK(ndr_pull_bytes(ndr, as, len2));
445 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2:
446 NDR_CHECK(ndr_pull_uint16(ndr, &len3));
447 NDR_ALLOC_N(ndr, as, (len3+1));
448 NDR_CHECK(ndr_pull_bytes(ndr, as, len3));
454 return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
455 ndr->flags & LIBNDR_STRING_FLAGS);
463 push a general string onto the wire
465 NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
467 ssize_t s_len, c_len;
471 if (!(ndr_flags & NDR_SCALARS)) {
475 if (ndr->flags & LIBNDR_FLAG_BIGENDIAN) {
479 s_len = s?strlen(s):0;
480 c_len = s?strlen_m(s):0;
482 switch (ndr->flags & LIBNDR_STRING_FLAGS) {
483 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
484 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
485 NDR_CHECK(ndr_push_uint32(ndr, 0));
486 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
487 NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
488 ret = convert_string(CH_UNIX, chset,
490 ndr->data+ndr->offset, c_len*2 + 2);
492 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
493 "Bad character conversion");
495 ndr->offset += c_len*2 + 2;
498 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
499 NDR_CHECK(ndr_push_uint32(ndr, c_len));
500 NDR_CHECK(ndr_push_uint32(ndr, 0));
501 NDR_CHECK(ndr_push_uint32(ndr, c_len));
502 NDR_PUSH_NEED_BYTES(ndr, c_len*2);
503 ret = convert_string(CH_UNIX, chset,
505 ndr->data+ndr->offset, c_len*2);
507 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
508 "Bad character conversion");
510 ndr->offset += c_len*2;
513 case LIBNDR_FLAG_STR_SIZE4:
514 NDR_CHECK(ndr_push_uint32(ndr, c_len + 1));
515 NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
516 ret = convert_string(CH_UNIX, chset,
518 ndr->data+ndr->offset, c_len*2 + 2);
520 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
521 "Bad character conversion");
523 ndr->offset += c_len*2 + 2;
526 case LIBNDR_FLAG_STR_NULLTERM:
527 NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
528 ret = convert_string(CH_UNIX, chset,
530 ndr->data+ndr->offset, c_len*2 + 2);
532 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
533 "Bad character conversion");
535 ndr->offset += c_len*2 + 2;
538 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
539 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
540 NDR_CHECK(ndr_push_uint32(ndr, 0));
541 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
542 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
543 ret = convert_string(CH_UNIX, CH_DOS,
545 ndr->data+ndr->offset, c_len + 1);
547 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
548 "Bad character conversion");
550 ndr->offset += c_len + 1;
553 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4:
554 NDR_CHECK(ndr_push_uint32(ndr, 0));
555 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
556 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
557 ret = convert_string(CH_UNIX, CH_DOS,
559 ndr->data+ndr->offset, c_len + 1);
561 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
562 "Bad character conversion");
564 ndr->offset += c_len + 1;
567 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2:
568 NDR_CHECK(ndr_push_uint16(ndr, c_len+1));
569 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
570 ret = convert_string(CH_UNIX, CH_DOS,
572 ndr->data+ndr->offset, c_len + 1);
574 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
575 "Bad character conversion");
577 ndr->offset += c_len + 1;
581 return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
582 ndr->flags & LIBNDR_STRING_FLAGS);
591 NTSTATUS ndr_push_NTTIME(struct ndr_push *ndr, NTTIME t)
593 NDR_CHECK(ndr_push_uint32(ndr, t.low));
594 NDR_CHECK(ndr_push_uint32(ndr, t.high));
601 NTSTATUS ndr_pull_NTTIME(struct ndr_pull *ndr, NTTIME *t)
603 NDR_CHECK(ndr_pull_uint32(ndr, &t->low));
604 NDR_CHECK(ndr_pull_uint32(ndr, &t->high));
611 NTSTATUS ndr_push_time_t(struct ndr_push *ndr, time_t t)
613 return ndr_push_uint32(ndr, t);
619 NTSTATUS ndr_pull_time_t(struct ndr_pull *ndr, time_t *t)
622 NDR_CHECK(ndr_pull_uint32(ndr, &tt));
628 void ndr_print_struct(struct ndr_print *ndr, const char *name, const char *type)
630 ndr->print(ndr, "%s: struct %s", name, type);
633 void ndr_print_uint8(struct ndr_print *ndr, const char *name, uint8 v)
635 ndr->print(ndr, "%-25s: 0x%02x (%u)", name, v, v);
638 void ndr_print_uint16(struct ndr_print *ndr, const char *name, uint16 v)
640 ndr->print(ndr, "%-25s: 0x%04x (%u)", name, v, v);
643 void ndr_print_uint32(struct ndr_print *ndr, const char *name, uint32 v)
645 ndr->print(ndr, "%-25s: 0x%08x (%u)", name, v, v);
648 void ndr_print_HYPER_T(struct ndr_print *ndr, const char *name, HYPER_T v)
650 ndr->print(ndr, "%-25s: 0x%08x%08x", name, v.high, v.low);
653 void ndr_print_ptr(struct ndr_print *ndr, const char *name, const void *p)
656 ndr->print(ndr, "%-25s: *", name);
658 ndr->print(ndr, "%-25s: NULL", name);
662 void ndr_print_string(struct ndr_print *ndr, const char *name, const char *s)
665 ndr->print(ndr, "%-25s: '%s'", name, s);
667 ndr->print(ndr, "%-25s: NULL", name);
671 void ndr_print_NTTIME(struct ndr_print *ndr, const char *name, NTTIME t)
673 ndr->print(ndr, "%-25s: %s", name, nt_time_string(ndr->mem_ctx, &t));
676 void ndr_print_time_t(struct ndr_print *ndr, const char *name, time_t t)
678 if (t == (time_t)-1 || t == 0) {
679 ndr->print(ndr, "%-25s: (time_t)%d", name, (int)t);
681 ndr->print(ndr, "%-25s: %s", name, http_timestring(ndr->mem_ctx, t));
685 void ndr_print_union(struct ndr_print *ndr, const char *name, uint16 level, const char *type)
687 ndr->print(ndr, "%-25s: union %s(case %u)", name, type, level);
690 void ndr_print_bad_level(struct ndr_print *ndr, const char *name, uint16 level)
692 ndr->print(ndr, "UNKNOWN LEVEL %u", level);
695 void ndr_print_array_uint32(struct ndr_print *ndr, const char *name,
696 const uint32 *data, uint32 count)
700 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
702 for (i=0;i<count;i++) {
704 asprintf(&idx, "[%d]", i);
706 ndr_print_uint32(ndr, idx, data[i]);
713 void ndr_print_array_uint16(struct ndr_print *ndr, const char *name,
714 const uint16 *data, uint32 count)
718 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
720 for (i=0;i<count;i++) {
722 asprintf(&idx, "[%d]", i);
724 ndr_print_uint16(ndr, idx, data[i]);
731 void ndr_print_array_uint8(struct ndr_print *ndr, const char *name,
732 const uint8 *data, uint32 count)
736 if (count <= 32 && (ndr->flags & LIBNDR_PRINT_ARRAY_HEX)) {
738 for (i=0;i<count;i++) {
739 snprintf(&s[i*2], 3, "%02x", data[i]);
742 ndr->print(ndr, "%-25s: %s", name, s);
746 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
748 for (i=0;i<count;i++) {
750 asprintf(&idx, "[%d]", i);
752 ndr_print_uint8(ndr, idx, data[i]);
760 build a GUID from a string
762 NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
765 uint32 time_mid, time_hi_and_version;
770 if (11 != sscanf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
771 &time_low, &time_mid, &time_hi_and_version,
772 &clock_seq[0], &clock_seq[1],
773 &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
774 return NT_STATUS_INVALID_PARAMETER;
777 guid->time_low = time_low;
778 guid->time_mid = time_mid;
779 guid->time_hi_and_version = time_hi_and_version;
780 guid->clock_seq[0] = clock_seq[0];
781 guid->clock_seq[1] = clock_seq[1];
783 guid->node[i] = node[i];
790 its useful to be able to display these in debugging messages
792 const char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
794 return talloc_asprintf(mem_ctx,
795 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
796 guid->time_low, guid->time_mid,
797 guid->time_hi_and_version,
800 guid->node[0], guid->node[1],
801 guid->node[2], guid->node[3],
802 guid->node[4], guid->node[5]);
805 void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid)
807 ndr->print(ndr, "%-25s: %s", GUID_string(ndr->mem_ctx, guid));
810 void ndr_print_DATA_BLOB(struct ndr_print *ndr, const char *name, DATA_BLOB r)
812 ndr->print(ndr, "%-25s: DATA_BLOB length=%u", name, r.length);
814 dump_data(10, r.data, r.length);
820 push a DATA_BLOB onto the wire.
822 NTSTATUS ndr_push_DATA_BLOB(struct ndr_push *ndr, DATA_BLOB blob)
824 if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
825 if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
826 blob.length = NDR_ALIGN(ndr, 2);
827 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
828 blob.length = NDR_ALIGN(ndr, 4);
829 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
830 blob.length = NDR_ALIGN(ndr, 8);
832 NDR_PUSH_ALLOC_SIZE(ndr, blob.data, blob.length);
833 data_blob_clear(&blob);
834 } else if (!(ndr->flags & LIBNDR_FLAG_REMAINING)) {
835 NDR_CHECK(ndr_push_uint32(ndr, blob.length));
837 NDR_CHECK(ndr_push_bytes(ndr, blob.data, blob.length));
842 pull a DATA_BLOB from the wire.
844 NTSTATUS ndr_pull_DATA_BLOB(struct ndr_pull *ndr, DATA_BLOB *blob)
848 if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
849 if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
850 length = NDR_ALIGN(ndr, 2);
851 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
852 length = NDR_ALIGN(ndr, 4);
853 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
854 length = NDR_ALIGN(ndr, 8);
856 if (ndr->data_size - ndr->offset < length) {
857 length = ndr->data_size - ndr->offset;
859 } else if (ndr->flags & LIBNDR_FLAG_REMAINING) {
860 length = ndr->data_size - ndr->offset;
862 NDR_CHECK(ndr_pull_uint32(ndr, &length));
864 NDR_PULL_NEED_BYTES(ndr, length);
865 *blob = data_blob_talloc(ndr->mem_ctx, ndr->data+ndr->offset, length);
866 ndr->offset += length;