a fairly large commit!
authorAndrew Tridgell <tridge@samba.org>
Tue, 16 Dec 2003 09:02:58 +0000 (09:02 +0000)
committerAndrew Tridgell <tridge@samba.org>
Tue, 16 Dec 2003 09:02:58 +0000 (09:02 +0000)
This adds support for bigendian rpc in the client. I have installed
SUN pcnetlink locally and am using it to test the samba4 rpc
code. This allows us to easily find places where we have stuffed up
the types (such as 2 uint16 versus a uint32), as testing both
big-endian and little-endian easily shows which is correct. I have now
used this to fix several bugs like that in the samba4 IDL.

In order to make this work I also had to redefine a GUID as a true
structure, not a blob. From the pcnetlink wire it is clear that it is
indeed defined as a structure (the byte order changes). This required
changing lots of Samba code to use a GUID as a structure.

I also had to fix the if_version code in dcerpc syntax IDs, as it
turns out they are a single uint32 not two uint16s.

The big-endian support is a bit ugly at the moment, and breaks the
layering in some places. More work is needed, especially on the server
side.
(This used to be commit bb1af644a5a7b188290ce36232f255da0e5d66d2)

25 files changed:
source4/build/pidl/header.pm
source4/include/includes.h
source4/include/rpc_secdes.h
source4/include/smb.h
source4/include/smb_interfaces.h
source4/lib/util_sid.c
source4/lib/util_uuid.c
source4/libcli/raw/rawfsinfo.c
source4/librpc/idl/dcerpc.idl
source4/librpc/idl/misc.idl
source4/librpc/ndr/ndr_basic.c
source4/librpc/rpc/dcerpc.c
source4/librpc/rpc/dcerpc.h
source4/librpc/rpc/dcerpc_smb.c
source4/librpc/rpc/dcerpc_tcp.c
source4/librpc/rpc/dcerpc_util.c
source4/ntvfs/ipc/vfs_ipc.c
source4/passdb/secrets.c
source4/rpc_server/dcerpc_server.c
source4/rpc_server/dcesrv_auth.c
source4/rpc_server/epmapper/rpc_epmapper.c
source4/smbd/trans2.c
source4/torture/rpc/epmapper.c
source4/torture/rpc/mgmt.c
source4/torture/rpc/scanner.c

index c993108f98e873f2d7230be6cf5da40431bad382..418ae97aed8cae8858cf570dcc8936b39f42eeee 100644 (file)
@@ -269,6 +269,9 @@ sub HeaderInterface($)
 
     my $count = 0;
 
+    $res .= "#ifndef _HEADER_NDR_$interface->{NAME}\n";
+    $res .= "#define _HEADER_NDR_$interface->{NAME}\n\n";
+
     if (defined $if_uuid) {
            my $name = uc $interface->{NAME};
            $res .= "#define DCERPC_$name\_UUID \"$if_uuid\"\n";
@@ -297,6 +300,7 @@ sub HeaderInterface($)
            HeaderFunction($d);
     }
 
+    $res .= "#endif /* _HEADER_NDR_$interface->{NAME} */\n";
 }
 
 #####################################################################
index b3f98d2f2c2ffff87054b4375b736b91fa6ea047..6d796da6b3649b7e2db78f61f81556752a9e6dbb 100644 (file)
@@ -768,7 +768,6 @@ extern int errno;
 
 #include "mutex.h"
 
-#include "librpc/ndr/libndr.h"
 #include "librpc/rpc/dcerpc.h"
 
 #include "rpc_server/dcerpc_server.h"
index 70191901c70d17ba2b8a4b008d1b3ffdb27a2cf3..80cc71fccf3667b36cdd4c4c2b3004669c495266 100644 (file)
@@ -116,8 +116,8 @@ typedef struct security_ace_info
 
        /* this stuff may be present when type is XXXX_TYPE_XXXX_OBJECT */
        uint32  obj_flags; /* xxxx_ACE_OBJECT_xxxx e.g present/inherited present etc */
-       GUID    obj_guid;  /* object GUID */
-       GUID    inh_guid;  /* inherited object GUID */          
+       struct GUID    obj_guid;  /* object GUID */
+       struct GUID    inh_guid;  /* inherited object GUID */           
         /* eof object stuff */
 
        DOM_SID trustee;
