From 3847155cc47187689a7ef2c3902238ce71056955 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 17 Feb 2007 09:09:07 +0000 Subject: r21405: add support for [flag(STR_NOTERM|NDR_REMAINING)] string_array foo; this is handles the content of the 'Packages' element in the supplementalCredetials metze (This used to be commit 07fe22f82ebe66464ef73274a109d1e21a0d7f0f) --- source4/librpc/ndr/ndr_string.c | 127 +++++++++++++++++++++++++++++++++------- 1 file changed, 105 insertions(+), 22 deletions(-) (limited to 'source4/librpc') diff --git a/source4/librpc/ndr/ndr_string.c b/source4/librpc/ndr/ndr_string.c index 6c4332bd01..e6da55a33b 100644 --- a/source4/librpc/ndr/ndr_string.c +++ b/source4/librpc/ndr/ndr_string.c @@ -275,7 +275,8 @@ _PUBLIC_ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const cha case LIBNDR_FLAG_STR_NOTERM: if (!(ndr->flags & LIBNDR_FLAG_REMAINING)) { - break; + return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x (missing NDR_REMAINING)\n", + ndr->flags & LIBNDR_STRING_FLAGS); } len1 = ndr->data_size - ndr->offset; @@ -482,32 +483,85 @@ _PUBLIC_ NTSTATUS ndr_pull_string_array(struct ndr_pull *ndr, int ndr_flags, con { const char **a = *_a; uint32_t count; + unsigned flags = ndr->flags; + unsigned saved_flags = ndr->flags; if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; } - for (count = 0;; count++) { - TALLOC_CTX *tmp_ctx; - const char *s = NULL; - a = talloc_realloc(ndr->current_mem_ctx, a, const char *, count + 2); - NT_STATUS_HAVE_NO_MEMORY(a); - a[count] = NULL; - a[count+1] = NULL; - - tmp_ctx = ndr->current_mem_ctx; - ndr->current_mem_ctx = a; - NDR_CHECK(ndr_pull_string(ndr, ndr_flags, &s)); - ndr->current_mem_ctx = tmp_ctx; - if (strcmp("", s)==0) { - a[count] = NULL; - break; - } else { + switch (flags & LIBNDR_STRING_FLAGS) { + case LIBNDR_FLAG_STR_NULLTERM: + /* + * here the strings are null terminated + * but also the array is null terminated + */ + for (count = 0;; count++) { + TALLOC_CTX *tmp_ctx; + const char *s = NULL; + a = talloc_realloc(ndr->current_mem_ctx, a, const char *, count + 2); + NT_STATUS_HAVE_NO_MEMORY(a); + a[count] = NULL; + a[count+1] = NULL; + + tmp_ctx = ndr->current_mem_ctx; + ndr->current_mem_ctx = a; + NDR_CHECK(ndr_pull_string(ndr, ndr_flags, &s)); + ndr->current_mem_ctx = tmp_ctx; + if (strcmp("", s)==0) { + a[count] = NULL; + break; + } else { + a[count] = s; + } + } + + *_a =a; + break; + + case LIBNDR_FLAG_STR_NOTERM: + if (!(ndr->flags & LIBNDR_FLAG_REMAINING)) { + return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x (missing NDR_REMAINING)\n", + ndr->flags & LIBNDR_STRING_FLAGS); + } + /* + * here the strings are not null terminated + * but serarated by a null terminator + * + * which means the same as: + * very string is null terminated exept the last + * string is terminated by the end of the buffer + * + * as LIBNDR_FLAG_STR_NULLTERM also end at the end + * of the buffer, we can pull each string with this flag + */ + ndr->flags &= ~(LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_REMAINING); + ndr->flags |= LIBNDR_FLAG_STR_NULLTERM; + + for (count = 0; ((ndr->data_size - ndr->offset) > 0); count++) { + TALLOC_CTX *tmp_ctx; + const char *s = NULL; + a = talloc_realloc(ndr->current_mem_ctx, a, const char *, count + 2); + NT_STATUS_HAVE_NO_MEMORY(a); + a[count] = NULL; + a[count+1] = NULL; + + tmp_ctx = ndr->current_mem_ctx; + ndr->current_mem_ctx = a; + NDR_CHECK(ndr_pull_string(ndr, ndr_flags, &s)); + ndr->current_mem_ctx = tmp_ctx; a[count] = s; } + + *_a =a; + break; + + default: + return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n", + ndr->flags & LIBNDR_STRING_FLAGS); } - *_a =a; + ndr->flags = saved_flags; return NT_STATUS_OK; } @@ -517,17 +571,46 @@ _PUBLIC_ NTSTATUS ndr_pull_string_array(struct ndr_pull *ndr, int ndr_flags, con _PUBLIC_ NTSTATUS ndr_push_string_array(struct ndr_push *ndr, int ndr_flags, const char **a) { uint32_t count; + unsigned flags = ndr->flags; + unsigned saved_flags = ndr->flags; if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; } - for (count = 0; a && a[count]; count++) { - NDR_CHECK(ndr_push_string(ndr, ndr_flags, a[count])); - } + switch (flags & LIBNDR_STRING_FLAGS) { + case LIBNDR_FLAG_STR_NULLTERM: + for (count = 0; a && a[count]; count++) { + NDR_CHECK(ndr_push_string(ndr, ndr_flags, a[count])); + } + + NDR_CHECK(ndr_push_string(ndr, ndr_flags, "")); + break; + + case LIBNDR_FLAG_STR_NOTERM: + if (!(ndr->flags & LIBNDR_FLAG_REMAINING)) { + return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x (missing NDR_REMAINING)\n", + ndr->flags & LIBNDR_STRING_FLAGS); + } - NDR_CHECK(ndr_push_string(ndr, ndr_flags, "")); + for (count = 0; a && a[count]; count++) { + if (count > 0) { + ndr->flags &= ~(LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_REMAINING); + ndr->flags |= LIBNDR_FLAG_STR_NULLTERM; + NDR_CHECK(ndr_push_string(ndr, ndr_flags, "")); + ndr->flags = saved_flags; + } + NDR_CHECK(ndr_push_string(ndr, ndr_flags, a[count])); + } + + break; + default: + return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n", + ndr->flags & LIBNDR_STRING_FLAGS); + } + + ndr->flags = saved_flags; return NT_STATUS_OK; } -- cgit