The branch, master has been updated
       via  7313e7c s4-torture: point out why we cannot validate MSZIP 
compressed files
       via  c60ad39 librpc/ndr: add MSZIP compression for cabinet files
       via  43a1952 librpc/ndr: simplify cabinet file size calculation
       via  7c20a87 librpc/ndr: Use correct value for max compression size
       via  a281612 librpc/ndr: Use MAX_WBITS zlib define and change memLevel 
in MSZIP code
       via  9ec74a3 librpc/ndr: remove unused ndr_cab_get_compression() function
       via  466d5e8 librpc: use DATA_BLOB in CFDATA structure
       via  1edf126 librpc/ndr: add helper functions to setup and free 
compression states.
       via  096efc9 librpc/ndr: add new MSZIP compression type for cabinet files
       via  aa33aa6 librpc/ndr: add new ndr_compression_state
       via  a44bce6 libndr/compression: pass down compressed length in 
ndr_pull_compression_start
       via  3b5442e librpc/ndr: remove trailing whitespace from compression 
file.
       via  9a2180c librpc:ndr_cab: Cast data pointer correctly
       via  e54adf5 ndr_compression: use MAX_WBITS constant
       via  0181fcc smbd: Fix a connection run-down race condition
      from  1b7b7a9 examples: add winbindd.stp and a shell script to generate it

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 7313e7c10df438fdf980ff9da80637df9f8dcb89
Author: Günther Deschner <[email protected]>
Date:   Tue May 23 15:50:55 2017 +0200

    s4-torture: point out why we cannot validate MSZIP compressed files
    
    Guenther
    
    Signed-off-by: Guenther Deschner <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    
    Autobuild-User(master): Jeremy Allison <[email protected]>
    Autobuild-Date(master): Thu Jul 20 01:38:02 CEST 2017 on sn-devel-144

commit c60ad394fa0da0d8dfbd9f3336b422f26bed8378
Author: Aurelien Aptel <[email protected]>
Date:   Tue May 23 12:09:28 2017 +0200

    librpc/ndr: add MSZIP compression for cabinet files
    
    Signed-off-by: Aurelien Aptel <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 43a1952b17c71b336af79411d9e26b5d91900998
Author: Aurelien Aptel <[email protected]>
Date:   Tue May 23 15:41:24 2017 +0200

    librpc/ndr: simplify cabinet file size calculation
    
    Signed-off-by: Aurelien Aptel <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 7c20a87097f506215423ea7494956fd1d993e36d
Author: Andreas Schneider <[email protected]>
Date:   Wed Jun 21 17:01:43 2017 +0200

    librpc/ndr: Use correct value for max compression size
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit a2816122f9a94b2edc0e464ed44353409357f182
Author: Günther Deschner <[email protected]>
Date:   Tue May 23 15:48:42 2017 +0200

    librpc/ndr: Use MAX_WBITS zlib define and change memLevel in MSZIP code
    
    Guenther
    
    Signed-off-by: Günther Deschner <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 9ec74a319fc6cbaf5a0159ef9323cd18e79c010f
Author: Aurelien Aptel <[email protected]>
Date:   Tue May 23 15:37:13 2017 +0200

    librpc/ndr: remove unused ndr_cab_get_compression() function
    
    Signed-off-by: Aurelien Aptel <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 466d5e814727046dd630d5503b43874ec46a365e
Author: Aurelien Aptel <[email protected]>
Date:   Tue May 23 15:31:44 2017 +0200

    librpc: use DATA_BLOB in CFDATA structure
    
    Signed-off-by: Aurelien Aptel <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 1edf126693b8bafe5f94a6ab4d34e0d21a05cb3d
Author: Aurelien Aptel <[email protected]>
Date:   Tue May 23 12:02:33 2017 +0200

    librpc/ndr: add helper functions to setup and free compression states.
    
    Signed-off-by: Aurelien Aptel <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 096efc93df490117b1de3bd2647bad52a7175a7f
Author: Günther Deschner <[email protected]>
Date:   Tue May 23 12:02:10 2017 +0200

    librpc/ndr: add new MSZIP compression type for cabinet files
    
    Guenther
    
    Signed-off-by: Guenther Deschner <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit aa33aa6e64b3306ffb777ed690a60c5576e8514b