index 9b8bc28614439a395540cd4b4ed3a941641ec410..89623895edf5690bee4770756a68b9df980ade53 100644 (file)
@@ -421,7 +421,9 @@ struct vuid_cache {
 #include "smb_acls.h"
 #include "enums.h"
 #include "events.h"
+#include "librpc/gen_ndr/ndr_misc.h"
 #include "smb_interfaces.h"
+#include "librpc/ndr/libndr.h"
 
 typedef struct smb_vfs_handle_struct
 {
index 4bf557359ef473ce5930c44e5f952d66578e6967..6f820be5367d9d2becdc60a78554753e78bd318b 100644 (file)
@@ -24,10 +24,6 @@ typedef SMB_BIG_UINT large_t;
 
 /* Globally Unique ID */
 #define GUID_SIZE 16
-typedef struct GUID
-{
-       uint8 info[GUID_SIZE];
-} GUID;
 
 /* 64 bit time (100 nanosec) 1601 - cifs6.txt, section 3.5, page 30 */
 typedef struct nttime_info
@@ -946,7 +942,7 @@ union smb_fsinfo {
                        large_t quota_soft;
                        large_t quota_hard;
                        large_t quota_flags;
-                       GUID guid;
+                       struct GUID guid;
                        char *volume_name;
                        char *fs_type;
                } out;
@@ -1074,7 +1070,7 @@ union smb_fsinfo {
                enum fsinfo_level level;
 
                struct {
-                       GUID  guid;
+                       struct GUID  guid;
                        large_t unknown[6];
                } out;
        } objectid_information; 
index 6436035f8e50f79c6874c3ca5012b54954fbf37a..44bb4cebb11e62a68c3771135d66fd0487cdece1 100644 (file)
@@ -613,24 +613,6 @@ char *sid_binstring(const DOM_SID *sid)
        return s;
 }
 
-
-/*****************************************************************
- Print a GUID structure for debugging.
-*****************************************************************/
-
-void print_guid(GUID *guid)
-{
-       int i;
-
-       d_printf("%08x-%04x-%04x", 
-                IVAL(guid->info, 0), SVAL(guid->info, 4), SVAL(guid->info, 6));
-       d_printf("-%02x%02x-", guid->info[8], guid->info[9]);
-       for (i=10;i<GUID_SIZE;i++)
-               d_printf("%02x", guid->info[i]);
-       d_printf("\n");
-}
-
-
 /*******************************************************************
  Check if ACE has OBJECT type.
 ********************************************************************/
index 1b8c7572c729042a09a2a6f54b94af270e139438..0c607fb82387c9a1102445c35d85ea1451a3416f 100644 (file)
@@ -3,6 +3,7 @@
  *  UUID server routines
  *  Copyright (C) Theodore Ts'o               1996, 1997,
  *  Copyright (C) Jim McDonough                     2002.
+ *  Copyright (C) Andrew Tridgell                   2003.
  *
  *  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
 
 #include "includes.h"
 
-/*
- * Offset between 15-Oct-1582 and 1-Jan-70
- */
-#define TIME_OFFSET_HIGH 0x01B21DD2
-#define TIME_OFFSET_LOW  0x13814000
-
-struct uuid {
-        uint32   time_low;
-        uint16   time_mid;
-        uint16   time_hi_and_version;
-        uint8    clock_seq[2];
-        uint8    node[6];
-};
-
-
-static void uuid_pack(const struct uuid *uu, GUID *ptr)
-{
-       uint8 *out = ptr->info;
-
-       SIVAL(out, 0, uu->time_low);
-       SSVAL(out, 4, uu->time_mid);
-       SSVAL(out, 6, uu->time_hi_and_version);
-       memcpy(out+8, uu->clock_seq, 2);
-       memcpy(out+10, uu->node, 6);
-}
-
-static void uuid_unpack(const GUID in, struct uuid *uu)
+void uuid_generate_random(struct GUID *out)
 {
-       const uint8 *ptr = in.info;
-
-       uu->time_low = IVAL(ptr, 0);
-       uu->time_mid = SVAL(ptr, 4);
-       uu->time_hi_and_version = SVAL(ptr, 6);
-       memcpy(uu->clock_seq, ptr+8, 2);
-       memcpy(uu->node, ptr+10, 6);
-}
-
-void uuid_generate_random(GUID *out)
-{
-       GUID tmp;
-       struct uuid uu;
-
-       generate_random_buffer(tmp.info, sizeof(tmp.info), True);
-       uuid_unpack(tmp, &uu);
-
-       uu.clock_seq[0] = (uu.clock_seq[0] & 0x3F) | 0x80;
-       uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;
-       uuid_pack(&uu, out);
+       generate_random_buffer(out, sizeof(struct GUID), False);
+       out->clock_seq[0] = (out->clock_seq[0] & 0x3F) | 0x80;
+       out->time_hi_and_version = (out->time_hi_and_version & 0x0FFF) | 0x4000;
 }
index 362063bfc59f41737833766e6e91632d2a95126a..85daf654d36b5f91f4a79d0993fa1d3e1ae421de 100644 (file)
@@ -259,7 +259,8 @@ NTSTATUS smb_raw_fsinfo_recv(struct cli_request *req,
 
        case RAW_QFS_OBJECTID_INFORMATION:
                QFS_CHECK_SIZE(64);
-               memcpy(fsinfo->objectid_information.out.guid.info, blob.data, GUID_SIZE);
+               status = ndr_pull_struct_blob(&blob, mem_ctx, &fsinfo->objectid_information.out.guid,
+                                             (ndr_pull_flags_fn_t)ndr_pull_GUID);
                for (i=0;i<6;i++) {
                        fsinfo->objectid_information.out.unknown[i] = BVAL(blob.data, 16 + i*8);
                }
index cf195b6aeaf851a6213c5e234fad202a30c64ac4..ad8267957624b3d221b026e7a7c162775ceeec25 100644 (file)
@@ -13,8 +13,7 @@ interface dcerpc
 {
        typedef [public] struct {
                GUID uuid;
-               uint16 major_version;
-               uint16 minor_version;
+               uint32 if_version;
        } dcerpc_syntax_id;
 
        typedef struct {
@@ -28,7 +27,7 @@ interface dcerpc
                uint16 max_xmit_frag;
                uint16 max_recv_frag;
                uint32 assoc_group_id;
-               uint8 num_contexts;
+               uint8  num_contexts;
                dcerpc_ctx_list ctx_list[num_contexts];
                [flag(NDR_ALIGN8)]    DATA_BLOB _pad;
                [flag(NDR_REMAINING)] DATA_BLOB auth_info;
@@ -167,6 +166,7 @@ interface dcerpc
        const uint8 DCERPC_PFC_FLAG_NOCALL = 0x20;
 
        /* these offsets are needed by the signing code */
+       const uint8 DCERPC_DREP_OFFSET     =  4;
        const uint8 DCERPC_FRAG_LEN_OFFSET =  8;
        const uint8 DCERPC_AUTH_LEN_OFFSET = 10;
 
index eb2288bc353937917f6f1bd96074860e9cce43b8..a1f8549eaa217f60e7b847c01c443a4bb61ae9cf 100644 (file)
@@ -8,6 +8,14 @@
 interface misc
 {
 
+       typedef [public,noprint] struct {
+               uint32 time_low;
+               uint16 time_mid;
+               uint16 time_hi_and_version;
+               uint8  clock_seq[2];
+               uint8  node[6];
+       } GUID;
+
        /* a domain SID. Note that unlike Samba3 this contains a pointer,
           so you can't copy them using assignment */
        typedef [public,noprint] struct {
index 3b5aea60ca7e58388c9471fb7d68c84068b0d708..ed75b8c27c0990c11e2a166b8c980dfa51fc7d9f 100644 (file)
 
 #include "includes.h"
 
+#define NDR_BE(ndr) ((ndr)->flags & LIBNDR_FLAG_BIGENDIAN)
+#define NDR_SVAL(ndr, ofs) (NDR_BE(ndr)?RSVAL(ndr->data,ofs):SVAL(ndr->data,ofs))
+#define NDR_IVAL(ndr, ofs) (NDR_BE(ndr)?RIVAL(ndr->data,ofs):IVAL(ndr->data,ofs))
+#define NDR_SSVAL(ndr, ofs, v) do { if (NDR_BE(ndr))  { RSSVAL(ndr->data,ofs,v); } else SSVAL(ndr->data,ofs,v); } while (0)
+#define NDR_SIVAL(ndr, ofs, v) do { if (NDR_BE(ndr))  { RSIVAL(ndr->data,ofs,v); } else SIVAL(ndr->data,ofs,v); } while (0)
+
 /*
   parse a uint8
 */
@@ -41,7 +47,7 @@ NTSTATUS ndr_pull_uint16(struct ndr_pull *ndr, uint16 *v)
 {
        NDR_PULL_ALIGN(ndr, 2);
        NDR_PULL_NEED_BYTES(ndr, 2);
-       *v = SVAL(ndr->data, ndr->offset);
+       *v = NDR_SVAL(ndr, ndr->offset);
        ndr->offset += 2;
        return NT_STATUS_OK;
 }
@@ -54,7 +60,7 @@ NTSTATUS ndr_pull_uint32(struct ndr_pull *ndr, uint32 *v)
 {
        NDR_PULL_ALIGN(ndr, 4);
        NDR_PULL_NEED_BYTES(ndr, 4);
-       *v = IVAL(ndr->data, ndr->offset);
+       *v = NDR_IVAL(ndr, ndr->offset);
        ndr->offset += 4;
        return NT_STATUS_OK;
 }
@@ -66,8 +72,8 @@ NTSTATUS ndr_pull_HYPER_T(struct ndr_pull *ndr, HYPER_T *v)
 {
        NDR_PULL_ALIGN(ndr, 8);
        NDR_PULL_NEED_BYTES(ndr, 8);
-       v->low = IVAL(ndr->data, ndr->offset);
-       v->high = IVAL(ndr->data, ndr->offset+4);
+       v->low = NDR_IVAL(ndr, ndr->offset);
+       v->high = NDR_IVAL(ndr, ndr->offset+4);
        ndr->offset += 8;
        return NT_STATUS_OK;
 }
@@ -173,18 +179,6 @@ NTSTATUS ndr_pull_array_uint32(struct ndr_pull *ndr, int ndr_flags, uint32 *data
        return NT_STATUS_OK;
 }
 
-/*
-  parse a GUID
-*/
-NTSTATUS ndr_pull_GUID(struct ndr_pull *ndr, int ndr_flags, GUID *guid)
-{
-       if (ndr_flags & NDR_SCALARS) {
-               return ndr_pull_bytes(ndr, guid->info, GUID_SIZE);
-       }
-       return NT_STATUS_OK;
-}
-
-
 /*
   push a uint8
 */
@@ -203,7 +197,7 @@ NTSTATUS ndr_push_uint16(struct ndr_push *ndr, uint16 v)
 {
        NDR_PUSH_ALIGN(ndr, 2);
        NDR_PUSH_NEED_BYTES(ndr, 2);
-       SSVAL(ndr->data, ndr->offset, v);
+       NDR_SSVAL(ndr, ndr->offset, v);
        ndr->offset += 2;
        return NT_STATUS_OK;
 }
@@ -215,7 +209,7 @@ NTSTATUS ndr_push_uint32(struct ndr_push *ndr, uint32 v)
 {
        NDR_PUSH_ALIGN(ndr, 4);
        NDR_PUSH_NEED_BYTES(ndr, 4);
-       SIVAL(ndr->data, ndr->offset, v);
+       NDR_SIVAL(ndr, ndr->offset, v);
        ndr->offset += 4;
        return NT_STATUS_OK;
 }
@@ -227,8 +221,8 @@ NTSTATUS ndr_push_HYPER_T(struct ndr_push *ndr, HYPER_T v)
 {
        NDR_PUSH_ALIGN(ndr, 8);
        NDR_PUSH_NEED_BYTES(ndr, 8);
-       SIVAL(ndr->data, ndr->offset, v.low);
-       SIVAL(ndr->data, ndr->offset+4, v.high);
+       NDR_SIVAL(ndr, ndr->offset, v.low);
+       NDR_SIVAL(ndr, ndr->offset+4, v.high);
        ndr->offset += 8;
        return NT_STATUS_OK;
 }
@@ -581,17 +575,6 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
        return NT_STATUS_OK;
 }
 
-/*
-  push a GUID
-*/
-NTSTATUS ndr_push_GUID(struct ndr_push *ndr, int ndr_flags, GUID *guid)
-{
-       if (ndr_flags & NDR_SCALARS) {
-               return ndr_push_bytes(ndr, guid->info, GUID_SIZE);
-       }
-       return NT_STATUS_OK;
-}
-
 /*
   push a NTTIME
 */
@@ -770,26 +753,25 @@ NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
 {
         uint32 time_low;
         uint32 time_mid, time_hi_and_version;
-        uint32 clock_seq_hi_and_reserved;
-        uint32 clock_seq_low;
+        uint32 clock_seq[2];
         uint32 node[6];
         int i;
 
         if (11 != sscanf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
                          &time_low, &time_mid, &time_hi_and_version, 
-                         &clock_seq_hi_and_reserved, &clock_seq_low,
+                         &clock_seq[0], &clock_seq[1],
                          &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
                 return NT_STATUS_INVALID_PARAMETER;
         }
 
-        SIVAL(guid->info, 0, time_low);
-        SSVAL(guid->info, 4, time_mid);
-        SSVAL(guid->info, 6, time_hi_and_version);
-        SCVAL(guid->info, 8, clock_seq_hi_and_reserved);
-        SCVAL(guid->info, 9, clock_seq_low);
+       guid->time_low = time_low;
+       guid->time_mid = time_mid;
+       guid->time_hi_and_version = time_hi_and_version;
+       guid->clock_seq[0] = clock_seq[0];
+       guid->clock_seq[1] = clock_seq[1];
         for (i=0;i<6;i++) {
-                SCVAL(guid->info, 10 + i, node[i]);
-        }
+               guid->node[i] = node[i];
+       }
 
         return NT_STATUS_OK;
 }
@@ -801,12 +783,13 @@ const char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
 {
        return talloc_asprintf(mem_ctx, 
                               "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-                              IVAL(guid->info, 0), SVAL(guid->info, 4), 
-                              SVAL(guid->info, 6),
-                              guid->info[8], guid->info[9],
-                              guid->info[10], guid->info[11], 
-                              guid->info[12], guid->info[13], 
-                              guid->info[14], guid->info[15]);
+                              guid->time_low, guid->time_mid,
+                              guid->time_hi_and_version,
+                              guid->clock_seq[0],
+                              guid->clock_seq[1],
+                              guid->node[0], guid->node[1],
+                              guid->node[2], guid->node[3],
+                              guid->node[4], guid->node[5]);
 }
 
 void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid)
index 3dcaca83ec746570cd40a8d5e3c9e9313c92f036..c82d8d67ab4c4db4b028cd841544ccaea2b58f33 100644 (file)
@@ -64,6 +64,35 @@ void dcerpc_pipe_close(struct dcerpc_pipe *p)
        }
 }
 
