Import warning fixes from Samba 3.
[ira/wip.git] / source4 / librpc / ndr / ndr.c
index 40852456bceb117300744d73acb9ead234bc4570..e8daa99e15bc60d864b7a7569b25e7586981458d 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "includes.h"
 #include "librpc/ndr/libndr.h"
-#include "lib/util/dlinklist.h"
+#include "../lib/util/dlinklist.h"
 #include "librpc/gen_ndr/dcerpc.h"
 #include "param/param.h"
 
@@ -163,16 +163,20 @@ _PUBLIC_ enum ndr_err_code ndr_push_expand(struct ndr_push *ndr, uint32_t extra_
        return NDR_ERR_SUCCESS;
 }
 
-_PUBLIC_ void ndr_print_debug_helper(struct ndr_print *ndr, const char *format, ...)
+_PUBLIC_ void ndr_print_debug_helper(struct ndr_print *ndr, const char *format, ...) 
 {
        va_list ap;
        char *s = NULL;
-       int i;
+       int i, ret;
 
        va_start(ap, format);
-       vasprintf(&s, format, ap);
+       ret = vasprintf(&s, format, ap);
        va_end(ap);
 
+       if (ret == -1) {
+               return;
+       }
+
        for (i=0;i<ndr->depth;i++) {
                DEBUGADD(0,("    "));
        }
@@ -350,12 +354,17 @@ _PUBLIC_ enum ndr_err_code ndr_pull_error(struct ndr_pull *ndr,
 {
        char *s=NULL;
        va_list ap;
+       int ret;
 
        va_start(ap, format);
-       vasprintf(&s, format, ap);
+       ret = vasprintf(&s, format, ap);
        va_end(ap);
 
-       DEBUG(3,("ndr_pull_error(%u): %s\n", ndr_err, s));
+       if (ret == -1) {
+               return NDR_ERR_ALLOC;
+       }
+
+       DEBUG(1,("ndr_pull_error(%u): %s\n", ndr_err, s));
 
        free(s);
 
@@ -367,16 +376,21 @@ _PUBLIC_ enum ndr_err_code ndr_pull_error(struct ndr_pull *ndr,
 */
 _PUBLIC_ enum ndr_err_code ndr_push_error(struct ndr_push *ndr,
                                 enum ndr_err_code ndr_err,
-                                const char *format, ...)
+                                const char *format, ...) 
 {
        char *s=NULL;
        va_list ap;
+       int ret;
 
        va_start(ap, format);
-       vasprintf(&s, format, ap);
+       ret = vasprintf(&s, format, ap);
        va_end(ap);
 
-       DEBUG(3,("ndr_push_error(%u): %s\n", ndr_err, s));
+       if (ret == -1) {
+               return NDR_ERR_ALLOC;
+       }
+
+       DEBUG(1,("ndr_push_error(%u): %s\n", ndr_err, s));
 
        free(s);
 
@@ -394,6 +408,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 +442,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 +527,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 +577,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 +601,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);