From 1edf126693b8bafe5f94a6ab4d34e0d21a05cb3d Mon Sep 17 00:00:00 2001 From: Aurelien Aptel Date: Tue, 23 May 2017 12:02:33 +0200 Subject: librpc/ndr: add helper functions to setup and free compression states. Signed-off-by: Aurelien Aptel Reviewed-by: Guenther Deschner Reviewed-by: Jeremy Allison --- librpc/ndr/ndr_compression.c | 145 +++++++++++++++++++++++++++++++++++++++++++ librpc/ndr/ndr_compression.h | 10 +++ 2 files changed, 155 insertions(+) (limited to 'librpc') diff --git a/librpc/ndr/ndr_compression.c b/librpc/ndr/ndr_compression.c index b2cb4341058..b0408d58a15 100644 --- a/librpc/ndr/ndr_compression.c +++ b/librpc/ndr/ndr_compression.c @@ -524,3 +524,148 @@ enum ndr_err_code ndr_push_compression_end(struct ndr_push *subndr, talloc_free(uncomndr); return NDR_ERR_SUCCESS; } + +static enum ndr_err_code generic_mszip_init(TALLOC_CTX *mem_ctx, + struct ndr_compression_state *state) +{ + z_stream *z = talloc_zero(mem_ctx, z_stream); + NDR_ERR_HAVE_NO_MEMORY(z); + + z->zalloc = ndr_zlib_alloc; + z->zfree = ndr_zlib_free; + z->opaque = mem_ctx; + + state->mszip.z = z; + state->mszip.dict_size = 0; + /* pre-alloc dictionnary */ + state->mszip.dict = talloc_array(mem_ctx, uint8_t, 0x8000); + NDR_ERR_HAVE_NO_MEMORY(state->mszip.dict); + + return NDR_ERR_SUCCESS; +} + +static void generic_mszip_free(struct ndr_compression_state *state) +{ + if (state == NULL) { + return; + } + + TALLOC_FREE(state->mszip.z); + TALLOC_FREE(state->mszip.dict); +} + + +enum ndr_err_code ndr_pull_compression_state_init(struct ndr_pull *ndr, + enum ndr_compression_alg compression_alg, + struct ndr_compression_state **state) +{ + struct ndr_compression_state *s; + int z_ret; + + s = talloc_zero(ndr, struct ndr_compression_state); + NDR_ERR_HAVE_NO_MEMORY(s); + s->type = compression_alg; + + switch (compression_alg) { + case NDR_COMPRESSION_MSZIP: + case NDR_COMPRESSION_XPRESS: + break; + case NDR_COMPRESSION_MSZIP_CAB: + NDR_CHECK(generic_mszip_init(ndr, s)); + z_ret = inflateInit2(s->mszip.z, -MAX_WBITS); + if (z_ret != Z_OK) { + return ndr_pull_error(ndr, NDR_ERR_COMPRESSION, + "zlib inflateinit2 error %s (%d) %s (PULL)", + zError(z_ret), z_ret, s->mszip.z->msg); + } + break; + default: + return ndr_pull_error(ndr, NDR_ERR_COMPRESSION, + "Bad compression algorithm %d (PULL)", + compression_alg); + break; + } + + *state = s; + + return NDR_ERR_SUCCESS; +} + +void ndr_pull_compression_state_free(struct ndr_compression_state *state) +{ + if (state == NULL) { + return; + } + + switch (state->type) { + case NDR_COMPRESSION_MSZIP: + case NDR_COMPRESSION_XPRESS: + break; + case NDR_COMPRESSION_MSZIP_CAB: + generic_mszip_free(state); + break; + default: + break; + } + TALLOC_FREE(state); +} + +enum ndr_err_code ndr_push_compression_state_init(struct ndr_push *ndr, + enum ndr_compression_alg compression_alg, + struct ndr_compression_state **state) +{ + struct ndr_compression_state *s; + int z_ret; + + s = talloc_zero(ndr, struct ndr_compression_state); + NDR_ERR_HAVE_NO_MEMORY(s); + s->type = compression_alg; + + switch (compression_alg) { + case NDR_COMPRESSION_XPRESS: + case NDR_COMPRESSION_MSZIP: + break; + case NDR_COMPRESSION_MSZIP_CAB: + NDR_CHECK(generic_mszip_init(ndr, s)); + z_ret = deflateInit2(s->mszip.z, + Z_DEFAULT_COMPRESSION, + Z_DEFLATED, + -MAX_WBITS, + 8, /* memLevel */ + Z_DEFAULT_STRATEGY); + if (z_ret != Z_OK) { + return ndr_push_error(ndr, NDR_ERR_COMPRESSION, + "zlib inflateinit2 error %s (%d) %s (PUSH)", + zError(z_ret), z_ret, s->mszip.z->msg); + } + break; + default: + return ndr_push_error(ndr, NDR_ERR_COMPRESSION, + "Bad compression algorithm %d (PUSH)", + compression_alg); + break; + } + + *state = s; + + return NDR_ERR_SUCCESS; +} + +void ndr_push_compression_state_free(struct ndr_compression_state *state) +{ + if (state == NULL) { + return; + } + + switch (state->type) { + case NDR_COMPRESSION_MSZIP: + case NDR_COMPRESSION_XPRESS: + break; + case NDR_COMPRESSION_MSZIP_CAB: + generic_mszip_free(state); + break; + default: + break; + } + TALLOC_FREE(state); +} diff --git a/librpc/ndr/ndr_compression.h b/librpc/ndr/ndr_compression.h index d682d4d3693..a67a73ed7d6 100644 --- a/librpc/ndr/ndr_compression.h +++ b/librpc/ndr/ndr_compression.h @@ -51,6 +51,16 @@ enum ndr_err_code ndr_push_compression_end(struct ndr_push *subndr, struct ndr_push *uncomndr, enum ndr_compression_alg compression_alg, ssize_t decompressed_len); + +enum ndr_err_code ndr_pull_compression_state_init(struct ndr_pull *ndr, + enum ndr_compression_alg compression_alg, + struct ndr_compression_state **state); +void ndr_pull_compression_state_free(struct ndr_compression_state *state); +enum ndr_err_code ndr_push_compression_state_init(struct ndr_push *ndr, + enum ndr_compression_alg compression_alg, + struct ndr_compression_state **state); +void ndr_push_compression_state_free(struct ndr_compression_state *state); + #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) -- cgit v1.2.1