+/* we need to be able to get/set the fragment length without doing a full
+   decode */
+void dcerpc_set_frag_length(DATA_BLOB *blob, uint16 v)
+{
+       if (CVAL(blob->data,DCERPC_DREP_OFFSET) & 0x10) {
+               SSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, v);
+       } else {
+               RSSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, v);
+       }
+}
+
+uint16 dcerpc_get_frag_length(DATA_BLOB *blob)
+{
+       if (CVAL(blob->data,DCERPC_DREP_OFFSET) & 0x10) {
+               return SVAL(blob->data, DCERPC_FRAG_LEN_OFFSET);
+       } else {
+               return RSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET);
+       }
+}
+
+void dcerpc_set_auth_length(DATA_BLOB *blob, uint16 v)
+{
+       if (CVAL(blob->data,DCERPC_DREP_OFFSET) & 0x10) {
+               SSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, v);
+       } else {
+               RSSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, v);
+       }
+}
+
 
 /* 
    parse a data blob into a dcerpc_packet structure. This handles both
@@ -79,6 +108,10 @@ static NTSTATUS dcerpc_pull(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
                return NT_STATUS_NO_MEMORY;
        }
 
+       if (! (CVAL(blob, DCERPC_DREP_OFFSET) & 0x10)) {
+               ndr->flags |= DCERPC_PULL_BIGENDIAN;
+       }
+
        return ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
 }
 
@@ -104,6 +137,10 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
                return NT_STATUS_NO_MEMORY;
        }
 
+       if (! (CVAL(blob, DCERPC_DREP_OFFSET) & 0x10)) {
+               ndr->flags |= DCERPC_PULL_BIGENDIAN;
+       }
+
        /* pull the basic packet */
        status = ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
        if (!NT_STATUS_IS_OK(status)) {
@@ -132,6 +169,10 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
                return NT_STATUS_NO_MEMORY;
        }
 
