[PATCH] s4:librpc/ndr: add new LIBNDR_FLAG_STR_RAW8 for ndr_pull_string

Sean Finney seanius at seanius.net
Mon May 23 06:05:04 MDT 2011


Introduce a new flag, LIBNDR_FLAG_STR_RAW8, which when combined with
LIBNDR_FLAG_STR_NULLTERM will indicate that libndr should not attempt
to convert the corresponding string, and place the responsibility on
the caller to do so later.

This is needed in cases where the string is known to be 8-bit and NULL
terminated, but in an unspecified character set.  For example, when
pulling PT_STRING8 properties from an exchange server via libmapi +
libndr, the codepage is neither known nor in the control of the caller,
and is determined by subsequent properties requested from the server.
Therefore the client would like to fetch all properties in one large
batch, and convert the resulting strings locally.

Signed-off-by: Sean Finney <seanius at seanius.net>
---
 librpc/idl/idl_types.h  |    6 ++++++
 librpc/ndr/libndr.h     |    1 +
 librpc/ndr/ndr_string.c |   27 +++++++++++++++++++++++----
 3 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/librpc/idl/idl_types.h b/librpc/idl/idl_types.h
index 023c040..c50efac 100644
--- a/librpc/idl/idl_types.h
+++ b/librpc/idl/idl_types.h
@@ -8,6 +8,7 @@
 #define STR_CONFORMANT  LIBNDR_FLAG_STR_CONFORMANT
 #define STR_CHARLEN	LIBNDR_FLAG_STR_CHARLEN
 #define STR_UTF8	LIBNDR_FLAG_STR_UTF8
+#define STR_RAW8	LIBNDR_FLAG_STR_RAW8
 
 /*
   a null terminated UCS2 string
@@ -25,6 +26,11 @@
 #define utf8string	[flag(STR_UTF8|STR_NULLTERM)] string
 
 /*
+  a null terminated "raw" string (null terminated byte sequence)
+*/
+#define raw8string	[flag(STR_RAW8|STR_NULLTERM)] string
+
+/*
   a null terminated UCS2 string
 */
 #define nstring_array	[flag(STR_NULLTERM|NDR_ALIGN2)] string_array
diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
index cbe9b40..ca3710b 100644
--- a/librpc/ndr/libndr.h
+++ b/librpc/ndr/libndr.h
@@ -122,6 +122,7 @@ struct ndr_print {
 #define LIBNDR_FLAG_STR_CONFORMANT	(1<<10)
 #define LIBNDR_FLAG_STR_CHARLEN		(1<<11)
 #define LIBNDR_FLAG_STR_UTF8		(1<<12)
+#define LIBNDR_FLAG_STR_RAW8		(1<<13)
 #define LIBNDR_STRING_FLAGS		(0x7FFC)
 
 /* set if relative pointers should *not* be marshalled in reverse order */
diff --git a/librpc/ndr/ndr_string.c b/librpc/ndr/ndr_string.c
index 6e20333..a46d704 100644
--- a/librpc/ndr/ndr_string.c
+++ b/librpc/ndr/ndr_string.c
@@ -31,7 +31,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_string(struct ndr_pull *ndr, int ndr_flags,
 	uint32_t len1, ofs, len2;
 	uint16_t len3;
 	size_t converted_size;
-	int chset = CH_UTF16;
+	int do_convert = 1, chset = CH_UTF16;
 	unsigned byte_mul = 2;
 	unsigned flags = ndr->flags;
 	unsigned c_len_term = 0;
@@ -56,6 +56,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_string(struct ndr_pull *ndr, int ndr_flags,
 		flags &= ~LIBNDR_FLAG_STR_UTF8;
 	}
 
+	if (flags & LIBNDR_FLAG_STR_RAW8) {
+		do_convert = 0;
+		byte_mul = 1;
+		flags &= ~LIBNDR_FLAG_STR_RAW8;
+	}
+
 	flags &= ~LIBNDR_FLAG_STR_CONFORMANT;
 	if (flags & LIBNDR_FLAG_STR_CHARLEN) {
 		c_len_term = 1;
@@ -246,7 +252,10 @@ _PUBLIC_ enum ndr_err_code ndr_pull_string(struct ndr_pull *ndr, int ndr_flags,
 		} else {
 			len1 = utf16_len_n(ndr->data+ndr->offset, ndr->data_size - ndr->offset);
 		}
-		if (!convert_string_talloc(ndr->current_mem_ctx, chset, CH_UNIX,
+		if (!do_convert) {
+			as = talloc_strndup(ndr->current_mem_ctx,
+			                    ndr->data + ndr->offset, len1);
+		} else if (!convert_string_talloc(ndr->current_mem_ctx, chset, CH_UNIX,
 					   ndr->data+ndr->offset, len1,
 					   (void **)(void *)&as,
 					   &converted_size))
@@ -301,7 +310,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_string(struct ndr_push *ndr, int ndr_flags,
 {
 	ssize_t s_len, c_len;
 	size_t d_len;
-	int chset = CH_UTF16;
+	int do_convert = 1, chset = CH_UTF16;
 	unsigned flags = ndr->flags;
 	unsigned byte_mul = 2;
 	uint8_t *dest = NULL;
@@ -328,12 +337,22 @@ _PUBLIC_ enum ndr_err_code ndr_push_string(struct ndr_push *ndr, int ndr_flags,
 		flags &= ~LIBNDR_FLAG_STR_UTF8;
 	}
 
+	if (flags & LIBNDR_FLAG_STR_RAW8) {
+		do_convert = 0;
+		byte_mul = 1;
+		flags &= ~LIBNDR_FLAG_STR_RAW8;
+	}
+
 	flags &= ~LIBNDR_FLAG_STR_CONFORMANT;
 
 	if (!(flags & LIBNDR_FLAG_STR_NOTERM)) {
 		s_len++;
 	}
-	if (!convert_string_talloc(ndr, CH_UNIX, chset, s, s_len,
+
+	if (!do_convert) {
+		d_len = s_len;
+		dest = talloc_strndup(ndr, s, s_len);
+	} else if (!convert_string_talloc(ndr, CH_UNIX, chset, s, s_len,
 				   (void **)(void *)&dest, &d_len))
 	{
 		return ndr_push_error(ndr, NDR_ERR_CHARCNV, 
-- 
1.7.0.4



More information about the samba-technical mailing list