s3-dceprc: Improve dcerpc_guess_sizes() interface
authorSimo Sorce <idra@samba.org>
Fri, 30 Jul 2010 17:12:35 +0000 (13:12 -0400)
committerSimo Sorce <idra@samba.org>
Fri, 30 Jul 2010 18:55:28 +0000 (14:55 -0400)
Make it possible to pass in the NDR padding size so that theoretically
client and server code can decide to use a different alignment.

Pass in the header length as a parameter so that this function can be used for
different type of packets.

Make sure padding size will not make the fragment exceed the maximum length.

Calculate padding taking in account the header length.

source3/librpc/rpc/dcerpc.h
source3/librpc/rpc/dcerpc_helpers.c
source3/rpc_client/cli_pipe.c

index fd80dbeb04acc288f3ca335177dabd142052f429..f07403ae44e3fa9e3eb63947d62fafe5777a1974 100644 (file)
@@ -140,7 +140,8 @@ NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
                                 struct dcerpc_auth *r,
                                 bool bigendian);
 NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
-                           size_t data_left, size_t max_xmit_frag,
+                           size_t header_len, size_t data_left,
+                           size_t max_xmit_frag, size_t pad_alignment,
                            size_t *data_to_send, size_t *frag_len,
                            size_t *auth_len, size_t *pad_len);
 NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth,
index e089e9cbf04cd936014eff02ba9897f628dc8c29..84f7ce4c8262ce24a0e72beba61d7f7e4a46afbb 100644 (file)
@@ -246,20 +246,23 @@ NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
 *       auth token and pad lengths.
 *
 * @param auth          The pipe_auth_data structure for this pipe.
+* @param header_len    The length of the packet header
 * @param data_left     The data left in the send buffer
-* @param data_to_send  The max data we will send in the pdu
-* @param frag_len      The total length of the fragment
-* @param auth_len      The length of the auth trailer
-* @param pad_len       The padding to be applied
+* @param max_xmit_frag The max fragment size.
+* @param pad_alignment The NDR padding size.
+* @param data_to_send  [out] The max data we will send in the pdu
+* @param frag_len      [out] The total length of the fragment
+* @param auth_len      [out] The length of the auth trailer
+* @param pad_len       [out] The padding to be applied
 *
 * @return A NT Error status code.
 */
 NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
-                           size_t data_left, size_t max_xmit_frag,
+                           size_t header_len, size_t data_left,
+                           size_t max_xmit_frag, size_t pad_alignment,
                            size_t *data_to_send, size_t *frag_len,
                            size_t *auth_len, size_t *pad_len)
 {
-       size_t data_space;
        size_t max_len;
        size_t mod_len;
        struct gse_context *gse_ctx;
@@ -273,11 +276,11 @@ NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
        case DCERPC_AUTH_LEVEL_NONE:
        case DCERPC_AUTH_LEVEL_CONNECT:
        case DCERPC_AUTH_LEVEL_PACKET:
-               data_space = max_xmit_frag - DCERPC_REQUEST_LENGTH;
-               *data_to_send = MIN(data_space, data_left);
+               max_len = max_xmit_frag - header_len;
+               *data_to_send = MIN(max_len, data_left);
                *pad_len = 0;
                *auth_len = 0;
-               *frag_len = DCERPC_REQUEST_LENGTH + *data_to_send;
+               *frag_len = header_len + *data_to_send;
                return NT_STATUS_OK;
 
        case DCERPC_AUTH_LEVEL_PRIVACY:
@@ -294,9 +297,7 @@ NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
 
        /* Sign/seal case, calculate auth and pad lengths */
 
-       max_len = max_xmit_frag
-                       - DCERPC_REQUEST_LENGTH
-                       - DCERPC_AUTH_TRAILER_LENGTH;
+       max_len = max_xmit_frag - header_len - DCERPC_AUTH_TRAILER_LENGTH;
 
        /* Treat the same for all authenticated rpc requests. */
        switch (auth->auth_type) {
@@ -349,17 +350,23 @@ NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       data_space = max_len - *auth_len;
+       max_len -= *auth_len;
 
-       *data_to_send = MIN(data_space, data_left);
-       mod_len = *data_to_send % CLIENT_NDR_PADDING_SIZE;
+       *data_to_send = MIN(max_len, data_left);
+
+       mod_len = (header_len + *data_to_send) % pad_alignment;
        if (mod_len) {
-               *pad_len = CLIENT_NDR_PADDING_SIZE - mod_len;
+               *pad_len = pad_alignment - mod_len;
        } else {
                *pad_len = 0;
        }
-       *frag_len = DCERPC_REQUEST_LENGTH + *data_to_send + *pad_len
-                               + DCERPC_AUTH_TRAILER_LENGTH + *auth_len;
+
+       if (*data_to_send + *pad_len > max_len) {
+               *data_to_send -= pad_alignment;
+       }
+
+       *frag_len = header_len + *data_to_send + *pad_len
+                       + DCERPC_AUTH_TRAILER_LENGTH + *auth_len;
 
        return NT_STATUS_OK;
 }
index 99e856dfd826afc572e8491f0a60a7fa36dfebad..2bb9aad9e310aa1d294646214711e1be64aba1bb 100644 (file)
@@ -1286,8 +1286,10 @@ static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
 
        data_left = state->req_data->length - state->req_data_sent;
 
-       status = dcerpc_guess_sizes(state->cli->auth, data_left,
+       status = dcerpc_guess_sizes(state->cli->auth,
+                                   DCERPC_REQUEST_LENGTH, data_left,
                                    state->cli->max_xmit_frag,
+                                   CLIENT_NDR_PADDING_SIZE,
                                    &data_sent_thistime,
                                    &frag_len, &auth_len, &pad_len);
        if (!NT_STATUS_IS_OK(status)) {