summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2004-11-02 13:46:39 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:05:21 -0500
commita2fd2488c79902dfe1de764bea4f619ec6107fed (patch)
treeb0018bafa465de3b55acfd4db4bc9143ebce16c4
parent34c9263ed0ffc591e8313981085791b660ccfe26 (diff)
downloadsamba-a2fd2488c79902dfe1de764bea4f619ec6107fed.tar.gz
samba-a2fd2488c79902dfe1de764bea4f619ec6107fed.tar.bz2
samba-a2fd2488c79902dfe1de764bea4f619ec6107fed.zip
r3484: - add support for conformant string arrays at the end of a struct
- add support for strings where the length excludes the NULLTERM metze (This used to be commit 8251d8b3e5af351972aa41aed63f7a7d2640910e)
-rw-r--r--source4/build/pidl/parser.pm16
-rw-r--r--source4/build/pidl/util.pm18
-rw-r--r--source4/librpc/idl/idl_types.h18
-rw-r--r--source4/librpc/ndr/libndr.h43
-rw-r--r--source4/librpc/ndr/ndr_basic.c55
5 files changed, 115 insertions, 35 deletions
diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm
index c52be637ec..34f9df197f 100644
--- a/source4/build/pidl/parser.pm
+++ b/source4/build/pidl/parser.pm
@@ -705,7 +705,6 @@ sub ParseElementPullBuffer($$$)
sub ParseStructPush($)
{
my($struct) = shift;
- my $conform_e;
if (! defined $struct->{ELEMENTS}) {
return;
@@ -722,10 +721,14 @@ sub ParseStructPush($)
if (defined $e->{ARRAY_LEN} && $e->{ARRAY_LEN} eq "*") {
my $size = find_size_var($e, util::array_size($e), "r->");
$e->{CONFORMANT_SIZE} = $size;
- $conform_e = $e;
pidl "\tNDR_CHECK(ndr_push_uint32(ndr, $size));\n";
}
+ if (defined $e->{TYPE} && $e->{TYPE} eq "string"
+ && util::property_matches($e, "flag", ".*LIBNDR_FLAG_STR_CONFORMANT.*")) {
+ pidl "\tNDR_CHECK(ndr_push_uint32(ndr, ndr_string_array_size(ndr, r->$e->{NAME})));\n";
+ }
+
pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n";
pidl "\tNDR_CHECK(ndr_push_struct_start(ndr));\n";
@@ -790,6 +793,15 @@ sub ParseStructPull($)
my $e = $struct->{ELEMENTS}[-1];
if (defined $e->{ARRAY_LEN} && $e->{ARRAY_LEN} eq "*") {
$conform_e = $e;
+ }
+
+ if (defined $e->{TYPE} && $e->{TYPE} eq "string"
+ && util::property_matches($e, "flag", ".*LIBNDR_FLAG_STR_CONFORMANT.*")) {
+ $conform_e = $e;
+ }
+
+ if (defined $conform_e) {
+ $conform_e = $e;
pidl "\tuint32_t _conformant_size;\n";
$conform_e->{CONFORMANT_SIZE} = "_conformant_size";
}
diff --git a/source4/build/pidl/util.pm b/source4/build/pidl/util.pm
index c49e956e50..bddce57740 100644
--- a/source4/build/pidl/util.pm
+++ b/source4/build/pidl/util.pm
@@ -181,6 +181,24 @@ sub has_property($$)
return $e->{PROPERTIES}->{$p};
}
+#####################################################################
+# see if a pidl property matches a value
+sub property_matches($$$)
+{
+ my($e) = shift;
+ my($p) = shift;
+ my($v) = shift;
+
+ if (!defined has_property($e, $p)) {
+ return undef;
+ }
+
+ if ($e->{PROPERTIES}->{$p} =~ /$v/) {
+ return 1;
+ }
+
+ return undef;
+}
sub is_scalar_type($)
{
diff --git a/source4/librpc/idl/idl_types.h b/source4/librpc/idl/idl_types.h
index d74523d8fb..860c9d7260 100644
--- a/source4/librpc/idl/idl_types.h
+++ b/source4/librpc/idl/idl_types.h
@@ -1,11 +1,13 @@
-#define STR_ASCII LIBNDR_FLAG_STR_ASCII
-#define STR_LEN4 LIBNDR_FLAG_STR_LEN4
-#define STR_SIZE4 LIBNDR_FLAG_STR_SIZE4
-#define STR_SIZE2 LIBNDR_FLAG_STR_SIZE2
-#define STR_NOTERM LIBNDR_FLAG_STR_NOTERM
-#define STR_NULLTERM LIBNDR_FLAG_STR_NULLTERM
-#define STR_BYTESIZE LIBNDR_FLAG_STR_BYTESIZE
-#define STR_FIXLEN32 LIBNDR_FLAG_STR_FIXLEN32
+#define STR_ASCII LIBNDR_FLAG_STR_ASCII
+#define STR_LEN4 LIBNDR_FLAG_STR_LEN4
+#define STR_SIZE4 LIBNDR_FLAG_STR_SIZE4
+#define STR_SIZE2 LIBNDR_FLAG_STR_SIZE2
+#define STR_NOTERM LIBNDR_FLAG_STR_NOTERM
+#define STR_NULLTERM LIBNDR_FLAG_STR_NULLTERM
+#define STR_BYTESIZE LIBNDR_FLAG_STR_BYTESIZE
+#define STR_FIXLEN32 LIBNDR_FLAG_STR_FIXLEN32
+#define STR_CONFORMANT LIBNDR_FLAG_STR_CONFORMANT
+#define STR_CHARLEN LIBNDR_FLAG_STR_CHARLEN
/*
a UCS2 string prefixed with [size] [offset] [length], all 32 bits
diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h
index 09d06a7c7f..72d75f7d47 100644
--- a/source4/librpc/ndr/libndr.h
+++ b/source4/librpc/ndr/libndr.h
@@ -89,36 +89,39 @@ struct ndr_print {
#define LIBNDR_FLAG_BIGENDIAN (1<<0)
#define LIBNDR_FLAG_NOALIGN (1<<1)
-#define LIBNDR_FLAG_STR_ASCII (1<<2)
-#define LIBNDR_FLAG_STR_LEN4 (1<<3)
-#define LIBNDR_FLAG_STR_SIZE4 (1<<4)
-#define LIBNDR_FLAG_STR_NOTERM (1<<5)
-#define LIBNDR_FLAG_STR_NULLTERM (1<<6)
-#define LIBNDR_FLAG_STR_SIZE2 (1<<7)
-#define LIBNDR_FLAG_STR_BYTESIZE (1<<8)
-#define LIBNDR_FLAG_STR_FIXLEN32 (1<<9)
-#define LIBNDR_STRING_FLAGS (0x3FC)
-
-#define LIBNDR_FLAG_REF_ALLOC (1<<10)
-#define LIBNDR_FLAG_REMAINING (1<<11)
-#define LIBNDR_FLAG_ALIGN2 (1<<12)
-#define LIBNDR_FLAG_ALIGN4 (1<<13)
-#define LIBNDR_FLAG_ALIGN8 (1<<14)
+#define LIBNDR_FLAG_STR_ASCII (1<<2)
+#define LIBNDR_FLAG_STR_LEN4 (1<<3)
+#define LIBNDR_FLAG_STR_SIZE4 (1<<4)
+#define LIBNDR_FLAG_STR_NOTERM (1<<5)
+#define LIBNDR_FLAG_STR_NULLTERM (1<<6)
+#define LIBNDR_FLAG_STR_SIZE2 (1<<7)
+#define LIBNDR_FLAG_STR_BYTESIZE (1<<8)
+#define LIBNDR_FLAG_STR_FIXLEN32 (1<<9)
+#define LIBNDR_FLAG_STR_CONFORMANT (1<<10)
+#define LIBNDR_FLAG_STR_CHARLEN (1<<11)
+#define LIBNDR_STRING_FLAGS (0xFFC)
+
+
+#define LIBNDR_FLAG_REF_ALLOC (1<<20)
+#define LIBNDR_FLAG_REMAINING (1<<21)
+#define LIBNDR_FLAG_ALIGN2 (1<<22)
+#define LIBNDR_FLAG_ALIGN4 (1<<23)
+#define LIBNDR_FLAG_ALIGN8 (1<<24)
#define LIBNDR_ALIGN_FLAGS (LIBNDR_FLAG_ALIGN2|LIBNDR_FLAG_ALIGN4|LIBNDR_FLAG_ALIGN8)
-#define LIBNDR_PRINT_ARRAY_HEX (1<<15)
-#define LIBNDR_PRINT_SET_VALUES (1<<16)
+#define LIBNDR_PRINT_ARRAY_HEX (1<<25)
+#define LIBNDR_PRINT_SET_VALUES (1<<26)
/* used to force a section of IDL to be little-endian */
-#define LIBNDR_FLAG_LITTLE_ENDIAN (1<<17)
+#define LIBNDR_FLAG_LITTLE_ENDIAN (1<<27)
/* used to check if alignment padding is zero */
-#define LIBNDR_FLAG_PAD_CHECK (1<<18)
+#define LIBNDR_FLAG_PAD_CHECK (1<<28)
/* used to indicate spoolss style relative pointers (relative to current
offset, not base) */
-#define LIBNDR_FLAG_RELATIVE_CURRENT (1<<19)
+#define LIBNDR_FLAG_RELATIVE_CURRENT (1<<29)
/* useful macro for debugging */
diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c
index 95d8c28e75..84c4ab9ddc 100644
--- a/source4/librpc/ndr/ndr_basic.c
+++ b/source4/librpc/ndr/ndr_basic.c
@@ -522,6 +522,9 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
flags &= ~LIBNDR_FLAG_STR_ASCII;
}
+ flags &= ~LIBNDR_FLAG_STR_CONFORMANT;
+ flags &= ~LIBNDR_FLAG_STR_CHARLEN;
+
switch (flags & LIBNDR_STRING_FLAGS) {
case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
@@ -740,6 +743,7 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
int chset = CH_UTF16;
unsigned flags = ndr->flags;
unsigned byte_mul = 2;
+ unsigned c_len_term = 1;
if (!(ndr_flags & NDR_SCALARS)) {
return NT_STATUS_OK;
@@ -758,11 +762,18 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
flags &= ~LIBNDR_FLAG_STR_ASCII;
}
+ flags &= ~LIBNDR_FLAG_STR_CONFORMANT;
+
+ if (flags & LIBNDR_FLAG_STR_CHARLEN) {
+ c_len_term = 0;
+ flags &= ~LIBNDR_FLAG_STR_CHARLEN;
+ }
+
switch (flags & LIBNDR_STRING_FLAGS) {
case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
- NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
+ NDR_CHECK(ndr_push_uint32(ndr, c_len+c_len_term));
NDR_CHECK(ndr_push_uint32(ndr, 0));
- NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
+ NDR_CHECK(ndr_push_uint32(ndr, c_len+c_len_term));
NDR_PUSH_NEED_BYTES(ndr, byte_mul*(c_len+1));
ret = convert_string(CH_UNIX, chset,
s, s_len+1,
@@ -792,7 +803,7 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
case LIBNDR_FLAG_STR_LEN4:
NDR_CHECK(ndr_push_uint32(ndr, 0));
- NDR_CHECK(ndr_push_uint32(ndr, c_len + 1));
+ NDR_CHECK(ndr_push_uint32(ndr, c_len + c_len_term));
NDR_PUSH_NEED_BYTES(ndr, byte_mul*(c_len+1));
ret = convert_string(CH_UNIX, chset,
s, s_len + 1,
@@ -805,7 +816,7 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
break;
case LIBNDR_FLAG_STR_SIZE4:
- NDR_CHECK(ndr_push_uint32(ndr, c_len + 1));
+ NDR_CHECK(ndr_push_uint32(ndr, c_len + c_len_term));
NDR_PUSH_NEED_BYTES(ndr, byte_mul*(c_len+1));
ret = convert_string(CH_UNIX, chset,
s, s_len + 1,
@@ -818,7 +829,7 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
break;
case LIBNDR_FLAG_STR_SIZE2:
- NDR_CHECK(ndr_push_uint16(ndr, c_len + 1));
+ NDR_CHECK(ndr_push_uint16(ndr, c_len + c_len_term));
NDR_PUSH_NEED_BYTES(ndr, byte_mul*(c_len+1));
ret = convert_string(CH_UNIX, chset,
s, s_len + 1,
@@ -876,6 +887,40 @@ 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)
+{
+ size_t c_len;
+ unsigned flags = ndr->flags;
+ unsigned byte_mul = 2;
+ unsigned c_len_term = 1;
+
+ if (flags & LIBNDR_FLAG_STR_FIXLEN32) {
+ return 32;
+ }
+
+ c_len = s?strlen_m(s):0;
+
+ if (flags & LIBNDR_FLAG_STR_ASCII) {
+ byte_mul = 1;
+ }
+
+ if (flags & LIBNDR_FLAG_STR_NOTERM) {
+ c_len_term = 0;
+ }
+
+ c_len = c_len + c_len_term;
+
+ if (flags & LIBNDR_FLAG_STR_BYTESIZE) {
+ c_len = c_len * byte_mul;
+ }
+
+ return c_len;
+}
+
+
+/*
push a NTTIME
*/
NTSTATUS ndr_push_NTTIME(struct ndr_push *ndr, NTTIME t)