+       if (! (CVAL(blob, DCERPC_DREP_OFFSET) & 0x10)) {
+               ndr->flags |= DCERPC_PULL_BIGENDIAN;
+       }
+
        status = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -184,7 +225,7 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
 
        /* non-signed packets are simpler */
        if (!p->auth_info || !p->ntlmssp_state) {
-               return dcerpc_push_auth(blob, mem_ctx, pkt, p->auth_info);
+               return dcerpc_push_auth(blob, mem_ctx, pkt, p->auth_info, p->flags);
        }
 
        ndr = ndr_push_init_ctx(mem_ctx);
@@ -192,6 +233,10 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
                return NT_STATUS_NO_MEMORY;
        }
 
+       if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+               ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+       }
+
        status = ndr_push_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -242,8 +287,8 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
        /* fill in the fragment length and auth_length, we can't fill
           in these earlier as we don't know the signature length (it
           could be variable length) */
-       SSVAL(blob->data,  DCERPC_FRAG_LEN_OFFSET, blob->length);
-       SSVAL(blob->data,  DCERPC_AUTH_LEN_OFFSET, p->auth_info->credentials.length);
+       dcerpc_set_frag_length(blob, blob->length);
+       dcerpc_set_auth_length(blob, p->auth_info->credentials.length);
 
        data_blob_free(&p->auth_info->credentials);
 