Author: Aurelien Aptel <[email protected]>
Date:   Tue May 23 11:59:59 2017 +0200

    librpc/ndr: add new ndr_compression_state
    
    Signed-off-by: Aurelien Aptel <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit a44bce6dfab59a6440ccc30ef0968d59b9f43fd3
Author: Günther Deschner <[email protected]>
Date:   Tue Sep 20 00:18:43 2016 +0200

    libndr/compression: pass down compressed length in 
ndr_pull_compression_start
    
    Guenther
    
    Signed-off-by: Guenther Deschner <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 3b5442e77bc80f81a4c5ddd69d1544c25e125f4e
Author: Aurelien Aptel <[email protected]>
Date:   Tue Jan 24 19:00:53 2017 +0100

    librpc/ndr: remove trailing whitespace from compression file.
    
    Signed-off-by: Aurelien Aptel <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 9a2180cd04a2885d519fa3bac6fd2a30a8a1155f
Author: Andreas Schneider <[email protected]>
Date:   Tue May 9 16:51:43 2017 +0200

    librpc:ndr_cab: Cast data pointer correctly
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Guenther Deschner <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit e54adf516e5c6546e45fb0efbb43f3c45f8917d1
Author: Aurelien Aptel <[email protected]>
Date:   Fri Jun 30 15:07:31 2017 +0200

    ndr_compression: use MAX_WBITS constant
    
    Signed-off-by: Aurelien Aptel <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 0181fcc4aaa730e3a88ff5d397145332f4013950
Author: Volker Lendecke <[email protected]>
Date:   Wed Jul 19 14:51:33 2017 +0200

    smbd: Fix a connection run-down race condition
    
    When we do a server exit with active aio jobs, we need to keep the
    aio state active for the helper thread. Right now I don't see another
    chance than to leak memory in this case. And, I don't really oversee
    how cancelling requests works in this case, but this does fix crashes
    seen at a customer site.
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 librpc/idl/cab.idl                       |   2 +-
 librpc/ndr/libndr.h                      |   7 +
 librpc/ndr/ndr_cab.c                     | 290 ++++++++++++++++----
 librpc/ndr/ndr_cab.h                     |   1 -
 librpc/ndr/ndr_compression.c             | 453 ++++++++++++++++++++++++++++++-
 librpc/ndr/ndr_compression.h             |  13 +-
 pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm |   3 +-
 source3/modules/vfs_default.c            |  33 ++-
 source4/torture/ndr/cabinet.c            |  18 +-
 9 files changed, 732 insertions(+), 88 deletions(-)


Changeset truncated at 500 lines:

diff --git a/librpc/idl/cab.idl b/librpc/idl/cab.idl
index 2174bce..9f3a02c 100644
--- a/librpc/idl/cab.idl
+++ b/librpc/idl/cab.idl
@@ -117,7 +117,7 @@ import "misc.idl";
 #if 0
                uint8 abReserve[];      /* (optional) per-datablock reserved 
area */
 #endif
-               uint8 ab[cbData];       /* compressed data bytes */
+               DATA_BLOB ab;   /* compressed data bytes */
        } CFDATA;
 
        typedef 
[nopush,nopull,public,flag(NDR_PAHEX|NDR_LITTLE_ENDIAN|NDR_NOALIGN)] struct {
diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
index 072fd66..de93893 100644
--- a/librpc/ndr/libndr.h
+++ b/librpc/ndr/libndr.h
@@ -47,6 +47,8 @@ struct ndr_token_list {
        uint32_t count;
 };
 
+struct ndr_compression_state;
+
 /* this is the base structure passed to routines that
    parse MSRPC formatted data
 
@@ -71,6 +73,8 @@ struct ndr_pull {
        struct ndr_token_list array_length_list;
        struct ndr_token_list switch_list;
 
+       struct ndr_compression_state *cstate;
+
        TALLOC_CTX *current_mem_ctx;
 
        /* this is used to ensure we generate unique reference IDs
@@ -97,6 +101,8 @@ struct ndr_push {
        struct ndr_token_list dns_string_list;
        struct ndr_token_list full_ptr_list;
 
+       struct ndr_compression_state *cstate;
+
        /* this is used to ensure we generate unique reference IDs */
        uint32_t ptr_count;
 };
