rpc_server: correct the chunk_size depending on the signature size
authorStefan Metzmacher <metze@samba.org>
Mon, 11 Aug 2008 16:12:54 +0000 (18:12 +0200)
committerStefan Metzmacher <metze@samba.org>
Mon, 11 Aug 2008 16:15:59 +0000 (18:15 +0200)
metze
(This used to be commit 20fc0d7bfdaa60d6a8ac939dc64733a91652587e)

source4/rpc_server/dcerpc_server.c
source4/rpc_server/dcesrv_auth.c

index a336ddb3398b1208bf3c60d591be26847e573942..fa7b8d26f5c72fe0c57ffb6d47e1f957da898b84 100644 (file)
@@ -917,6 +917,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call)
        DATA_BLOB stub;
        uint32_t total_length, chunk_size;
        struct dcesrv_connection_context *context = call->context;
        DATA_BLOB stub;
        uint32_t total_length, chunk_size;
        struct dcesrv_connection_context *context = call->context;
+       size_t sig_size = 0;
 
        /* call the reply function */
        status = context->iface->reply(call, call, call->r);
 
        /* call the reply function */
        status = context->iface->reply(call, call, call->r);
@@ -948,7 +949,15 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call)
 
        /* we can write a full max_recv_frag size, minus the dcerpc
           request header size */
 
        /* we can write a full max_recv_frag size, minus the dcerpc
           request header size */
-       chunk_size = call->conn->cli_max_recv_frag - (DCERPC_MAX_SIGN_SIZE+DCERPC_REQUEST_LENGTH);
+       chunk_size = call->conn->cli_max_recv_frag;
+       chunk_size -= DCERPC_REQUEST_LENGTH;
+       if (call->conn->auth_state.gensec_security) {
+               chunk_size -= DCERPC_AUTH_TRAILER_LENGTH;
+               sig_size = gensec_sig_size(call->conn->auth_state.gensec_security,
+                                          call->conn->cli_max_recv_frag);
+               chunk_size -= sig_size;
+               chunk_size -= (chunk_size % 16);
+       }
 
        do {
                uint32_t length;
 
        do {
                uint32_t length;
@@ -978,7 +987,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call)
                pkt.u.response.stub_and_verifier.data = stub.data;
                pkt.u.response.stub_and_verifier.length = length;
 
                pkt.u.response.stub_and_verifier.data = stub.data;
                pkt.u.response.stub_and_verifier.length = length;
 
-               if (!dcesrv_auth_response(call, &rep->blob, &pkt)) {
+               if (!dcesrv_auth_response(call, &rep->blob, sig_size, &pkt)) {
                        return dcesrv_fault(call, DCERPC_FAULT_OTHER);          
                }
 
                        return dcesrv_fault(call, DCERPC_FAULT_OTHER);          
                }
 
index 64f42eea257d35066b7f3033158a03ccbd0dd1cf..0aad3775d0bfdf08a763c279e956164a1285e900 100644 (file)
@@ -398,7 +398,8 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet)
    push a signed or sealed dcerpc request packet into a blob
 */
 bool dcesrv_auth_response(struct dcesrv_call_state *call,
    push a signed or sealed dcerpc request packet into a blob
 */
 bool dcesrv_auth_response(struct dcesrv_call_state *call,
-                         DATA_BLOB *blob, struct ncacn_packet *pkt)
+                         DATA_BLOB *blob, size_t sig_size,
+                         struct ncacn_packet *pkt)
 {
        struct dcesrv_connection *dce_conn = call->conn;
        NTSTATUS status;
 {
        struct dcesrv_connection *dce_conn = call->conn;
        NTSTATUS status;
@@ -445,9 +446,7 @@ bool dcesrv_auth_response(struct dcesrv_call_state *call,
                 * GENSEC mech does AEAD signing of the packet
                 * headers */
                dce_conn->auth_state.auth_info->credentials
                 * GENSEC mech does AEAD signing of the packet
                 * headers */
                dce_conn->auth_state.auth_info->credentials
-                       = data_blob_talloc(call, NULL, 
-                                          gensec_sig_size(dce_conn->auth_state.gensec_security, 
-                                                          payload_length));
+                       = data_blob_talloc(call, NULL, sig_size);
                data_blob_clear(&dce_conn->auth_state.auth_info->credentials);
        }
 
                data_blob_clear(&dce_conn->auth_state.auth_info->credentials);
        }