summaryrefslogtreecommitdiff
path: root/source4/librpc/ndr/ndr_string.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2007-02-17 09:09:07 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:48:26 -0500
commit3847155cc47187689a7ef2c3902238ce71056955 (patch)
tree17092e956825b4c237312c61bc7bc12834465a50 /source4/librpc/ndr/ndr_string.c
parent683eb22d3fb418d57dcae401783126e644a283a0 (diff)
downloadsamba-3847155cc47187689a7ef2c3902238ce71056955.tar.gz
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)
Diffstat (limited to 'source4/librpc/ndr/ndr_string.c')
-rw-r--r--source4/librpc/ndr/ndr_string.c127
1 files changed, 105 insertions, 22 deletions
diff --git a/source4/librpc/ndr/ndr_string.c b/source4/librpc/ndr/ndr_string.c
index 6c4332bd01c..e6da55a33bb 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;
}