@@ -256,6 +262,7 @@ enum ndr_err_code {
 } while (0)
 
 enum ndr_compression_alg {
+       NDR_COMPRESSION_MSZIP_CAB = 1,
        NDR_COMPRESSION_MSZIP   = 2,
        NDR_COMPRESSION_XPRESS  = 3
 };
diff --git a/librpc/ndr/ndr_cab.c b/librpc/ndr/ndr_cab.c
index ae95bf4..837ed25 100644
--- a/librpc/ndr/ndr_cab.c
+++ b/librpc/ndr/ndr_cab.c
@@ -21,6 +21,9 @@
 
 #include "includes.h"
 #include "librpc/gen_ndr/ndr_cab.h"
+#include "librpc/ndr/ndr_compression.h"
+
+#define OFFSET_OF_FOLDER_COFFCABSTART(folder) (36 /* cfheader size */ + 
(size_t)(folder)*8)
 
 _PUBLIC_ void ndr_print_cf_time(struct ndr_print *ndr, const char *name, const 
struct cf_time *r)
 {
@@ -79,7 +82,7 @@ static uint32_t ndr_cab_compute_checksum(uint8_t *data, 
uint32_t length, uint32_
        pb = data;
 
        while (num_ulong-- > 0) {
-               ul = *pb++;
+               ul = (uint32_t)(*pb++);
                ul |= (((uint32_t)(*pb++)) <<  8);
                ul |= (((uint32_t)(*pb++)) << 16);
                ul |= (((uint32_t)(*pb++)) << 24);
@@ -95,7 +98,7 @@ static uint32_t ndr_cab_compute_checksum(uint8_t *data, 
uint32_t length, uint32_
        case 2:
                ul |= (((uint32_t)(*pb++)) <<  8);
        case 1:
-               ul |= *pb++;
+               ul |= (uint32_t)(*pb++);
        default:
                break;
        }
@@ -109,97 +112,182 @@ uint32_t ndr_cab_generate_checksum(const struct CFDATA 
*r)
 {
        uint32_t csumPartial;
 
-       csumPartial = ndr_cab_compute_checksum(&r->ab[0], r->cbData, 0);
+       csumPartial = ndr_cab_compute_checksum(&r->ab.data[0], r->cbData, 0);
 
        return ndr_cab_compute_checksum((uint8_t *)discard_const(&r->cbData),
                                        sizeof(r->cbData) + sizeof(r->cbUncomp),
                                        csumPartial);
 }
 
-static bool ndr_size_cab_file(const struct cab_file *r, uint32_t *psize)
+/* Push all CFDATA of a folder.
+ *
+ * This works on a folder level because compression type is set per
+ * folder, and a compression state can be shared between CFDATA of the
+ * same folder.
+ *
+ * This is not a regular NDR func as we pass the compression type and
+ * the number of CFDATA as extra arguments
+ */
+static enum ndr_err_code ndr_push_folder_cfdata(struct ndr_push *ndr,
+                                               const struct CFDATA *r,
+                                               enum cf_compress_type cab_ctype,
+                                               size_t num_cfdata)
 {
-       uint32_t size = 0;
-       int i;
+       size_t i;
+       enum ndr_compression_alg ndr_ctype = 0;
 
-       /* header */
-       size += 36;
+       ndr_set_flags(&ndr->flags, 
LIBNDR_PRINT_ARRAY_HEX|LIBNDR_FLAG_LITTLE_ENDIAN|LIBNDR_FLAG_NOALIGN);
 
-       /* folder */
-       for (i = 0; i < r->cfheader.cFolders; i++) {
-               if (size + 8 < size) {
-                       /* Integer wrap. */
-                       return false;
-               }
-               size += 8;
+       if (cab_ctype == CF_COMPRESS_MSZIP) {
+               ndr_ctype = NDR_COMPRESSION_MSZIP_CAB;
+               NDR_CHECK(ndr_push_compression_state_init(ndr, ndr_ctype, 
&ndr->cstate));
        }
 
-       /* files */
-       for (i = 0; i < r->cfheader.cFiles; i++) {
-               uint32_t cfsize = ndr_size_CFFILE(&r->cffiles[i], 0);
-               if (size + cfsize < size) {
-                       /* Integer wrap. */
-                       return false;
-               }
-               size += cfsize;
-       }
+       for (i = 0; i < num_cfdata; i++, r++) {
+               uint32_t compressed_length = 0;
+               uint32_t csum, csumPartial;
+               size_t compressed_offset, csum_offset, data_offset;
 
-       /* data */
-       for (i = 0; i < ndr_count_cfdata(r); i++) {
-               if (size + 8 < size) {
-                       /* Integer wrap. */
-                       return false;
+               if (!r->ab.data) {
+                       return ndr_push_error(ndr, NDR_ERR_LENGTH,
+                                             "NULL uncompressed data blob");
                }
-               size += 8;
-               if (size + r->cfdata[i].cbData < size) {
-                       /* Integer wrap. */
-                       return false;
+               if (r->ab.length != r->cbUncomp) {
+                       return ndr_push_error(ndr, NDR_ERR_LENGTH,
+                                             "Uncompressed data blob size != 
uncompressed data size field");
                }
-               size += r->cfdata[i].cbData;
-       }
 
-       *psize = size;
-       return true;
-}
+               /*
+                * checksum is a function of the size fields
+                * and the potentially compressed data bytes,
+                * which haven't been compressed yet so
+                * remember offset, write zeroes, fill out
+                * later
+                */
+               csum_offset = ndr->offset;
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
+
+               /*
+                * similarly, we don't know the compressed
+                * size yet, remember offset, write zeros,
+                * fill out later
+                */
+               compressed_offset = ndr->offset;
+               NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 0));
+               NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->cbUncomp));
+
+               data_offset = ndr->offset;
+
+               switch (cab_ctype) {
+               case CF_COMPRESS_NONE:
+                       /* just copy the data */
+                       NDR_PUSH_NEED_BYTES(ndr, r->ab.length);
+                       NDR_CHECK(ndr_push_bytes(ndr, r->ab.data, 
r->ab.length));
+                       compressed_length = r->ab.length;
+                       break;
+               case CF_COMPRESS_LZX:
+                       /*
+                        * we have not yet worked out the details of LZX
+                        * compression
+                        */
+                       return NDR_ERR_COMPRESSION;
+
+               case CF_COMPRESS_MSZIP: {
+                       struct ndr_push *push_sub, *push_compress;
+
+                       /* compress via subcontext */
+                       NDR_CHECK(ndr_push_subcontext_start(ndr, &push_sub, 0, 
-1));
+                       push_sub->cstate = ndr->cstate;
+                       NDR_CHECK(ndr_push_compression_start(push_sub, 
&push_compress, ndr_ctype, -1));
+                       ndr_set_flags(&push_compress->flags, 
LIBNDR_FLAG_REMAINING);
+                       NDR_CHECK(ndr_push_DATA_BLOB(push_compress, 
NDR_SCALARS, r->ab));
+                       NDR_CHECK(ndr_push_compression_end(push_sub, 
push_compress, ndr_ctype, -1));
+                       NDR_CHECK(ndr_push_subcontext_end(ndr, push_sub, 0, 
-1));
+                       compressed_length = push_sub->offset;
+
+                       break;
+                       }
+               default:
+                       return NDR_ERR_BAD_SWITCH;
+               }
 
-enum cf_compress_type ndr_cab_get_compression(const struct cab_file *r)
-{
-       if (r->cfheader.cFolders == 0) {
-               return CF_COMPRESS_NONE;
+               /* we can now write the compressed size and the checksum */
+               SSVAL(ndr->data, compressed_offset, compressed_length);
+
+               /*
+                * Create checksum over compressed data.
+                *
+                * The 8 bytes are the header size.
+                *
+                * We have already have written the checksum and set it to zero,
+                * earlier. So we know that after the checksum end the value
+                * for the compressed length comes the blob data.
+                *
+                * NDR already did all the checks for integer wraps.
+                */
+               csumPartial = ndr_cab_compute_checksum(&ndr->data[data_offset],
+                                                      compressed_length, 0);
+
+               /*
+                * Checksum over header (compressed and uncompressed length).
+                *
+                * The first 4 bytes are the checksum size.
+                * The second 4 bytes are the size of the compressed and
+                * uncompressed length fields.
+                *
+                * NDR already did all the checks for integer wraps.
+                */
+               csum = ndr_cab_compute_checksum(&ndr->data[compressed_offset],
+                                               data_offset - compressed_offset,
+                                               csumPartial);
+
+               SIVAL(ndr->data, csum_offset, csum);
        }
 
-       return r->cffolders[0].typeCompress;
+       ndr_push_compression_state_free(ndr->cstate);
+       ndr->cstate = NULL;
+
+       return NDR_ERR_SUCCESS;
 }
 
 _PUBLIC_ enum ndr_err_code ndr_push_cab_file(struct ndr_push *ndr, int 
ndr_flags, const struct cab_file *r)
 {
        uint32_t cntr_cffolders_0;
        uint32_t cntr_cffiles_0;
-       uint32_t cntr_cfdata_0;
-       uint32_t cab_size = 0;
+       size_t processed_cfdata = 0;
        {
                uint32_t _flags_save_STRUCT = ndr->flags;
                ndr_set_flags(&ndr->flags, 
LIBNDR_PRINT_ARRAY_HEX|LIBNDR_FLAG_LITTLE_ENDIAN|LIBNDR_FLAG_NOALIGN);
                NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+
                if (ndr_flags & NDR_SCALARS) {
-                       uint32_t next_offset = 0;
+                       uint32_t i;
                        NDR_CHECK(ndr_push_align(ndr, 4));
                        NDR_CHECK(ndr_push_CFHEADER(ndr, NDR_SCALARS, 
&r->cfheader));
                        for (cntr_cffolders_0 = 0; cntr_cffolders_0 < 
(r->cfheader.cFolders); cntr_cffolders_0++) {
                                NDR_CHECK(ndr_push_CFFOLDER(ndr, NDR_SCALARS, 
&r->cffolders[cntr_cffolders_0]));
                        }
                        for (cntr_cffiles_0 = 0; cntr_cffiles_0 < 
(r->cfheader.cFiles); cntr_cffiles_0++) {
-                               uint32_t offset = ndr->offset + 4;
                                NDR_CHECK(ndr_push_CFFILE(ndr, NDR_SCALARS, 
&r->cffiles[cntr_cffiles_0]));
-                               if (cntr_cffiles_0 > 0) {
-                                       next_offset += 
r->cffiles[cntr_cffiles_0 - 1].cbFile;
-                               }
-                               SIVAL(ndr->data, offset, next_offset);
                        }
 #if 0
                        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 
ndr_count_cfdata(r)));
 #endif
-                       for (cntr_cfdata_0 = 0; cntr_cfdata_0 < 
(ndr_count_cfdata(r)); cntr_cfdata_0++) {
-                               NDR_CHECK(ndr_push_CFDATA(ndr, NDR_SCALARS, 
&r->cfdata[cntr_cfdata_0]));
+
+                       /* write in the folder header the offset of its first 
data block */
+                       for (i = 0; i < r->cfheader.cFolders; i++) {
+                               size_t off = OFFSET_OF_FOLDER_COFFCABSTART(i);
+                               /* check that the offset we want to
+                                * write to is always inside our
+                                * current push buffer
+                                */
+                               if (off >= ndr->offset) {
+                                       return ndr_push_error(ndr, 
NDR_ERR_OFFSET,
+                                                             "trying to write 
past current push buffer size");
+                               }
+                               SIVAL(ndr->data, off, ndr->offset);
+                               NDR_CHECK(ndr_push_folder_cfdata(ndr, r->cfdata 
+ processed_cfdata, r->cffolders[i].typeCompress, r->cffolders[i].cCFData));
+                               processed_cfdata += r->cffolders[i].cCFData;
                        }
                        NDR_CHECK(ndr_push_trailer_align(ndr, 4));
                }
@@ -208,10 +296,90 @@ _PUBLIC_ enum ndr_err_code ndr_push_cab_file(struct 
ndr_push *ndr, int ndr_flags
                ndr->flags = _flags_save_STRUCT;
        }
 
-       if (ndr_size_cab_file(r, &cab_size) == false) {
-               return NDR_ERR_VALIDATE;
+
+       /* write total file size in header */
+       SIVAL(ndr->data, 8, ndr->offset);
+
+       return NDR_ERR_SUCCESS;
+}
+
+
+/* Pull all CFDATA of a folder.
+ *
+ * This works on a folder level because compression type is set per
+ * folder, and a compression state can be shared between CFDATA of the
+ * same folder.
+ *
+ * This is not a regular NDR func as we pass the compression type and
+ * the number of CFDATA as extra arguments
+ */
+static enum ndr_err_code ndr_pull_folder_cfdata(struct ndr_pull *ndr,
+                                               struct CFDATA *r,
+                                               enum cf_compress_type cab_ctype,
+                                               size_t num_cfdata)
+{
+       size_t i;
+       enum ndr_compression_alg ndr_ctype = 0;
+
+       if (cab_ctype == CF_COMPRESS_MSZIP) {
+               ndr_ctype = NDR_COMPRESSION_MSZIP_CAB;
+               NDR_CHECK(ndr_pull_compression_state_init(ndr, 
NDR_COMPRESSION_MSZIP_CAB, &ndr->cstate));
+       }
+
+       for (i = 0; i < num_cfdata; i++, r++) {
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->csum));
+               NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->cbData));
+               NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->cbUncomp));
+
+               switch (cab_ctype) {
+               case CF_COMPRESS_NONE:
+                       /* just copy the data */
+                       NDR_PULL_NEED_BYTES(ndr, r->cbUncomp);
+                       r->ab = data_blob_talloc(ndr->current_mem_ctx,
+                                                ndr->data+ndr->offset,
+                                                r->cbUncomp);
+                       if (r->ab.data == NULL) {
+                               return ndr_pull_error(ndr, NDR_ERR_ALLOC,
+                                                     "failed to allocate 
buffer for uncompressed CFDATA block");
+                       }
+                       ndr->offset += r->cbUncomp;
+                       break;
+
+               case CF_COMPRESS_LZX:
+                       /* just copy the data (LZX decompression not 
implemented yet) */
+                       NDR_PULL_NEED_BYTES(ndr, r->cbData);
+                       r->ab = data_blob_talloc(ndr->current_mem_ctx,
+                                                ndr->data+ndr->offset,
+                                                r->cbData);
+                       if (r->ab.data == NULL) {
+                               return ndr_pull_error(ndr, NDR_ERR_ALLOC,
+                                                     "failed to allocate 
buffer for LZX-compressed CFDATA block");
+                       }
+                       ndr->offset += r->cbData;
+                       break;
+
+               case CF_COMPRESS_MSZIP: {
+                       struct ndr_pull *pull_sub, *pull_compress;
+                       NDR_PULL_NEED_BYTES(ndr, r->cbData);
+                       /* decompress via subcontext */
+                       NDR_CHECK(ndr_pull_subcontext_start(ndr, &pull_sub, 0, 
r->cbData));
+                       pull_sub->cstate = ndr->cstate;
+                       NDR_CHECK(ndr_pull_compression_start(pull_sub, 
&pull_compress,
+                                                            ndr_ctype, 
r->cbUncomp, r->cbData));
+                       ndr_set_flags(&pull_compress->flags, 
LIBNDR_FLAG_REMAINING);
+                       NDR_CHECK(ndr_pull_DATA_BLOB(pull_compress, 
NDR_SCALARS, &r->ab));
+                       NDR_CHECK(ndr_pull_compression_end(pull_sub, 
pull_compress, ndr_ctype, r->cbUncomp));
+                       NDR_CHECK(ndr_pull_subcontext_end(ndr, pull_sub, 0, 
r->cbData));
+
+                       break;
+               }
+               default:
+                       return NDR_ERR_BAD_SWITCH;
+               }
        }
-       SIVAL(ndr->data, 8, cab_size);
+
+       ndr_pull_compression_state_free(ndr->cstate);
+       ndr->cstate = NULL;
 
        return NDR_ERR_SUCCESS;
 }
@@ -225,7 +393,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_cab_file(struct 
ndr_pull *ndr, int ndr_flags
        uint32_t cntr_cffiles_0;
        TALLOC_CTX *_mem_save_cffiles_0 = NULL;
        uint32_t size_cfdata_0 = 0;
-       uint32_t cntr_cfdata_0;
+       size_t processed_cfdata = 0;
        TALLOC_CTX *_mem_save_cfdata_0 = NULL;
        {
                uint32_t _flags_save_STRUCT = ndr->flags;
@@ -259,8 +427,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_cab_file(struct 
ndr_pull *ndr, int ndr_flags
                        NDR_PULL_ALLOC_N(ndr, r->cfdata, size_cfdata_0);
                        _mem_save_cfdata_0 = NDR_PULL_GET_MEM_CTX(ndr);
                        NDR_PULL_SET_MEM_CTX(ndr, r->cfdata, 0);
-                       for (cntr_cfdata_0 = 0; cntr_cfdata_0 < 
(size_cfdata_0); cntr_cfdata_0++) {
-                               NDR_CHECK(ndr_pull_CFDATA(ndr, NDR_SCALARS, 
&r->cfdata[cntr_cfdata_0]));
+                       for (cntr_cffolders_0 = 0; cntr_cffolders_0 < 
(size_cffolders_0); cntr_cffolders_0++) {
+                               NDR_CHECK(ndr_pull_folder_cfdata(ndr,
+                                                                r->cfdata + 
processed_cfdata,
+                                                                
r->cffolders[cntr_cffolders_0].typeCompress,
+                                                                
r->cffolders[cntr_cffolders_0].cCFData));
+                               processed_cfdata += 
r->cffolders[cntr_cffolders_0].cCFData;
                        }
                        NDR_PULL_SET_MEM_CTX(ndr, _mem_save_cfdata_0, 0);
                        NDR_CHECK(ndr_pull_trailer_align(ndr, 4));
diff --git a/librpc/ndr/ndr_cab.h b/librpc/ndr/ndr_cab.h
index 7987153..59dbc99 100644
--- a/librpc/ndr/ndr_cab.h
+++ b/librpc/ndr/ndr_cab.h
@@ -21,4 +21,3 @@
 
 uint32_t ndr_count_cfdata(const struct cab_file *r);
 uint32_t ndr_cab_generate_checksum(const struct CFDATA *r);
-enum cf_compress_type ndr_cab_get_compression(const struct cab_file *r);
diff --git a/librpc/ndr/ndr_compression.c b/librpc/ndr/ndr_compression.c
index d291df5..bdce431 100644
--- a/librpc/ndr/ndr_compression.c
+++ b/librpc/ndr/ndr_compression.c
@@ -1,21 +1,21 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
 
    libndr compression support
 
    Copyright (C) Stefan Metzmacher 2005
    Copyright (C) Matthieu Suiche 2008
-   
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -26,6 +26,17 @@
 #include "../librpc/ndr/ndr_compression.h"
 #include <zlib.h>
 
+struct ndr_compression_state {
+       enum ndr_compression_alg type;
+       union {
+               struct {
+                       struct z_stream_s *z;
+                       uint8_t *dict;
+                       size_t dict_size;
+               } mszip;
+       };
+};
+
 static voidpf ndr_zlib_alloc(voidpf opaque, uInt items, uInt size)
 {
        return talloc_zero_size(opaque, items * size);
@@ -36,6 +47,261 @@ static void  ndr_zlib_free(voidpf opaque, voidpf address)
        talloc_free(address);
 }
 
+static enum ndr_err_code ndr_pull_compression_mszip_cab_chunk(struct ndr_pull 
*ndrpull,
+                                                             struct ndr_push 
*ndrpush,
+                                                             struct 
ndr_compression_state *state,


-- 
Samba Shared Repository

Reply via email to