[Samba4][Patch]: padding dcerpc faults packets

View: New views
5 Messages — Rating Filter:   Alert me  

[Samba4][Patch]: padding dcerpc faults packets

by Julien Kerihuel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi List,

I've noticed a difference between dcerpc faults sent from a real
Exchange server and dcerpc_server in Samba4.

Samba4 (after calculation) sends the dcerpc fault with a fraglen set to
28 bytes - which is the correct size - while Exchange appends 4 padding
bytes set to 0 and set the fraglen to 32 bytes. I can send some captures
if needed.

This difference matters when Outlook connects to an Exchange server and
requests for an unsupported operation. If for example we connect Outlook
2003 to Exchange 2000:
        1. Outlook 2003 first tries to connect using EcDoConnectEx (0xa)
        but Exchange 2000 doesn't support this operation.
       
        2. Exchange 2000 sends a dcerpc fault with
        dcerpc_fault_op_nrg_error.
       
        3. Outlook 2003 tries to use EcDoConnect(0x0) instead and the
        "real communication" starts.

The main problem is:
        * If these 4 bytes are present, then Outlook retrogrades its
        protocol version and calls EcDoConnect and everything is fine.
       
        * If these 4 bytes are missing, then Outlook unexpectedly ends
        the connection (FIN/ACK), then binds on the emsmdb server and
        repeat the same operation over and over until Outlook stops and
        display and error message box.

The attached patch adds a uint32_t padding field to the
dcesrv_call_state structure and if this field is defined, realloc the
fault blob with the specified number of padding bytes.

The scope of this patch is limited to dcesrv_fault -- doesn't seem to
occur with real RPC operations.

It is quite weird, but it makes Outlook happy ...

Cheers,
Julien.

--
Julien Kerihuel
j.kerihuel@...
OpenChange Project Manager

GPG Fingerprint: 0B55 783D A781 6329 108A  B609 7EF6 FE11 A35F 1F79


[dcerpc_server_padding_bytes.diff]

diff --git a/source/rpc_server/dcerpc_server.c b/source/rpc_server/dcerpc_server.c
index beb795e..3fd3e54 100644
--- a/source/rpc_server/dcerpc_server.c
+++ b/source/rpc_server/dcerpc_server.c
@@ -468,6 +468,17 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code
  if (!NT_STATUS_IS_OK(status)) {
  return status;
  }
+
+ if (call->padding) {
+ rep->blob.data = talloc_realloc((TALLOC_CTX *)call,
+ rep->blob.data, uint8_t,
+ rep->blob.length + call->padding);
+ if (!rep->blob.data) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ memset(&rep->blob.data[rep->blob.length], call->padding, 0);
+ rep->blob.length += call->padding;
+ }
 
  dcerpc_set_frag_length(&rep->blob, rep->blob.length);
 
diff --git a/source/rpc_server/dcerpc_server.h b/source/rpc_server/dcerpc_server.h
index 058dfe3..8a5ff55 100644
--- a/source/rpc_server/dcerpc_server.h
+++ b/source/rpc_server/dcerpc_server.h
@@ -128,6 +128,9 @@ struct dcesrv_call_state {
 
  /* this is used by the boilerplate code to generate DCERPC faults */
  uint32_t fault_code;
+
+ /* this is used to add custom padding bytes to replies */
+ uint32_t padding;
 };
 
 #define DCESRV_HANDLE_ANY 255



signature.asc (196 bytes) Download Attachment

Re: [Samba4][Patch]: padding dcerpc faults packets

by Stefan (metze) Metzmacher :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

hi Julien,
> Samba4 (after calculation) sends the dcerpc fault with a fraglen set to
> 28 bytes - which is the correct size - while Exchange appends 4 padding
> bytes set to 0 and set the fraglen to 32 bytes. I can send some captures
> if needed.

NT4 also sends 32 bytes for the not supported
LsarQueryInformationPolicy2

And w2k3 also replies with 32 byte with DCERPC_FAULT_ACCESS_DENIED
when I try DRSUAPI over ncacn_np.

So I think it's better when we always send 32 byte too.

metze



signature.asc (257 bytes) Download Attachment

Re: [Samba4][Patch]: padding dcerpc faults packets

by Volker Lendecke :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, May 13, 2008 at 05:33:34PM +0200, Stefan (metze) Metzmacher wrote:

> hi Julien,
> > Samba4 (after calculation) sends the dcerpc fault with a fraglen set to
> > 28 bytes - which is the correct size - while Exchange appends 4 padding
> > bytes set to 0 and set the fraglen to 32 bytes. I can send some captures
> > if needed.
>
> NT4 also sends 32 bytes for the not supported
> LsarQueryInformationPolicy2
>
> And w2k3 also replies with 32 byte with DCERPC_FAULT_ACCESS_DENIED
> when I try DRSUAPI over ncacn_np.
>
> So I think it's better when we always send 32 byte too.
I wonder where you find this in the protocol docs ;-)

Volker


