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.
28 NTSTATUS ndr_pull_uint8(struct ndr_pull *ndr, uint8 *v)
30 NDR_PULL_NEED_BYTES(ndr, 1);
31 *v = CVAL(ndr->data, ndr->offset);
40 NTSTATUS ndr_pull_uint16(struct ndr_pull *ndr, uint16 *v)
42 NDR_PULL_ALIGN(ndr, 2);
43 NDR_PULL_NEED_BYTES(ndr, 2);
44 *v = SVAL(ndr->data, ndr->offset);
53 NTSTATUS ndr_pull_uint32(struct ndr_pull *ndr, uint32 *v)
55 NDR_PULL_ALIGN(ndr, 4);
56 NDR_PULL_NEED_BYTES(ndr, 4);
57 *v = IVAL(ndr->data, ndr->offset);
65 NTSTATUS ndr_pull_HYPER_T(struct ndr_pull *ndr, HYPER_T *v)
67 NDR_PULL_ALIGN(ndr, 8);
68 NDR_PULL_NEED_BYTES(ndr, 8);
69 v->low = IVAL(ndr->data, ndr->offset);
70 v->high = IVAL(ndr->data, ndr->offset+4);
78 NTSTATUS ndr_pull_NTSTATUS(struct ndr_pull *ndr, NTSTATUS *status)
81 NDR_CHECK(ndr_pull_uint32(ndr, &v));
82 *status = NT_STATUS(v);
89 NTSTATUS ndr_push_NTSTATUS(struct ndr_push *ndr, NTSTATUS status)
91 return ndr_push_uint32(ndr, NT_STATUS_V(status));
94 void ndr_print_NTSTATUS(struct ndr_print *ndr, const char *name, NTSTATUS *r)
96 ndr->print(ndr, "%-25s: %s", name, nt_errstr(*r));
102 NTSTATUS ndr_pull_WERROR(struct ndr_pull *ndr, WERROR *status)
105 NDR_CHECK(ndr_pull_uint32(ndr, &v));
106 *status = W_ERROR(v);
113 NTSTATUS ndr_push_WERROR(struct ndr_push *ndr, WERROR status)
115 return ndr_push_uint32(ndr, W_ERROR_V(status));
118 void ndr_print_WERROR(struct ndr_print *ndr, const char *name, WERROR *r)
120 ndr->print(ndr, "%-25s: %s", name, win_errstr(*r));
126 NTSTATUS ndr_pull_bytes(struct ndr_pull *ndr, char *data, uint32 n)
128 NDR_PULL_NEED_BYTES(ndr, n);
129 memcpy(data, ndr->data + ndr->offset, n);
135 pull an array of uint8
137 NTSTATUS ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, char *data, uint32 n)
139 if (!(ndr_flags & NDR_SCALARS)) {
142 return ndr_pull_bytes(ndr, data, n);
147 pull an array of uint16
149 NTSTATUS ndr_pull_array_uint16(struct ndr_pull *ndr, int ndr_flags, uint16 *data, uint32 n)
152 if (!(ndr_flags & NDR_SCALARS)) {
156 NDR_CHECK(ndr_pull_uint16(ndr, &data[i]));
162 pull a const array of uint32
164 NTSTATUS ndr_pull_array_uint32(struct ndr_pull *ndr, int ndr_flags, uint32 *data, uint32 n)
167 if (!(ndr_flags & NDR_SCALARS)) {
171 NDR_CHECK(ndr_pull_uint32(ndr, &data[i]));
179 NTSTATUS ndr_pull_GUID(struct ndr_pull *ndr, int ndr_flags, GUID *guid)
181 if (ndr_flags & NDR_SCALARS) {
182 return ndr_pull_bytes(ndr, guid->info, GUID_SIZE);
191 NTSTATUS ndr_push_uint8(struct ndr_push *ndr, uint8 v)
193 NDR_PUSH_NEED_BYTES(ndr, 1);
194 SCVAL(ndr->data, ndr->offset, v);
202 NTSTATUS ndr_push_uint16(struct ndr_push *ndr, uint16 v)
204 NDR_PUSH_ALIGN(ndr, 2);
205 NDR_PUSH_NEED_BYTES(ndr, 2);
206 SSVAL(ndr->data, ndr->offset, v);
214 NTSTATUS ndr_push_uint32(struct ndr_push *ndr, uint32 v)
216 NDR_PUSH_ALIGN(ndr, 4);
217 NDR_PUSH_NEED_BYTES(ndr, 4);
218 SIVAL(ndr->data, ndr->offset, v);
226 NTSTATUS ndr_push_HYPER_T(struct ndr_push *ndr, HYPER_T v)
228 NDR_PUSH_ALIGN(ndr, 8);
229 NDR_PUSH_NEED_BYTES(ndr, 8);
230 SIVAL(ndr->data, ndr->offset, v.low);
231 SIVAL(ndr->data, ndr->offset+4, v.high);
236 NTSTATUS ndr_push_align(struct ndr_push *ndr, size_t size)
238 NDR_PUSH_ALIGN(ndr, size);
242 NTSTATUS ndr_pull_align(struct ndr_pull *ndr, size_t size)
244 NDR_PULL_ALIGN(ndr, size);
251 NTSTATUS ndr_push_bytes(struct ndr_push *ndr, const char *data, uint32 n)
253 NDR_PUSH_NEED_BYTES(ndr, n);
254 memcpy(ndr->data + ndr->offset, data, n);
260 push an array of uint8
262 NTSTATUS ndr_push_array_uint8(struct ndr_push *ndr, int ndr_flags, const char *data, uint32 n)
264 if (!(ndr_flags & NDR_SCALARS)) {
267 return ndr_push_bytes(ndr, data, n);
271 push an array of uint32
273 NTSTATUS ndr_push_array_uint32(struct ndr_push *ndr, int ndr_flags, const uint32 *data, uint32 n)
276 if (!(ndr_flags & NDR_SCALARS)) {
280 NDR_CHECK(ndr_push_uint32(ndr, data[i]));
286 save the current position
288 void ndr_push_save(struct ndr_push *ndr, struct ndr_push_save *save)
290 save->offset = ndr->offset;
296 void ndr_push_restore(struct ndr_push *ndr, struct ndr_push_save *save)
298 ndr->offset = save->offset;
302 this is used when a packet has a 4 byte length field. We remember the start position
303 and come back to it later to fill in the size
305 NTSTATUS ndr_push_length4_start(struct ndr_push *ndr, struct ndr_push_save *save)
307 NDR_PUSH_ALIGN(ndr, 4);
308 ndr_push_save(ndr, save);
309 return ndr_push_uint32(ndr, 0);
312 NTSTATUS ndr_push_length4_end(struct ndr_push *ndr, struct ndr_push_save *save)
314 struct ndr_push_save save2;
315 ndr_push_save(ndr, &save2);
316 ndr_push_restore(ndr, save);
317 NDR_CHECK(ndr_push_uint32(ndr, save2.offset - ndr->offset));
318 ndr_push_restore(ndr, &save2);
323 push a 1 if a pointer is non-NULL, otherwise 0
325 NTSTATUS ndr_push_ptr(struct ndr_push *ndr, const void *p)
329 /* we do this to ensure that we generate unique ref ids,
330 which means we can handle the case where a MS programmer
331 forgot to mark a pointer as unique */
333 ptr = ndr->ptr_count;
335 return ndr_push_uint32(ndr, ptr);
340 pull a general string from the wire
342 NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
345 uint32 len1, ofs, len2;
349 if (!(ndr_flags & NDR_SCALARS)) {
353 switch (ndr->flags & LIBNDR_STRING_FLAGS) {
354 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
355 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
356 NDR_CHECK(ndr_pull_uint32(ndr, &len1));
357 NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
358 NDR_CHECK(ndr_pull_uint32(ndr, &len2));
360 return ndr_pull_error(ndr, NDR_ERR_STRING,
361 "Bad string lengths len1=%u ofs=%u len2=%u\n",
365 *s = talloc_strdup(ndr->mem_ctx, "");
368 NDR_PULL_NEED_BYTES(ndr, len2*2);
369 ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX,
370 ndr->data+ndr->offset,
374 return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
375 "Bad character conversion");
377 NDR_CHECK(ndr_pull_advance(ndr, len2*2));
381 case LIBNDR_FLAG_STR_SIZE4:
382 NDR_CHECK(ndr_pull_uint32(ndr, &len1));
383 NDR_PULL_NEED_BYTES(ndr, len1*2);
385 *s = talloc_strdup(ndr->mem_ctx, "");
388 ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX,
389 ndr->data+ndr->offset,
393 return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
394 "Bad character conversion");
396 NDR_CHECK(ndr_pull_advance(ndr, len1*2));
400 case LIBNDR_FLAG_STR_NULLTERM:
401 len1 = strnlen_w(ndr->data+ndr->offset,
402 (ndr->data_size - ndr->offset)/2);
403 if (len1*2+2 <= ndr->data_size - ndr->offset) {
406 ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX,
407 ndr->data+ndr->offset,
411 return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
412 "Bad character conversion");
414 NDR_CHECK(ndr_pull_advance(ndr, len1*2));
417 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
418 NDR_CHECK(ndr_pull_uint32(ndr, &len1));
419 NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
420 NDR_CHECK(ndr_pull_uint32(ndr, &len2));
422 return ndr_pull_error(ndr, NDR_ERR_STRING,
423 "Bad ascii string lengths len1=%u ofs=%u len2=%u\n",
426 NDR_ALLOC_N(ndr, as, (len2+1));
427 NDR_CHECK(ndr_pull_bytes(ndr, as, len2));
432 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4:
433 NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
434 NDR_CHECK(ndr_pull_uint32(ndr, &len2));
435 NDR_ALLOC_N(ndr, as, (len2+1));
436 NDR_CHECK(ndr_pull_bytes(ndr, as, len2));
441 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2:
442 NDR_CHECK(ndr_pull_uint16(ndr, &len3));
443 NDR_ALLOC_N(ndr, as, (len3+1));
444 NDR_CHECK(ndr_pull_bytes(ndr, as, len3));
450 return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
451 ndr->flags & LIBNDR_STRING_FLAGS);
459 push a general string onto the wire
461 NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
463 ssize_t s_len, c_len;
466 if (!(ndr_flags & NDR_SCALARS)) {
470 s_len = s?strlen(s):0;
471 c_len = s?strlen_m(s):0;
473 switch (ndr->flags & LIBNDR_STRING_FLAGS) {
474 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
475 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
476 NDR_CHECK(ndr_push_uint32(ndr, 0));
477 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
478 NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
479 ret = convert_string(CH_UNIX, CH_UCS2,
481 ndr->data+ndr->offset, c_len*2 + 2);
483 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
484 "Bad character conversion");
486 ndr->offset += c_len*2 + 2;
489 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
490 NDR_CHECK(ndr_push_uint32(ndr, c_len));
491 NDR_CHECK(ndr_push_uint32(ndr, 0));
492 NDR_CHECK(ndr_push_uint32(ndr, c_len));
493 NDR_PUSH_NEED_BYTES(ndr, c_len*2);
494 ret = convert_string(CH_UNIX, CH_UCS2,
496 ndr->data+ndr->offset, c_len*2);
498 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
499 "Bad character conversion");
501 ndr->offset += c_len*2;
504 case LIBNDR_FLAG_STR_SIZE4:
505 NDR_CHECK(ndr_push_uint32(ndr, c_len + 1));
506 NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
507 ret = convert_string(CH_UNIX, CH_UCS2,
509 ndr->data+ndr->offset, c_len*2 + 2);
511 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
512 "Bad character conversion");
514 ndr->offset += c_len*2 + 2;
517 case LIBNDR_FLAG_STR_NULLTERM:
518 NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
519 ret = convert_string(CH_UNIX, CH_UCS2,
521 ndr->data+ndr->offset, c_len*2 + 2);
523 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
524 "Bad character conversion");
526 ndr->offset += c_len*2 + 2;
529 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
530 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
531 NDR_CHECK(ndr_push_uint32(ndr, 0));
532 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
533 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
534 ret = convert_string(CH_UNIX, CH_DOS,
536 ndr->data+ndr->offset, c_len + 1);
538 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
539 "Bad character conversion");
541 ndr->offset += c_len + 1;
544 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4:
545 NDR_CHECK(ndr_push_uint32(ndr, 0));
546 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
547 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
548 ret = convert_string(CH_UNIX, CH_DOS,
550 ndr->data+ndr->offset, c_len + 1);
552 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
553 "Bad character conversion");
555 ndr->offset += c_len + 1;
558 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2:
559 NDR_CHECK(ndr_push_uint16(ndr, c_len+1));
560 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
561 ret = convert_string(CH_UNIX, CH_DOS,
563 ndr->data+ndr->offset, c_len + 1);
565 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
566 "Bad character conversion");
568 ndr->offset += c_len + 1;
572 return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
573 ndr->flags & LIBNDR_STRING_FLAGS);
580 push a 4 byte offset pointer, remembering where we are so we can later fill
583 NTSTATUS ndr_push_offset(struct ndr_push *ndr, struct ndr_push_save *ofs)
585 NDR_PUSH_ALIGN(ndr, 4);
586 ndr_push_save(ndr, ofs);
587 return ndr_push_uint32(ndr, 0);
591 fill in the correct offset in a saved offset pointer
592 the offset is taken relative to 'save'
594 NTSTATUS ndr_push_offset_ptr(struct ndr_push *ndr,
595 struct ndr_push_save *ofs,
596 struct ndr_push_save *save)
598 struct ndr_push_save save2;
599 ndr_push_save(ndr, &save2);
600 ndr_push_restore(ndr, ofs);
601 NDR_CHECK(ndr_push_uint32(ndr, save2.offset - save->offset));
602 ndr_push_restore(ndr, &save2);
610 NTSTATUS ndr_push_GUID(struct ndr_push *ndr, int ndr_flags, GUID *guid)
612 if (ndr_flags & NDR_SCALARS) {
613 return ndr_push_bytes(ndr, guid->info, GUID_SIZE);
621 NTSTATUS ndr_push_NTTIME(struct ndr_push *ndr, NTTIME t)
623 NDR_CHECK(ndr_push_uint32(ndr, t.low));
624 NDR_CHECK(ndr_push_uint32(ndr, t.high));
631 NTSTATUS ndr_pull_NTTIME(struct ndr_pull *ndr, NTTIME *t)
633 NDR_CHECK(ndr_pull_uint32(ndr, &t->low));
634 NDR_CHECK(ndr_pull_uint32(ndr, &t->high));
639 void ndr_print_struct(struct ndr_print *ndr, const char *name, const char *type)
641 ndr->print(ndr, "%s: struct %s", name, type);
644 void ndr_print_uint8(struct ndr_print *ndr, const char *name, uint8 v)
646 ndr->print(ndr, "%-25s: 0x%02x (%u)", name, v, v);
649 void ndr_print_uint16(struct ndr_print *ndr, const char *name, uint16 v)
651 ndr->print(ndr, "%-25s: 0x%04x (%u)", name, v, v);
654 void ndr_print_uint32(struct ndr_print *ndr, const char *name, uint32 v)
656 ndr->print(ndr, "%-25s: 0x%08x (%u)", name, v, v);
659 void ndr_print_HYPER_T(struct ndr_print *ndr, const char *name, HYPER_T v)
661 ndr->print(ndr, "%-25s: 0x%08x%08x", name, v.high, v.low);
664 void ndr_print_ptr(struct ndr_print *ndr, const char *name, const void *p)
667 ndr->print(ndr, "%-25s: *", name);
669 ndr->print(ndr, "%-25s: NULL", name);
673 void ndr_print_string(struct ndr_print *ndr, const char *name, const char *s)
676 ndr->print(ndr, "%-25s: '%s'", name, s);
678 ndr->print(ndr, "%-25s: NULL", name);
682 void ndr_print_NTTIME(struct ndr_print *ndr, const char *name, NTTIME t)
684 ndr->print(ndr, "%-25s: %s", name, nt_time_string(ndr->mem_ctx, &t));
687 void ndr_print_union(struct ndr_print *ndr, const char *name, uint16 level, const char *type)
689 ndr->print(ndr, "%-25s: union %s(case %u)", name, type, level);
692 void ndr_print_bad_level(struct ndr_print *ndr, const char *name, uint16 level)
694 ndr->print(ndr, "UNKNOWN LEVEL %u", level);
697 void ndr_print_array_uint32(struct ndr_print *ndr, const char *name,
698 const uint32 *data, uint32 count)
702 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
704 for (i=0;i<count;i++) {
706 asprintf(&idx, "[%d]", i);
708 ndr_print_uint32(ndr, idx, data[i]);
715 void ndr_print_array_uint8(struct ndr_print *ndr, const char *name,
716 const uint8 *data, uint32 count)
720 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
722 for (i=0;i<count;i++) {
724 asprintf(&idx, "[%d]", i);
726 ndr_print_uint8(ndr, idx, data[i]);
734 build a GUID from a string
736 NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
739 uint32 time_mid, time_hi_and_version;
740 uint32 clock_seq_hi_and_reserved;
741 uint32 clock_seq_low;
745 if (11 != sscanf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
746 &time_low, &time_mid, &time_hi_and_version,
747 &clock_seq_hi_and_reserved, &clock_seq_low,
748 &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
749 return NT_STATUS_INVALID_PARAMETER;
752 SIVAL(guid->info, 0, time_low);
753 SSVAL(guid->info, 4, time_mid);
754 SSVAL(guid->info, 6, time_hi_and_version);
755 SCVAL(guid->info, 8, clock_seq_hi_and_reserved);
756 SCVAL(guid->info, 9, clock_seq_low);
758 SCVAL(guid->info, 10 + i, node[i]);
765 const char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
767 return talloc_asprintf(mem_ctx,
768 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
769 IVAL(guid->info, 0), SVAL(guid->info, 4),
771 guid->info[8], guid->info[9],
772 guid->info[10], guid->info[11],
773 guid->info[12], guid->info[13],
774 guid->info[14], guid->info[15]);
777 void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid)
779 ndr->print(ndr, "%-25s: %s", GUID_string(ndr->mem_ctx, guid));
782 void ndr_print_DATA_BLOB(struct ndr_print *ndr, const char *name, DATA_BLOB r)
784 ndr->print(ndr, "%-25s: DATA_BLOB length=%u", name, r.length);
789 push a DATA_BLOB onto the wire.
791 NTSTATUS ndr_push_DATA_BLOB(struct ndr_push *ndr, DATA_BLOB blob)
793 if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
794 if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
795 blob.length = NDR_ALIGN(ndr, 2);
796 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
797 blob.length = NDR_ALIGN(ndr, 4);
798 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
799 blob.length = NDR_ALIGN(ndr, 8);
801 NDR_PUSH_ALLOC_SIZE(ndr, blob.data, blob.length);
802 data_blob_clear(&blob);
803 } else if (!(ndr->flags & LIBNDR_FLAG_REMAINING)) {
804 NDR_CHECK(ndr_push_uint32(ndr, blob.length));
806 NDR_CHECK(ndr_push_bytes(ndr, blob.data, blob.length));
811 pull a DATA_BLOB from the wire.
813 NTSTATUS ndr_pull_DATA_BLOB(struct ndr_pull *ndr, DATA_BLOB *blob)
817 if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
818 if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
819 length = NDR_ALIGN(ndr, 2);
820 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
821 length = NDR_ALIGN(ndr, 4);
822 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
823 length = NDR_ALIGN(ndr, 8);
825 if (ndr->data_size - ndr->offset < length) {
826 length = ndr->data_size - ndr->offset;
828 } else if (ndr->flags & LIBNDR_FLAG_REMAINING) {
829 length = ndr->data_size - ndr->offset;
831 NDR_CHECK(ndr_pull_uint32(ndr, &length));
833 NDR_PULL_NEED_BYTES(ndr, length);
834 *blob = data_blob_talloc(ndr->mem_ctx, ndr->data+ndr->offset, length);
835 ndr->offset += length;
840 void ndr_print_policy_handle(struct ndr_print *ndr, const char *name, struct policy_handle *r)
842 ndr->print(ndr, "%-25s: policy_handle %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
844 r->data[0], r->data[1], r->data[2], r->data[3], r->data[4],
845 r->data[5], r->data[6], r->data[7], r->data[8], r->data[9],
846 r->data[10], r->data[11], r->data[12], r->data[13], r->data[14],
847 r->data[15], r->data[16], r->data[17], r->data[18], r->data[19]);