diff options
Diffstat (limited to 'source4/librpc/ndr')
-rw-r--r-- | source4/librpc/ndr/libndr.h | 2 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_compression.c | 153 |
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); |