@@ -254,11 +299,15 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
 /* 
    fill in the fixed values in a dcerpc header 
 */
-static void init_dcerpc_hdr(struct dcerpc_packet *pkt)
+static void init_dcerpc_hdr(struct dcerpc_pipe *p, struct dcerpc_packet *pkt)
 {
        pkt->rpc_vers = 5;
        pkt->rpc_vers_minor = 0;
-       pkt->drep[0] = 0x10; /* Little endian */
+       if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+               pkt->drep[0] = 0;
+       } else {
+               pkt->drep[0] = 0x10;
+       }
        pkt->drep[1] = 0;
        pkt->drep[2] = 0;
        pkt->drep[3] = 0;
@@ -281,7 +330,7 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p,
        DATA_BLOB blob;
        struct dcerpc_syntax_id tsyntax;
 
-       init_dcerpc_hdr(&pkt);
+       init_dcerpc_hdr(p, &pkt);
 
        pkt.ptype = DCERPC_PKT_BIND;
        pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
@@ -304,7 +353,7 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p,
        pkt.u.bind.auth_info = data_blob(NULL, 0);
 
        /* construct the NDR form of the packet */
-       status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info);
+       status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info, p->flags);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -353,7 +402,7 @@ NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p,
        NTSTATUS status;
        DATA_BLOB blob;
 
-       init_dcerpc_hdr(&pkt);
+       init_dcerpc_hdr(p, &pkt);
 
        pkt.ptype = DCERPC_PKT_AUTH3;
        pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
@@ -363,7 +412,7 @@ NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p,
        pkt.u.auth.auth_info = data_blob(NULL, 0);
 
        /* construct the NDR form of the packet */
-       status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info);
+       status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info, p->flags);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -392,15 +441,13 @@ NTSTATUS dcerpc_bind_byuuid(struct dcerpc_pipe *p,
                DEBUG(2,("Invalid uuid string in dcerpc_bind_byuuid\n"));
                return status;
        }
-       syntax.major_version = version;
-       syntax.minor_version = 0;
+       syntax.if_version = version;
 
        status = GUID_from_string(NDR_GUID, &transfer_syntax.uuid);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
-       transfer_syntax.major_version = NDR_GUID_VERSION;
-       transfer_syntax.minor_version = 0;
+       transfer_syntax.if_version = NDR_GUID_VERSION;
 
        return dcerpc_bind(p, mem_ctx, &syntax, &transfer_syntax);
 }
@@ -420,7 +467,7 @@ NTSTATUS dcerpc_request(struct dcerpc_pipe *p,
        DATA_BLOB blob, payload;
        uint32 remaining, chunk_size;
 
-       init_dcerpc_hdr(&pkt);
+       init_dcerpc_hdr(p, &pkt);
 
        remaining = stub_data_in->length;
 
@@ -552,6 +599,12 @@ NTSTATUS dcerpc_request(struct dcerpc_pipe *p,
                *stub_data_out = payload;
        }
 
+       if (!(pkt.drep[0] & 0x10)) {
+               p->flags |= DCERPC_PULL_BIGENDIAN;
+       } else {
+               p->flags &= ~DCERPC_PULL_BIGENDIAN;
+       }
+
        return status;
 }
 
@@ -723,6 +776,10 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p,
                return NT_STATUS_NO_MEMORY;
        }
 
+       if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+               push->flags |= LIBNDR_FLAG_BIGENDIAN;
+       }
+
        /* push the structure into a blob */
        status = ndr_push(push, NDR_IN, struct_ptr);
        if (!NT_STATUS_IS_OK(status)) {
@@ -755,6 +812,10 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p,
                goto failed;
        }
 
+       if (p->flags & DCERPC_PULL_BIGENDIAN) {
+               pull->flags |= LIBNDR_FLAG_BIGENDIAN;
+       }
+
        DEBUG(10,("rpc reply data:\n"));
        dump_data(10, pull->data, pull->data_size);
 
