summaryrefslogtreecommitdiff
path: root/source3/librpc/ndr/ndr_string.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/librpc/ndr/ndr_string.c')
-rw-r--r--source3/librpc/ndr/ndr_string.c214
1 files changed, 165 insertions, 49 deletions
diff --git a/source3/librpc/ndr/ndr_string.c b/source3/librpc/ndr/ndr_string.c
index bc4582cca7..375cb00eb4 100644
--- a/source3/librpc/ndr/ndr_string.c
+++ b/source3/librpc/ndr/ndr_string.c
@@ -20,17 +20,18 @@
*/
#include "includes.h"
+#include "librpc/ndr/libndr.h"
/**
pull a general string from the wire
*/
-NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
+_PUBLIC_ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
{
char *as=NULL;
uint32_t len1, ofs, len2;
uint16_t len3;
int ret;
- charset_t chset = CH_UTF16LE;
+ int chset = CH_UTF16;
unsigned byte_mul = 2;
unsigned flags = ndr->flags;
unsigned c_len_term = 0;
@@ -84,7 +85,7 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
chset, CH_UNIX,
ndr->data+ndr->offset,
(len2 + c_len_term)*byte_mul,
- &as, True);
+ (void **)&as, false);
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
@@ -121,7 +122,7 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
chset, CH_UNIX,
ndr->data+ndr->offset,
(len1 + c_len_term)*byte_mul,
- &as, False);
+ (void **)&as, false);
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
@@ -159,7 +160,7 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
chset, CH_UNIX,
ndr->data+ndr->offset,
(len1 + c_len_term)*byte_mul,
- &as, False);
+ (void **)&as, false);
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
@@ -193,7 +194,7 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
chset, CH_UNIX,
ndr->data+ndr->offset,
(len3 + c_len_term)*byte_mul,
- &as, False);
+ (void **)&as, false);
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
@@ -224,7 +225,8 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
ret = convert_string_talloc(ndr->current_mem_ctx,
chset, CH_UNIX,
ndr->data+ndr->offset,
- len3, &as, False);
+ len3,
+ (void **)&as, false);
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
@@ -243,7 +245,8 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
ret = convert_string_talloc(ndr->current_mem_ctx,
chset, CH_UNIX,
ndr->data+ndr->offset,
- len1, &as, False);
+ len1,
+ (void **)&as, false);
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
@@ -259,7 +262,8 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
ret = convert_string_talloc(ndr->current_mem_ctx,
chset, CH_UNIX,
ndr->data+ndr->offset,
- len1*byte_mul, &as, False);
+ len1*byte_mul,
+ (void **)&as, false);
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
@@ -268,6 +272,33 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
*s = as;
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);
+ }
+
+ len1 = ndr->data_size - ndr->offset;
+
+ NDR_PULL_NEED_BYTES(ndr, len1);
+ if (len1 == 0) {
+ as = talloc_strdup(ndr->current_mem_ctx, "");
+ } else {
+ ret = convert_string_talloc(ndr->current_mem_ctx,
+ chset, CH_UNIX,
+ ndr->data+ndr->offset,
+ len1,
+ (void **)&as, false);
+ if (ret == -1) {
+ return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
+ "Bad character conversion");
+ }
+ }
+ NDR_CHECK(ndr_pull_advance(ndr, len1));
+
+ *s = as;
+ break;
+
default:
return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
ndr->flags & LIBNDR_STRING_FLAGS);
@@ -280,10 +311,10 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
/**
push a general string onto the wire
*/
-NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
+_PUBLIC_ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
{
ssize_t s_len, c_len, d_len;
- charset_t chset = CH_UTF16LE;
+ int chset = CH_UTF16;
unsigned flags = ndr->flags;
unsigned byte_mul = 2;
uint8_t *dest = NULL;
@@ -318,8 +349,7 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
LIBNDR_FLAG_STR_FIXLEN32))) {
s_len++;
}
- d_len = convert_string_talloc(ndr, CH_UNIX, chset, s, s_len, &dest,
- False);
+ d_len = convert_string_talloc(ndr, CH_UNIX, chset, s, s_len, (void **)&dest, false);
if (d_len == -1) {
return ndr_push_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
@@ -379,6 +409,11 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
}
default:
+ if (ndr->flags & LIBNDR_FLAG_REMAINING) {
+ NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
+ break;
+ }
+
return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
ndr->flags & LIBNDR_STRING_FLAGS);
}
@@ -391,7 +426,7 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
/**
push a general string onto the wire
*/
-size_t ndr_string_array_size(struct ndr_push *ndr, const char *s)
+_PUBLIC_ size_t ndr_string_array_size(struct ndr_push *ndr, const char *s)
{
size_t c_len;
unsigned flags = ndr->flags;
@@ -405,7 +440,7 @@ size_t ndr_string_array_size(struct ndr_push *ndr, const char *s)
return 15;
}
- c_len = s?strlen(s):0;
+ c_len = s?strlen_m(s):0;
if (flags & (LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_UTF8)) {
byte_mul = 1;
@@ -424,7 +459,7 @@ size_t ndr_string_array_size(struct ndr_push *ndr, const char *s)
return c_len;
}
-void ndr_print_string(struct ndr_print *ndr, const char *name, const char *s)
+_PUBLIC_ void ndr_print_string(struct ndr_print *ndr, const char *name, const char *s)
{
if (s) {
ndr->print(ndr, "%-25s: '%s'", name, s);
@@ -433,7 +468,7 @@ void ndr_print_string(struct ndr_print *ndr, const char *name, const char *s)
}
}
-uint32_t ndr_size_string(int ret, const char * const* string, int flags)
+_PUBLIC_ uint32_t ndr_size_string(int ret, const char * const* string, int flags)
{
/* FIXME: Is this correct for all strings ? */
if(!(*string)) return ret;
@@ -443,60 +478,142 @@ uint32_t ndr_size_string(int ret, const char * const* string, int flags)
/**
pull a general string array from the wire
*/
-NTSTATUS ndr_pull_string_array(struct ndr_pull *ndr, int ndr_flags, const char ***_a)
+_PUBLIC_ NTSTATUS ndr_pull_string_array(struct ndr_pull *ndr, int ndr_flags, const char ***_a)
{
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;
}
/**
push a general string array onto the wire
*/
-NTSTATUS ndr_push_string_array(struct ndr_push *ndr, int ndr_flags, const char **a)
+_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, ""));
+ 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);
+ }
+
+ 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;
}
-void ndr_print_string_array(struct ndr_print *ndr, const char *name, const char **a)
+_PUBLIC_ void ndr_print_string_array(struct ndr_print *ndr, const char *name, const char **a)
{
uint32_t count;
uint32_t i;
@@ -519,7 +636,7 @@ void ndr_print_string_array(struct ndr_print *ndr, const char *name, const char
/**
* Return number of elements in a string including the last (zeroed) element
*/
-uint32_t ndr_string_length(const void *_var, uint32_t element_size)
+_PUBLIC_ uint32_t ndr_string_length(const void *_var, uint32_t element_size)
{
uint32_t i;
uint8_t zero[4] = {0,0,0,0};
@@ -530,7 +647,7 @@ uint32_t ndr_string_length(const void *_var, uint32_t element_size)
return i+1;
}
-NTSTATUS ndr_check_string_terminator(struct ndr_pull *ndr, uint32_t count, uint32_t element_size)
+_PUBLIC_ NTSTATUS ndr_check_string_terminator(struct ndr_pull *ndr, uint32_t count, uint32_t element_size)
{
uint32_t i;
struct ndr_pull_save save_offset;
@@ -552,7 +669,7 @@ NTSTATUS ndr_check_string_terminator(struct ndr_pull *ndr, uint32_t count, uint3
return NT_STATUS_OK;
}
-NTSTATUS ndr_pull_charset(struct ndr_pull *ndr, int ndr_flags, const char **var, uint32_t length, uint8_t byte_mul, charset_t chset)
+_PUBLIC_ NTSTATUS ndr_pull_charset(struct ndr_pull *ndr, int ndr_flags, const char **var, uint32_t length, uint8_t byte_mul, charset_t chset)
{
int ret;
if (length == 0) {
@@ -570,7 +687,7 @@ NTSTATUS ndr_pull_charset(struct ndr_pull *ndr, int ndr_flags, const char **var,
chset, CH_UNIX,
ndr->data+ndr->offset,
length*byte_mul,
- var, False);
+ discard_const_p(void *, var), false);
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
@@ -580,8 +697,7 @@ NTSTATUS ndr_pull_charset(struct ndr_pull *ndr, int ndr_flags, const char **var,
return NT_STATUS_OK;
}
-NTSTATUS ndr_push_charset(struct ndr_push *ndr, int ndr_flags, const char *var,
- uint32_t length, uint8_t byte_mul, charset_t chset)
+_PUBLIC_ NTSTATUS ndr_push_charset(struct ndr_push *ndr, int ndr_flags, const char *var, uint32_t length, uint8_t byte_mul, charset_t chset)
{
ssize_t ret, required;
@@ -594,7 +710,7 @@ NTSTATUS ndr_push_charset(struct ndr_push *ndr, int ndr_flags, const char *var,
NDR_PUSH_NEED_BYTES(ndr, required);
ret = convert_string(CH_UNIX, chset,
var, strlen(var),
- ndr->data+ndr->offset, required, False);
+ ndr->data+ndr->offset, required, false);
if (ret == -1) {
return ndr_push_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
@@ -611,7 +727,7 @@ NTSTATUS ndr_push_charset(struct ndr_push *ndr, int ndr_flags, const char *var,
}
/* Return number of elements in a string in the specified charset */
-uint32_t ndr_charset_length(const void *var, int chset)
+_PUBLIC_ uint32_t ndr_charset_length(const void *var, charset_t chset)
{
/* FIXME: Treat special chars special here, taking chset into account */
/* Also include 0 byte */