summaryrefslogtreecommitdiff
path: root/source4/librpc/ndr
diff options
context:
space:
mode:
Diffstat (limited to 'source4/librpc/ndr')
-rw-r--r--source4/librpc/ndr/libndr.h2
-rw-r--r--source4/librpc/ndr/ndr_compression.c153
2 files changed, 56 insertions, 99 deletions
diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h
index 3cc25b0ef2..15ac1b2d4c 100644
--- a/source4/librpc/ndr/libndr.h
+++ b/source4/librpc/ndr/libndr.h
@@ -162,7 +162,7 @@ enum ndr_err_code {
};
enum ndr_compression_alg {
- NDR_COMPRESSION_ZLIB
+ NDR_COMPRESSION_MSZIP
};
/*
diff --git a/source4/librpc/ndr/ndr_compression.c b/source4/librpc/ndr/ndr_compression.c
index f09007a715..c806f62189 100644
--- a/source4/librpc/ndr/ndr_compression.c
+++ b/source4/librpc/ndr/ndr_compression.c
@@ -21,27 +21,20 @@
*/
#include "includes.h"
+#include "lib/compression/mszip.h"
-#ifdef HAVE_ZLIB
-#include <zlib.h>
-
-static NTSTATUS ndr_pull_compression_zlib_chunk(struct ndr_pull *ndrpull,
- struct ndr_push *ndrpush,
- struct z_stream_s *zs, int i)
+static NTSTATUS ndr_pull_compression_mszip_chunk(struct ndr_pull *ndrpull,
+ struct ndr_push *ndrpush,
+ struct decomp_state *decomp_state)
{
- uint8_t *comp_chunk;
+ DATA_BLOB comp_chunk;
uint32_t comp_chunk_offset;
uint32_t comp_chunk_size;
- uint8_t *plain_chunk;
+ DATA_BLOB plain_chunk;
uint32_t plain_chunk_offset;
uint32_t plain_chunk_size;
- uint8_t C_CK_marker;
- uint8_t K_CK_marker;
int ret;
- /* I don't know why, this is needed... --metze */
- if (i == 5) ndrpull->offset -=4;
-
NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &plain_chunk_size));
if (plain_chunk_size > 0x00008000) {
return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "Bad ZLIB plain chunk size %08X > 0x00008000 (PULL)",
@@ -50,42 +43,23 @@ static NTSTATUS ndr_pull_compression_zlib_chunk(struct ndr_pull *ndrpull,
NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &comp_chunk_size));
- NDR_CHECK(ndr_pull_uint8(ndrpull, NDR_SCALARS, &C_CK_marker));
- NDR_CHECK(ndr_pull_uint8(ndrpull, NDR_SCALARS, &K_CK_marker));
- if (!(C_CK_marker == (uint8_t)'C' && K_CK_marker == (uint8_t)'K')) {
- return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "Bad ZLIB invalid CK marker C[%02X] K[%02X] (PULL)",
- C_CK_marker, K_CK_marker);
- }
-
DEBUG(10,("plain_chunk_size: %08X (%u) comp_chunk_size: %08X (%u)\n",
plain_chunk_size, plain_chunk_size, comp_chunk_size, comp_chunk_size));
comp_chunk_offset = ndrpull->offset;
NDR_CHECK(ndr_pull_advance(ndrpull, comp_chunk_size));
- comp_chunk = ndrpull->data + comp_chunk_offset;
+ comp_chunk.length = comp_chunk_size;
+ comp_chunk.data = ndrpull->data + comp_chunk_offset;
plain_chunk_offset = ndrpush->offset;
NDR_CHECK(ndr_push_zero(ndrpush, plain_chunk_size));
- plain_chunk = ndrpush->data + plain_chunk_offset;
-
- dump_data(10, comp_chunk, 16);
-
- zs->avail_in = comp_chunk_size;
- zs->next_in = comp_chunk;
- zs->next_out = plain_chunk;
- zs->avail_out = plain_chunk_size;
-
- while (True) {
- ret = inflate(zs, Z_BLOCK);
- if (ret == Z_STREAM_END) {
- DEBUG(0,("comp_chunk_size: %u avail_in: %d, plain_chunk_size: %u, avail_out: %d\n",
- comp_chunk_size, zs->avail_in, plain_chunk_size, zs->avail_out));
- break;
- }
- if (ret != Z_OK) {
- return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "Bad ZLIB (PULL) inflate error %d",
+ plain_chunk.length = plain_chunk_size;
+ plain_chunk.data = ndrpush->data + plain_chunk_offset;
+
+ ret = ZIPdecompress(decomp_state, &comp_chunk, &plain_chunk);
+ if (ret != DECR_OK) {
+ return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "Bad ZIBdecompress() error %d (PULL)",
ret);
- }
}
if ((plain_chunk_size < 0x00008000) || (ndrpull->offset+4 >= ndrpull->data_size)) {
@@ -96,84 +70,71 @@ static NTSTATUS ndr_pull_compression_zlib_chunk(struct ndr_pull *ndrpull,
return NT_STATUS_MORE_PROCESSING_REQUIRED;
}
-static NTSTATUS ndr_pull_compression_zlib(struct ndr_pull *subndr,
- struct ndr_pull *comndr,
- ssize_t decompressed_len)
+static NTSTATUS ndr_pull_compression_mszip(struct ndr_pull *subndr,
+ struct ndr_pull *comndr,
+ ssize_t decompressed_len)
{
NTSTATUS status = NT_STATUS_MORE_PROCESSING_REQUIRED;
struct ndr_push *ndrpush;
DATA_BLOB uncompressed;
- struct z_stream_s zs;
- int ret;
- int i = 0;
-
- ZERO_STRUCT(zs);
+ uint32_t payload_header[4];
+ uint32_t payload_size;
+ uint32_t payload_offset;
+ uint8_t *payload;
+ struct decomp_state *decomp_state;
ndrpush = ndr_push_init_ctx(subndr);
NT_STATUS_HAVE_NO_MEMORY(ndrpush);
- ret = inflateInit2(&zs, -15);
- if (ret != Z_OK) {
- return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad ZLIB (PULL) inflateInit2 error %d",
- ret);
- }
+ decomp_state = ZIPdecomp_state(subndr);
+ NT_STATUS_HAVE_NO_MEMORY(decomp_state);
while (NT_STATUS_EQUAL(NT_STATUS_MORE_PROCESSING_REQUIRED, status)) {
- status = ndr_pull_compression_zlib_chunk(subndr, ndrpush, &zs, i++);
+ status = ndr_pull_compression_mszip_chunk(subndr, ndrpush, decomp_state);
}
- inflateEnd(&zs);
NT_STATUS_NOT_OK_RETURN(status);
uncompressed = ndr_push_blob(ndrpush);
+ if (uncompressed.length != decompressed_len) {
+ return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad uncompressed_len [%u] != [%d] (PULL)",
+ uncompressed.length, decompressed_len);
+ }
+
*comndr = *subndr;
comndr->data = uncompressed.data;
comndr->data_size = uncompressed.length;
comndr->offset = 0;
- return NT_STATUS_OK;
-}
+ NDR_CHECK(ndr_pull_uint32(comndr, NDR_SCALARS, &payload_header[0]));
+ NDR_CHECK(ndr_pull_uint32(comndr, NDR_SCALARS, &payload_header[1]));
+ NDR_CHECK(ndr_pull_uint32(comndr, NDR_SCALARS, &payload_header[2]));
+ NDR_CHECK(ndr_pull_uint32(comndr, NDR_SCALARS, &payload_header[3]));
-static NTSTATUS ndr_push_compression_zlib(struct ndr_push *subndr,
- struct ndr_push *comndr)
-{
- DATA_BLOB inbuf;
- DATA_BLOB outbuf = data_blob_talloc(comndr, NULL, comndr->offset + 10);
- struct z_stream_s zs;
- int ret;
+ payload_size = payload_header[2];
- ZERO_STRUCT(zs);
-
- inbuf = ndr_push_blob(comndr);
-
- zs.avail_in = inbuf.length;
- zs.next_in = inbuf.data;
- zs.next_out = outbuf.data+10;
- zs.avail_out = outbuf.length-10;
-
- ret = deflateInit(&zs, Z_DEFAULT_COMPRESSION);
- if (ret != Z_OK) {
- return ndr_push_error(subndr, NDR_ERR_COMPRESSION, "Bad ZLIB (PUSH) deflateInit2 error %d",
- ret);
- }
-
- ret = deflate(&zs, Z_SYNC_FLUSH);
-
- if (ret != Z_OK && ret != Z_STREAM_END) {
- return ndr_push_error(subndr, NDR_ERR_COMPRESSION, "Bad ZLIB (PULL) deflate error %d",
- ret);
+ /* TODO: check the first 4 bytes of the header */
+ if (payload_header[1] != 0xCCCCCCCC) {
+ return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad payload_header[1] [0x%08X] != [0xCCCCCCCC] (PULL)",
+ payload_header[1]);
}
- deflateEnd(&zs);
+ payload_offset = comndr->offset;
+ NDR_CHECK(ndr_pull_advance(comndr, payload_size));
+ payload = comndr->data + payload_offset;
- /* TODO: push the header here */
-
-
- NDR_CHECK(ndr_push_bytes(subndr, outbuf.data, outbuf.length));
+ comndr->data = payload;
+ comndr->data_size = payload_size;
+ comndr->offset = 0;
return NT_STATUS_OK;
}
-#endif
+
+static NTSTATUS ndr_push_compression_mszip(struct ndr_push *subndr,
+ struct ndr_push *comndr)
+{
+ return ndr_push_error(subndr, NDR_ERR_COMPRESSION, "Bad MSZIP compression is not supported yet (PUSH)");
+}
/*
handle compressed subcontext buffers, which in midl land are user-marshalled, but
@@ -187,10 +148,8 @@ NTSTATUS ndr_pull_compression(struct ndr_pull *subndr,
comndr->flags = subndr->flags;
switch (compression_alg) {
-#ifdef HAVE_ZLIB
- case NDR_COMPRESSION_ZLIB:
- return ndr_pull_compression_zlib(subndr, comndr, decompressed_len);
-#endif
+ case NDR_COMPRESSION_MSZIP:
+ return ndr_pull_compression_mszip(subndr, comndr, decompressed_len);
default:
return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad compression algorithm %d (PULL)",
compression_alg);
@@ -208,10 +167,8 @@ NTSTATUS ndr_push_compression(struct ndr_push *subndr,
comndr->flags = subndr->flags;
switch (compression_alg) {
-#ifdef HAVE_ZLIB
- case NDR_COMPRESSION_ZLIB:
- return ndr_push_compression_zlib(subndr, comndr);
-#endif
+ case NDR_COMPRESSION_MSZIP:
+ return ndr_push_compression_mszip(subndr, comndr);
default:
return ndr_push_error(subndr, NDR_ERR_COMPRESSION, "Bad compression algorithm %d (PUSH)",
compression_alg);