index fa2ced253713d42c73cefa56cc15928fe43ce6e9..5d258820418f2a7417f90e8ccc31ddf50ab61922 100644 (file)
@@ -65,6 +65,9 @@ struct dcerpc_pipe {
 #define DCERPC_SIGN            16
 #define DCERPC_SEAL            32
 
+#define DCERPC_PUSH_BIGENDIAN   64
+#define DCERPC_PULL_BIGENDIAN  128
+
 /*
   this is used to find pointers to calls
 */
index 9acae002491270fc5125b3a535a597eb48964437..fc71a47cf4012758fb0aa6cabafc75add3c7610d 100644 (file)
@@ -91,7 +91,7 @@ static NTSTATUS dcerpc_raw_recv(struct dcerpc_pipe *p,
 
        /* we might have recieved a partial fragment, in which case we
           need to pull the rest of it */
-       frag_length = SVAL(payload.data, 8);
+       frag_length = dcerpc_get_frag_length(&payload);
        if (frag_length <= payload.length) {
                goto done;
        }
@@ -197,7 +197,7 @@ NTSTATUS smb_secondary_request(struct dcerpc_pipe *p,
                return status;
        }
 
-       frag_length = SVAL(blob->data, 8);
+       frag_length = dcerpc_get_frag_length(blob);
        if (frag_length <= blob->length) {
                return status;
        }
index 468cd9465b66809bde1516549005b6d614dd9f0c..b577260033ca719e4c3c54ef219315725913bef1 100644 (file)
@@ -60,7 +60,7 @@ static NTSTATUS tcp_raw_recv(struct dcerpc_pipe *p,
 
        /* we might have recieved a partial fragment, in which case we
           need to pull the rest of it */
-       frag_length = SVAL(blob1.data, 8);
+       frag_length = dcerpc_get_frag_length(&blob1);
        if (frag_length == blob1.length) {
                *blob = blob1;
                return NT_STATUS_OK;
index 02e224a26f2690405968ba4213dfe8d197ebb29b..fbc97f316ddfd8158e08ca70a303c2a5a9feff40 100644 (file)
@@ -59,7 +59,7 @@ NTSTATUS dcerpc_epm_map_tcp_port(const char *server,
        NTSTATUS status;
        struct epm_Map r;
        struct policy_handle handle;
-       GUID guid;
+       struct GUID guid;
        struct epm_twr_t twr, *twr_r;
 
        if (strcasecmp(uuid, DCERPC_EPMAPPER_UUID) == 0 ||
@@ -223,7 +223,8 @@ const struct dcerpc_interface_table *idl_iface_by_uuid(const char *uuid)
 */
 NTSTATUS dcerpc_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, 
                          struct dcerpc_packet *pkt,
-                         struct dcerpc_auth *auth_info)
+                         struct dcerpc_auth *auth_info,
+                         unsigned flags)
 {
        NTSTATUS status;
        struct ndr_push *ndr;
@@ -233,6 +234,10 @@ NTSTATUS dcerpc_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
                return NT_STATUS_NO_MEMORY;
        }
 
+       if (flags & DCERPC_PUSH_BIGENDIAN) {
+               ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+       }
+
        if (auth_info) {
                pkt->auth_length = auth_info->credentials.length;
        } else {
@@ -251,7 +256,7 @@ NTSTATUS dcerpc_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
        *blob = ndr_push_blob(ndr);
 
        /* fill in the frag length */
-       SSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, blob->length);
+       dcerpc_set_frag_length(blob, blob->length);
 
        return NT_STATUS_OK;
 }
@@ -278,7 +283,8 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_
        } options[] = {
                {"sign", DCERPC_SIGN},
                {"seal", DCERPC_SEAL},
-               {"validate", DCERPC_DEBUG_VALIDATE_BOTH}
+               {"validate", DCERPC_DEBUG_VALIDATE_BOTH},
+               {"bigendian", DCERPC_PUSH_BIGENDIAN}
        };
 
        p = strchr(s, ':');
index a3b3ab19b754770a35c49e03ebe795953a420959..96f28895c9bde84c685876040a983e31f827e560 100644 (file)
@@ -181,10 +181,13 @@ static NTSTATUS ipc_setpathinfo(struct request_context *req, union smb_setfilein
        return NT_STATUS_ACCESS_DENIED;
 }
 
+
+
 /*
-  open a file - used for MSRPC pipes
+  open a file backend - used for MSRPC pipes
 */
-static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi)
+static NTSTATUS ipc_open_generic(struct request_context *req, const char *fname, 
+                                struct pipe_state **ps)
 {
        struct pipe_state *p;
        TALLOC_CTX *mem_ctx;
@@ -192,12 +195,7 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi)
        struct dcesrv_endpoint endpoint;
        struct ipc_private *private = req->conn->ntvfs_private;
 
-       /* for now only handle NTcreateX style opens */
-       if (oi->generic.level != RAW_OPEN_NTCREATEX) {
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
-       mem_ctx = talloc_init("ipc_open '%s'", oi->ntcreatex.in.fname);
+       mem_ctx = talloc_init("ipc_open '%s'", fname);
        if (!mem_ctx) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -209,7 +207,7 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi)
        }
        p->mem_ctx = mem_ctx;
 
-       p->pipe_name = talloc_strdup(mem_ctx, oi->ntcreatex.in.fname);
+       p->pipe_name = talloc_strdup(mem_ctx, fname);
        if (!p->pipe_name) {
                talloc_destroy(mem_ctx);
                return NT_STATUS_NO_MEMORY;
@@ -250,11 +248,79 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi)
 
        DLIST_ADD(private->pipe_list, p);
 
