librpc-idl: change the drsuapi_DsBindInfoCtr so that it match what is on the wire...
authorMatthieu Patou <mat@matws.net>
Sun, 20 Oct 2013 20:37:17 +0000 (13:37 -0700)
committerStefan Metzmacher <metze@samba.org>
Tue, 10 Mar 2015 09:55:45 +0000 (10:55 +0100)
Previous implementation had a problem with NDR64 with uint32 and
uint3264 being in the wrong order

Signed-off-by: Matthieu Patou <mat@matws.net>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Wed Oct 30 10:16:02 CET 2013 on sn-devel-104

(cherry picked from commit 8dc931bafca00c1c61a4366ffb6cfa72a98bb412)

librpc/idl/drsuapi.idl
librpc/ndr/ndr_drsuapi.c

index 7e3d34317ecccf6011de3b6bac5b68876d841e26..f1c6cd6e9118246601588af850a1c56d72230e4c 100644 (file)
@@ -115,14 +115,14 @@ interface drsuapi
        } drsuapi_SupportedExtensionsExt;
 
        /* this is used by w2k */
-       typedef struct {
+       typedef [public] struct {
                drsuapi_SupportedExtensions supported_extensions;
                GUID site_guid;
                uint32 pid;
        } drsuapi_DsBindInfo24;
 
        /* this is used by w2k3 */
-       typedef struct {
+       typedef [public] struct {
                drsuapi_SupportedExtensions supported_extensions;
                GUID site_guid;
                uint32 pid;
@@ -130,7 +130,7 @@ interface drsuapi
        } drsuapi_DsBindInfo28;
 
        /* this is used by w2k8 */
-       typedef struct {
+       typedef [public] struct {
                drsuapi_SupportedExtensions supported_extensions;
                GUID site_guid;
                uint32 pid;
@@ -139,15 +139,21 @@ interface drsuapi
                GUID config_dn_guid;
        } drsuapi_DsBindInfo48;
 
-       typedef struct {
+       typedef [public] struct {
                [flag(NDR_REMAINING)] DATA_BLOB info;
        } drsuapi_DsBindInfoFallBack;
 
-       typedef [nodiscriminant] union {
-               [case(24)][subcontext(4)] drsuapi_DsBindInfo24 info24;
-               [case(28)][subcontext(4)] drsuapi_DsBindInfo28 info28;
-               [case(48)][subcontext(4)] drsuapi_DsBindInfo48 info48;
-               [default][subcontext(4)] drsuapi_DsBindInfoFallBack FallBack;
+       typedef [nopull, nopush, noprint] [nodiscriminant] union {
+               [case(24)][subcontext(0), subcontext_size(24)] drsuapi_DsBindInfo24 info24;
+               [case(28)][subcontext(0), subcontext_size(28)] drsuapi_DsBindInfo28 info28;
+               [case(48)][subcontext(0), subcontext_size(48)] drsuapi_DsBindInfo48 info48;
+               /*
+                * The size for the defaut case is a bit arbitrary it in fact the value
+                * of the switch but we can't reference it.
+                * As we hand(un-)marshall this structure it has 0 impact and makes
+                * pidl happy for wireshark too
+                */
+               [default][subcontext(0), subcontext_size(48)] drsuapi_DsBindInfoFallBack Fallback;
        } drsuapi_DsBindInfo;
 
        /* the drsuapi_DsBindInfoCtr was this before
@@ -160,11 +166,44 @@ interface drsuapi
         * so we're doing it here
         */
 
+       /*
+        * MS-DRSR.pdf gives the following definition
+       typedef struct {
+               [range(1,10000)] DWORD cb;
+               [size_is(cb)] BYTE rgb[];
+       } DRS_EXTENSIONS;
+
+       But we use a subcontext which has a slighly different signification on how
+       data are laid out.
+       With the MS-DRSR definition we will have
+               size_is_cb cv rgb_array
+       with size_is_cb being a uint3264 and cv being a uint32
+
+       We used to have
        typedef struct {
                [range(1,10000)] uint32 length;
                [switch_is(length)] drsuapi_DsBindInfo info;
        } drsuapi_DsBindInfoCtr;
 
+       typedef [nodiscriminant] union {
+               [case(24)][subcontext(4)] drsuapi_DsBindInfo24 info24;
+               [case(28)][subcontext(4)] drsuapi_DsBindInfo28 info28;
+               [case(48)][subcontext(4)] drsuapi_DsBindInfo48 info48;
+               [default][subcontext(4)] drsuapi_DsBindInfoFallBack FallBack;
+       } drsuapi_DsBindInfo;
+
+       With this definition data is laid out this way:
+       length subcontext_size drsuapi_DsBindInfoxx
+       with length being a uint32 and subcontext_size being a uint3264
+
+       It has clearly an impact on the way things are aligned when using NDR64
+       */
+       typedef [flag(NDR_NOALIGN)] struct {
+               [range(1,10000)] uint3264 length;
+               [value(length)] uint32 __ndr_length;
+               [switch_is(length)] drsuapi_DsBindInfo info;
+       } drsuapi_DsBindInfoCtr;
+
        /* this is a magic guid you need to pass to DsBind to make drsuapi_DsWriteAccountSpn() work
         *
         * maybe the bind_guid could also be the invocation_id see drsuapi_DsReplicaConnection04
index f7125e6e5542156081fd8802e8e8e1bf40f6a40c..cef617ba163f6fb59fe7843dabc56d097e37933f 100644 (file)
@@ -4,6 +4,7 @@
    routines for printing some linked list structs in DRSUAPI
 
    Copyright (C) Stefan (metze) Metzmacher 2005
+   Copyright (C) Matthieu Patou 2013
 
    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
@@ -406,3 +407,158 @@ _PUBLIC_ void ndr_print_drsuapi_DsAddEntry_AttrErrListItem_V1(struct ndr_print *
                ndr_print_drsuapi_DsAddEntry_AttrErrListItem_V1(ndr, "next", r->next);
        }
 }
+
+enum ndr_err_code ndr_push_drsuapi_DsBindInfo(struct ndr_push *ndr, int ndr_flags, const union drsuapi_DsBindInfo *r)
+{
+       NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
+       if (ndr_flags & NDR_SCALARS) {
+               uint32_t level = ndr_push_get_switch_value(ndr, r);
+               NDR_CHECK(ndr_push_union_align(ndr, 4));
+               switch (level) {
+                       case 24: {
+                               {
+                                       struct ndr_push *_ndr_info24;
+                                       NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info24, 0, 24));
+                                       NDR_CHECK(ndr_push_drsuapi_DsBindInfo24(_ndr_info24, NDR_SCALARS, &r->info24));
+                                       NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_info24, 0, 24));
+                               }
+                       break; }
+
+                       case 28: {
+                               {
+                                       struct ndr_push *_ndr_info28;
+                                       NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info28, 0, 28));
+                                       NDR_CHECK(ndr_push_drsuapi_DsBindInfo28(_ndr_info28, NDR_SCALARS, &r->info28));
+                                       NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_info28, 0, 28));
+                               }
+                       break; }
+
+                       case 48: {
+                               {
+                                       struct ndr_push *_ndr_info48;
+                                       NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info48, 0, 48));
+                                       NDR_CHECK(ndr_push_drsuapi_DsBindInfo48(_ndr_info48, NDR_SCALARS, &r->info48));
+                                       NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_info48, 0, 48));
+                               }
+                       break; }
+
+                       default: {
+                               {
+                                       struct ndr_push *_ndr_Fallback;
+                                       NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_Fallback, 0, level));
+                                       NDR_CHECK(ndr_push_drsuapi_DsBindInfoFallBack(_ndr_Fallback, NDR_SCALARS, &r->Fallback));
+                                       NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_Fallback, 0, level));
+                               }
+                       break; }
+
+               }
+       }
+       if (ndr_flags & NDR_BUFFERS) {
+               uint32_t level = ndr_push_get_switch_value(ndr, r);
+               switch (level) {
+                       case 24:
+                       break;
+
+                       case 28:
+                       break;
+
+                       case 48:
+                       break;
+
+                       default:
+                       break;
+
+               }
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+enum ndr_err_code ndr_pull_drsuapi_DsBindInfo(struct ndr_pull *ndr, int ndr_flags, union drsuapi_DsBindInfo *r)
+{
+       uint32_t level;
+       level = ndr_pull_get_switch_value(ndr, r);
+       NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
+       if (ndr_flags & NDR_SCALARS) {
+               NDR_CHECK(ndr_pull_union_align(ndr, 4));
+               switch (level) {
+                       case 24: {
+                               {
+                                       struct ndr_pull *_ndr_info24;
+                                       NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_info24, 0, 24));
+                                       NDR_CHECK(ndr_pull_drsuapi_DsBindInfo24(_ndr_info24, NDR_SCALARS, &r->info24));
+                                       NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_info24, 0, 24));
+                               }
+                       break; }
+
+                       case 28: {
+                               {
+                                       struct ndr_pull *_ndr_info28;
+                                       NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_info28, 0, 28));
+                                       NDR_CHECK(ndr_pull_drsuapi_DsBindInfo28(_ndr_info28, NDR_SCALARS, &r->info28));
+                                       NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_info28, 0, 28));
+                               }
+                       break; }
+
+                       case 48: {
+                               {
+                                       struct ndr_pull *_ndr_info48;
+                                       NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_info48, 0, 48));
+                                       NDR_CHECK(ndr_pull_drsuapi_DsBindInfo48(_ndr_info48, NDR_SCALARS, &r->info48));
+                                       NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_info48, 0, 48));
+                               }
+                       break; }
+
+                       default: {
+                               {
+                                       struct ndr_pull *_ndr_Fallback;
+                                       NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_Fallback, 0, level));
+                                       NDR_CHECK(ndr_pull_drsuapi_DsBindInfoFallBack(_ndr_Fallback, NDR_SCALARS, &r->Fallback));
+                                       NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_Fallback, 0, level));
+                               }
+                       break; }
+
+               }
+       }
+       if (ndr_flags & NDR_BUFFERS) {
+               switch (level) {
+                       case 24:
+                       break;
+
+                       case 28:
+                       break;
+
+                       case 48:
+                       break;
+
+                       default:
+                       break;
+
+               }
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_drsuapi_DsBindInfo(struct ndr_print *ndr, const char *name, const union drsuapi_DsBindInfo *r)
+{
+       uint32_t level;
+       level = ndr_print_get_switch_value(ndr, r);
+       ndr_print_union(ndr, name, level, "drsuapi_DsBindInfo");
+       switch (level) {
+               case 24:
+                       ndr_print_drsuapi_DsBindInfo24(ndr, "info24", &r->info24);
+               break;
+
+               case 28:
+                       ndr_print_drsuapi_DsBindInfo28(ndr, "info28", &r->info28);
+               break;
+
+               case 48:
+                       ndr_print_drsuapi_DsBindInfo48(ndr, "info48", &r->info48);
+               break;
+
+               default:
+                       ndr_print_drsuapi_DsBindInfoFallBack(ndr, "Fallback", &r->Fallback);
+               break;
+
+       }
+}