summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2008-08-18 17:10:59 +0200
committerStefan Metzmacher <metze@samba.org>2008-08-20 15:22:04 +0200
commitf4e2f3f14c06f6de59bbacc899a2bfe6cfbcfeb2 (patch)
tree9d02dba371556b10fdd6762eb31a3f8074585894
parent9f2468af157a80de3b71b472ab8aa337b10c5f84 (diff)
downloadsamba-f4e2f3f14c06f6de59bbacc899a2bfe6cfbcfeb2.tar.gz
samba-f4e2f3f14c06f6de59bbacc899a2bfe6cfbcfeb2.tar.bz2
samba-f4e2f3f14c06f6de59bbacc899a2bfe6cfbcfeb2.zip
librpc/ndr: add support for Type Serialization Version 1 to subcontext
We use the header size 0xFFFFFC01 as magic for constructed types. See [MS-RPCE] 2.2.6 Type Serialization Version 1 for more details. metze (This used to be commit 98d3568f079ea143214bcf5271b636313d6491c3)
-rw-r--r--source4/librpc/ndr/ndr.c115
1 files changed, 114 insertions, 1 deletions
diff --git a/source4/librpc/ndr/ndr.c b/source4/librpc/ndr/ndr.c
index 40852456bc..c5e4c44794 100644
--- a/source4/librpc/ndr/ndr.c
+++ b/source4/librpc/ndr/ndr.c
@@ -394,6 +394,8 @@ _PUBLIC_ enum ndr_err_code ndr_pull_subcontext_start(struct ndr_pull *ndr,
{
struct ndr_pull *subndr;
uint32_t r_content_size;
+ bool force_le = false;
+ bool force_be = false;
switch (header_size) {
case 0: {
@@ -426,6 +428,74 @@ _PUBLIC_ enum ndr_err_code ndr_pull_subcontext_start(struct ndr_pull *ndr,
r_content_size = content_size;
break;
}
+ case 0xFFFFFC01: {
+ /*
+ * Common Type Header for the Serialization Stream
+ * See [MS-RPCE] 2.2.6 Type Serialization Version 1
+ */
+ uint8_t version;
+ uint8_t drep;
+ uint16_t hdrlen;
+ uint32_t filler;
+ uint32_t content_size;
+ uint32_t reserved;
+
+ /* version */
+ NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &version));
+
+ if (version != 1) {
+ return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT,
+ "Bad subcontext (PULL) Common Type Header version %d != 1",
+ (int)version);
+ }
+
+ /*
+ * 0x10 little endian
+ * 0x00 big endian
+ */
+ NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &drep));
+ if (drep == 0x10) {
+ force_le = true;
+ } else if (drep == 0x00) {
+ force_be = true;
+ } else {
+ return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT,
+ "Bad subcontext (PULL) Common Type Header invalid drep 0x%02X",
+ (unsigned int)drep);
+ }
+
+ /* length of the "Private Header for Constructed Type" */
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &hdrlen));
+ if (hdrlen != 8) {
+ return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT,
+ "Bad subcontext (PULL) Common Type Header length %d != 8",
+ (int)hdrlen);
+ }
+
+ /* filler should be ignored */
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &filler));
+
+ /*
+ * Private Header for Constructed Type
+ */
+ /* length - will be updated latter */
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &content_size));
+ if (size_is >= 0 && size_is != content_size) {
+ return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) size_is(%d) mismatch content_size %d",
+ (int)size_is, (int)content_size);
+ }
+ /* the content size must be a multiple of 8 */
+ if ((content_size % 8) != 0) {
+ return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT,
+ "Bad subcontext (PULL) size_is(%d) not padded to 8 content_size %d",
+ (int)size_is, (int)content_size);
+ }
+ r_content_size = content_size;
+
+ /* reserved */
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &reserved));
+ break;
+ }
default:
return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) header_size %d",
(int)header_size);
@@ -443,6 +513,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_subcontext_start(struct ndr_pull *ndr,
subndr->data_size = r_content_size;
subndr->iconv_convenience = talloc_reference(subndr, ndr->iconv_convenience);
+ if (force_le) {
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_LITTLE_ENDIAN);
+ } else if (force_be) {
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN);
+ }
+
*_subndr = subndr;
return NDR_ERR_SUCCESS;
}
@@ -487,8 +563,10 @@ _PUBLIC_ enum ndr_err_code ndr_push_subcontext_end(struct ndr_push *ndr,
size_t header_size,
ssize_t size_is)
{
+ ssize_t padding_len;
+
if (size_is >= 0) {
- ssize_t padding_len = size_is - subndr->offset;
+ padding_len = size_is - subndr->offset;
if (padding_len > 0) {
NDR_CHECK(ndr_push_zero(subndr, padding_len));
} else if (padding_len < 0) {
@@ -509,6 +587,41 @@ _PUBLIC_ enum ndr_err_code ndr_push_subcontext_end(struct ndr_push *ndr,
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, subndr->offset));
break;
+ case 0xFFFFFC01:
+ /*
+ * Common Type Header for the Serialization Stream
+ * See [MS-RPCE] 2.2.6 Type Serialization Version 1
+ */
+ padding_len = NDR_ROUND(subndr->offset, 8) - subndr->offset;
+ if (padding_len > 0) {
+ NDR_CHECK(ndr_push_zero(subndr, padding_len));
+ }
+
+ /* version */
+ NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, 1));
+
+ /*
+ * 0x10 little endian
+ * 0x00 big endian
+ */
+ NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, NDR_BE(ndr)?0x00:0x10));
+
+ /* length of the "Private Header for Constructed Type" */
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 8));
+
+ /* filler */
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0xCCCCCCCC));
+
+ /*
+ * Private Header for Constructed Type
+ */
+ /* length - will be updated latter */
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, subndr->offset));
+
+ /* reserved */
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
+ break;
+
default:
return ndr_push_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext header size %d",
(int)header_size);