+       *ps = p;
+
+       return NT_STATUS_OK;
+}
+
+/*
+  open a file with ntcreatex - used for MSRPC pipes
+*/
+static NTSTATUS ipc_open_ntcreatex(struct request_context *req, union smb_open *oi)
+{
+       struct pipe_state *p;
+       NTSTATUS status;
+
+       status = ipc_open_generic(req, oi->ntcreatex.in.fname, &p);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        ZERO_STRUCT(oi->ntcreatex.out);
        oi->ntcreatex.out.fnum = p->fnum;
        oi->ntcreatex.out.ipc_state = p->ipc_state;
 
-       return NT_STATUS_OK;
+       return status;
+}
+
+/*
+  open a file with openx - used for MSRPC pipes
+*/
+static NTSTATUS ipc_open_openx(struct request_context *req, union smb_open *oi)
+{
+       struct pipe_state *p;
+       NTSTATUS status;
+       const char *fname = oi->openx.in.fname;
+
+       if (strncasecmp(fname, "PIPE\\", 5) != 0) {
+               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
+
+       fname += 4;
+
+       status = ipc_open_generic(req, fname, &p);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       ZERO_STRUCT(oi->openx.out);
+       oi->openx.out.fnum = p->fnum;
+       oi->openx.out.ftype = 2;
+       oi->openx.out.devstate = p->ipc_state;
+       
+       return status;
+}
+
+/*
+  open a file - used for MSRPC pipes
+*/
+static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi)
+{
+       NTSTATUS status;
+
+       switch (oi->generic.level) {
+       case RAW_OPEN_NTCREATEX:
+               status = ipc_open_ntcreatex(req, oi);
+               break;
+       case RAW_OPEN_OPENX:
+               status = ipc_open_openx(req, oi);
+               break;
+       default:
+               status = NT_STATUS_NOT_SUPPORTED;
+               break;
+       }
+
+       return status;
 }
 
 /*
index 60e211e66facf418c41f68c051f9625b2e3d82c7..486ccb8b111474ee46ddf7310a2137899907adf8 100644 (file)
@@ -141,25 +141,44 @@ BOOL secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
        return True;
 }
 
-BOOL secrets_store_domain_guid(const char *domain, GUID *guid)
+BOOL secrets_store_domain_guid(const char *domain, struct GUID *guid)
 {
+       const char *s;
        fstring key;
+       TALLOC_CTX *mem_ctx;
+       BOOL ret;
+       
+       mem_ctx = talloc_init("secrets_store_domain_guid");
+       if (!mem_ctx) {
+               return False;
+       }
+
+       s = GUID_string(mem_ctx, guid);
+       if (!s) {
+               talloc_destroy(mem_ctx);
+               return False;
+       }
+
 
        slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
        strupper(key);
-       return secrets_store(key, guid, sizeof(GUID));
+       ret = secrets_store(key, s, strlen(s)+1);
+       
+       talloc_destroy(mem_ctx);
+       return ret;
 }
 
-BOOL secrets_fetch_domain_guid(const char *domain, GUID *guid)
+BOOL secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
 {
-       GUID *dyn_guid;
+       char *dyn_guid;
        fstring key;
        size_t size;
-       GUID new_guid;
+       struct GUID new_guid;
+       NTSTATUS status;
 
        slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
        strupper(key);
-       dyn_guid = (GUID *)secrets_fetch(key, &size);
+       dyn_guid = secrets_fetch(key, &size);
 
        DEBUG(6,("key is %s, size is %d\n", key, (int)size));
 
@@ -167,19 +186,18 @@ BOOL secrets_fetch_domain_guid(const char *domain, GUID *guid)
                uuid_generate_random(&new_guid);
                if (!secrets_store_domain_guid(domain, &new_guid))
                        return False;
-               dyn_guid = (GUID *)secrets_fetch(key, &size);
+               dyn_guid = secrets_fetch(key, &size);
                if (dyn_guid == NULL)
                        return False;
        }
 
-       if (size != sizeof(GUID))
-       { 
-               SAFE_FREE(dyn_guid);
+       status = GUID_from_string(dyn_guid, guid);
+       SAFE_FREE(dyn_guid);
+
+       if (!NT_STATUS_IS_OK(status)) {
                return False;
        }
 
-       *guid = *dyn_guid;
-       SAFE_FREE(dyn_guid);
        return True;
 }
 
index f3c7a63c79f1bd06ac7dfd66919a8a6e8fbb8828..5780de0c302bfabd65729f0ddce24a90d063616c 100644 (file)
@@ -209,7 +209,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code)
                return NT_STATUS_NO_MEMORY;
        }
 
-       status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL);
+       status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL, 0);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -266,7 +266,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32 reason)
                return NT_STATUS_NO_MEMORY;
        }
 
-       status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL);
+       status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL, 0);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -296,13 +296,13 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
                return dcesrv_bind_nak(call, 0);
        }
 
-       if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.major_version;
+       if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.if_version;
        uuid = GUID_string(call->mem_ctx, &call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid);
        if (!uuid) {
                return dcesrv_bind_nak(call, 0);
        }
 
-       transfer_syntax_version = call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].major_version;
+       transfer_syntax_version = call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].if_version;
        transfer_syntax = GUID_string(call->mem_ctx, 
                                      &call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].uuid);
        if (!transfer_syntax ||
@@ -356,8 +356,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
        pkt.u.bind_ack.ctx_list[0].result = result;
        pkt.u.bind_ack.ctx_list[0].reason = reason;
        GUID_from_string(NDR_GUID, &pkt.u.bind_ack.ctx_list[0].syntax.uuid);
-       pkt.u.bind_ack.ctx_list[0].syntax.major_version = NDR_GUID_VERSION;
-       pkt.u.bind_ack.ctx_list[0].syntax.minor_version = 0;
+       pkt.u.bind_ack.ctx_list[0].syntax.if_version = NDR_GUID_VERSION;
        pkt.u.bind_ack.auth_info = data_blob(NULL, 0);
 
        if (!dcesrv_auth_bind_ack(call, &pkt)) {
@@ -370,7 +369,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
        }
 
        status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, 
-                                 call->dce->auth_state.auth_info);
+                                 call->dce->auth_state.auth_info, 0);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
index f290c741cb6650d23f2c439c2bef10bc11e37f0d..0f4b22ee3d068a68d260d0ae8d14e5b7c9efd6ed 100644 (file)
@@ -232,7 +232,7 @@ BOOL dcesrv_auth_response(struct dcesrv_call_state *call,
 
        /* non-signed packets are simple */
        if (!dce->auth_state.auth_info || !dce->auth_state.ntlmssp_state) {
-               status = dcerpc_push_auth(blob, call->mem_ctx, pkt, NULL);
+               status = dcerpc_push_auth(blob, call->mem_ctx, pkt, NULL, 0);
                return NT_STATUS_IS_OK(status);
        }
 
