diff options
Diffstat (limited to 'source4/librpc')
-rw-r--r-- | source4/librpc/idl/idl_types.h | 1 | ||||
-rw-r--r-- | source4/librpc/ndr/libndr.h | 1 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_basic.c | 58 |
3 files changed, 54 insertions, 6 deletions
diff --git a/source4/librpc/idl/idl_types.h b/source4/librpc/idl/idl_types.h index d36e51f8be..2140d44b20 100644 --- a/source4/librpc/idl/idl_types.h +++ b/source4/librpc/idl/idl_types.h @@ -4,6 +4,7 @@ #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 /* 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 7ab5de52fa..a7f90798b9 100644 --- a/source4/librpc/ndr/libndr.h +++ b/source4/librpc/ndr/libndr.h @@ -98,6 +98,7 @@ struct ndr_print { #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_STRING_FLAGS (0xFC) #define LIBNDR_FLAG_REF_ALLOC (1<<10) diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c index 88a58e91fd..d495bf2946 100644 --- a/source4/librpc/ndr/ndr_basic.c +++ b/source4/librpc/ndr/ndr_basic.c @@ -472,6 +472,7 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s) break; case LIBNDR_FLAG_STR_SIZE4: + case LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM: NDR_CHECK(ndr_pull_uint32(ndr, &len1)); NDR_PULL_NEED_BYTES(ndr, len1*2); if (len1 == 0) { @@ -487,6 +488,37 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s) "Bad character conversion"); } NDR_CHECK(ndr_pull_advance(ndr, len1*2)); + + /* this is a way of detecting if a string is sent with the wrong + termination */ + if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) { + if (strlen(as) < len1) { + DEBUG(6,("short string '%s'\n", as)); + } + } else { + if (strlen(as) == len1) { + DEBUG(6,("long string '%s'\n", as)); + } + } + *s = as; + break; + + case LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_STR_BYTESIZE: + NDR_CHECK(ndr_pull_uint16(ndr, &len3)); + NDR_PULL_NEED_BYTES(ndr, len3); + if (len3 == 0) { + *s = talloc_strdup(ndr->mem_ctx, ""); + break; + } + ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX, + ndr->data+ndr->offset, + len3, + (const void **)&as); + if (ret == -1) { + return ndr_pull_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + NDR_CHECK(ndr_pull_advance(ndr, len3)); *s = as; break; @@ -499,12 +531,13 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s) ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX, ndr->data+ndr->offset, len1*2, - (const void **)s); + (const void **)&as); if (ret == -1) { return ndr_pull_error(ndr, NDR_ERR_CHARCNV, "Bad character conversion"); } NDR_CHECK(ndr_pull_advance(ndr, len1*2)); + *s = as; break; case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4: @@ -520,7 +553,7 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s) NDR_ALLOC_N(ndr, as, (len2+1)); NDR_CHECK(ndr_pull_bytes(ndr, as, len2)); as[len2] = 0; - (*s) = as; + *s = as; break; case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4: @@ -529,7 +562,7 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s) NDR_ALLOC_N(ndr, as, (len2+1)); NDR_CHECK(ndr_pull_bytes(ndr, as, len2)); as[len2] = 0; - (*s) = as; + *s = as; break; case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2: @@ -537,7 +570,7 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s) NDR_ALLOC_N(ndr, as, (len3+1)); NDR_CHECK(ndr_pull_bytes(ndr, as, len3)); as[len3] = 0; - (*s) = as; + *s = as; break; case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM: @@ -548,7 +581,7 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s) NDR_ALLOC_N(ndr, as, (len1+1)); NDR_CHECK(ndr_pull_bytes(ndr, as, len1)); as[len1] = 0; - (*s) = as; + *s = as; break; default: @@ -635,7 +668,20 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s) } ndr->offset += c_len*2 + 2; break; - + + case LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_STR_BYTESIZE: + NDR_CHECK(ndr_push_uint16(ndr, c_len*2)); + NDR_PUSH_NEED_BYTES(ndr, c_len*2); + ret = convert_string(CH_UNIX, chset, + s, s_len, + ndr->data+ndr->offset, c_len*2); + if (ret == -1) { + return ndr_push_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + ndr->offset += c_len*2; + break; + case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4: NDR_CHECK(ndr_push_uint32(ndr, c_len+1)); NDR_CHECK(ndr_push_uint32(ndr, 0)); |