attachment0 (196 bytes) Download Attachment

Re: [Samba4][Patch]: padding dcerpc faults packets

by Julien Kerihuel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Modified patch attached.

Cheers,
Julien.

On Tue, 2008-05-13 at 17:33 +0200, Stefan (metze) Metzmacher wrote:

> hi Julien,
> > Samba4 (after calculation) sends the dcerpc fault with a fraglen set to
> > 28 bytes - which is the correct size - while Exchange appends 4 padding
> > bytes set to 0 and set the fraglen to 32 bytes. I can send some captures
> > if needed.
>
> NT4 also sends 32 bytes for the not supported
> LsarQueryInformationPolicy2
>
> And w2k3 also replies with 32 byte with DCERPC_FAULT_ACCESS_DENIED
> when I try DRSUAPI over ncacn_np.
>
> So I think it's better when we always send 32 byte too.
>
> metze
>
--
Julien Kerihuel
j.kerihuel@...
OpenChange Project Manager

GPG Fingerprint: 0B55 783D A781 6329 108A  B609 7EF6 FE11 A35F 1F79


[dcerpc_server_padding_bytes_static.diff]

diff --git a/source/rpc_server/dcerpc_server.c b/source/rpc_server/dcerpc_server.c
index 1962a97..06b5cf2 100644
--- a/source/rpc_server/dcerpc_server.c
+++ b/source/rpc_server/dcerpc_server.c
@@ -468,6 +468,16 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code
  return status;
  }
 
+ rep->blob.data = talloc_realloc((TALLOC_CTX *)call,
+ rep->blob.data, uint8_t,
+ rep->blob.length + sizeof (uint32_t));
+ if (!rep->blob.data) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ memset(&rep->blob.data[rep->blob.length], sizeof (uint32_t), 0);
+ rep->blob.length += sizeof (uint32_t);
+
  dcerpc_set_frag_length(&rep->blob, rep->blob.length);
 
  DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *);



signature.asc (196 bytes) Download Attachment

Re: [Samba4][Patch]: padding dcerpc faults packets

by Julien Kerihuel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Following Metze recommendations and the very famous IRC to diff
mechanism ;p you'll find below the last version of the patch.

This patch adds remaining padding bytes to the dcerpc_fault IDL
structure and adds a const 4 bytes blob to pkt.u.fault.

Cheers,
Julien.

On Wed, 2008-05-14 at 17:30 +0200, Julien Kerihuel wrote:

> Modified patch attached.
>
> Cheers,
> Julien.
>
> On Tue, 2008-05-13 at 17:33 +0200, Stefan (metze) Metzmacher wrote:
> > hi Julien,
> > > Samba4 (after calculation) sends the dcerpc fault with a fraglen set to
> > > 28 bytes - which is the correct size - while Exchange appends 4 padding
> > > bytes set to 0 and set the fraglen to 32 bytes. I can send some captures
> > > if needed.
> >
> > NT4 also sends 32 bytes for the not supported
> > LsarQueryInformationPolicy2
> >
> > And w2k3 also replies with 32 byte with DCERPC_FAULT_ACCESS_DENIED
> > when I try DRSUAPI over ncacn_np.
> >
> > So I think it's better when we always send 32 byte too.
> >
> > metze
> >
--
Julien Kerihuel
j.kerihuel@...
OpenChange Project Manager

GPG Fingerprint: 0B55 783D A781 6329 108A  B609 7EF6 FE11 A35F 1F79


[dcerpc_server_padding_bytes_idl.diff]

diff --git a/source/librpc/idl/dcerpc.idl b/source/librpc/idl/dcerpc.idl
index b2c6754..e228d85 100644
--- a/source/librpc/idl/dcerpc.idl
+++ b/source/librpc/idl/dcerpc.idl
@@ -116,6 +116,7 @@ interface dcerpc
  uint16 context_id;
  uint8 cancel_count;
  uint32 status;
+ [flag(NDR_REMAINING)] DATA_BLOB _pad;
  } dcerpc_fault;
 
  /* the auth types we know about */
diff --git a/source/rpc_server/dcerpc_server.c b/source/rpc_server/dcerpc_server.c
index 1962a97..83114c6 100644
--- a/source/rpc_server/dcerpc_server.c
+++ b/source/rpc_server/dcerpc_server.c
@@ -445,6 +445,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code
 {
  struct ncacn_packet pkt;
  struct data_blob_list_item *rep;
+ uint8_t zeros[4];
  NTSTATUS status;
 
  /* setup a bind_ack */
@@ -457,6 +458,9 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code
  pkt.u.fault.context_id = 0;
  pkt.u.fault.cancel_count = 0;
  pkt.u.fault.status = fault_code;
+
+ ZERO_STRUCT(zeros);
+ pkt.u.fault._pad = data_blob_const(zeros, sizeof(zeros));
 
  rep = talloc(call, struct data_blob_list_item);
  if (!rep) {



signature.asc (196 bytes) Download Attachment