index f2ecc0faa99b64889909c461d48e09295c8f1068..5e571ee1ef7ca9f81e216d6de296b38f53c99072 100644 (file)
@@ -30,7 +30,7 @@ enum handle_types {HTYPE_LOOKUP};
 /*
   simple routine to compare a GUID string to a GUID structure
 */
-static int guid_cmp(TALLOC_CTX *mem_ctx, const GUID *guid, const char *uuid_str)
+static int guid_cmp(TALLOC_CTX *mem_ctx, const struct GUID *guid, const char *uuid_str)
 {
        const char *s = GUID_string(mem_ctx, guid);
        if (!s || strcasecmp(s, uuid_str)) {
index 19f313a8604b0b517a0f66332cbf0488339824b4..6a15aad137cac9d34d851cf62ddad8b1d244c69f 100644 (file)
@@ -202,6 +202,7 @@ static NTSTATUS trans2_qfsinfo(struct request_context *req, struct smb_trans2 *t
        NTSTATUS status;
        uint16 level;
        uint_t i;
+       DATA_BLOB guid_blob;
 
        /* make sure we got enough parameters */
        if (trans->in.params.length != 2) {
@@ -369,7 +370,15 @@ static NTSTATUS trans2_qfsinfo(struct request_context *req, struct smb_trans2 *t
 
                trans2_setup_reply(req, trans, 0, 64, 0);
 
-               memcpy(trans->out.data.data, fsinfo.objectid_information.out.guid.info, GUID_SIZE);
+               status = ndr_push_struct_blob(&guid_blob, req->mem_ctx, 
+                                             &fsinfo.objectid_information.out.guid,
+                                             (ndr_push_flags_fn_t)ndr_push_GUID);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+
+               memcpy(trans->out.data.data, guid_blob.data, GUID_SIZE);
+
                for (i=0;i<6;i++) {
                        SBVAL(trans->out.data.data, 16 + 8*i, fsinfo.objectid_information.out.unknown[i]);
                }
index afc83a512da67109afb3634bcd64b84d6a126086..2b704659d6e245564b8a0a85a4114feca2fdb11f 100644 (file)
@@ -104,7 +104,7 @@ static BOOL test_Map(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 {
        NTSTATUS status;
        struct epm_Map r;
-       GUID uuid;
+       struct GUID uuid;
        const char *uuid_str;
        struct policy_handle handle;
        int i;
index 24bf080ffb9995471919f29a9516baa356dd32cd..3a50732c7e6dbcf38b540b8d5cc0807d5dd1c8a5 100644 (file)
@@ -55,10 +55,9 @@ static BOOL test_inq_if_ids(struct dcerpc_pipe *p,
 
                uuid = GUID_string(mem_ctx, &id->uuid);
 
-               printf("\tuuid %s  version 0x%04x:0x%04x  '%s'\n",
+               printf("\tuuid %s  version 0x%08x  '%s'\n",
                       uuid,
-                      id->major_version, id->minor_version,
-                      idl_pipe_name(uuid, id->major_version));
+                      id->if_version, idl_pipe_name(uuid, id->if_version));
        }
 
        return True;
index 3469294552efea9e354d33bea24e39d20a7e436e..99c047bf2ec8aeb8ad062bcc245bc6cb3fb9efb4 100644 (file)
@@ -39,7 +39,7 @@ static BOOL test_num_calls(const struct dcerpc_interface_table *iface,
        uuid = GUID_string(mem_ctx, &id->uuid);
 
        status = torture_rpc_connection(&p, iface->name,
-                                       uuid, id->major_version);
+                                       uuid, id->if_version);
        if (!NT_STATUS_IS_OK(status)) {
                printf("Failed to connect to '%s' on '%s' - %s\n", 
                       uuid, iface->name, nt_errstr(status));
@@ -69,7 +69,7 @@ static BOOL test_num_calls(const struct dcerpc_interface_table *iface,
        }
 
        printf("\t%d calls available\n", i);
-       idl_calls = idl_num_calls(uuid, id->major_version);
+       idl_calls = idl_num_calls(uuid, id->if_version);
        if (idl_calls == -1) {
                printf("\tinterface not known in local IDL\n");
        } else if (i != idl_calls) {
@@ -117,10 +117,9 @@ static BOOL test_inq_if_ids(struct dcerpc_pipe *p,
 
                uuid = GUID_string(mem_ctx, &id->uuid),
 
-               printf("\n\tuuid %s  version 0x%04x:0x%04x  '%s'\n",
+               printf("\n\tuuid %s  version 0x%08x '%s'\n",
                       uuid,
-                      id->major_version, id->minor_version,
-                      idl_pipe_name(uuid, id->major_version));
+                      id->if_version, idl_pipe_name(uuid, id->if_version));
                test_num_calls(iface, mem_ctx, id);
        }