s3:librpc/rpc: fix padding calculation in dcerpc_guess_sizes()
authorStefan Metzmacher <metze@samba.org>
Fri, 19 Jun 2015 13:52:11 +0000 (15:52 +0200)
committerKarolin Seeger <kseeger@samba.org>
Sat, 11 Jul 2015 19:59:25 +0000 (21:59 +0200)
The padding needs to be relative to the payload start not to the pdu start.
We also need align the padding to DCERPC_AUTH_PAD_ALIGNMENT (16 bytes).

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11061

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
(similar to commit b2e042ad9652e2dfb39640de43e09030efc41d3d)

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

index b3ae3b4e5c45364cc9b4c2fbee8af7398cb7914d..60b91d6dfa78a5beb11935c31a843f26a5b2fda7 100644 (file)
@@ -76,7 +76,7 @@ NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
                                 bool bigendian);
 NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
                            size_t header_len, size_t data_left,
-                           size_t max_xmit_frag, size_t pad_alignment,
+                           size_t max_xmit_frag,
                            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 aec275e422efc1058803ce3c3defa130560693ed..b48f45c55736f31f52373ccc0af815e95e3b2960 100644 (file)
@@ -256,7 +256,6 @@ NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
 * @param header_len    The length of the packet header
 * @param data_left     The data left in the send buffer
 * @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
@@ -266,7 +265,7 @@ NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
 */
 NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
                            size_t header_len, size_t data_left,
-                           size_t max_xmit_frag, size_t pad_alignment,
+                           size_t max_xmit_frag,
                            size_t *data_to_send, size_t *frag_len,
                            size_t *auth_len, size_t *pad_len)
 {
@@ -309,7 +308,11 @@ NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
        case DCERPC_AUTH_TYPE_KRB5:
                gensec_security = talloc_get_type_abort(auth->auth_ctx,
                                                        struct gensec_security);
-               *auth_len = gensec_sig_size(gensec_security, max_len);
+               mod_len = (max_len % DCERPC_AUTH_PAD_ALIGNMENT);
+               *auth_len = gensec_sig_size(gensec_security, max_len - mod_len);
+               if (*auth_len == 0) {
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
                break;
 
        case DCERPC_AUTH_TYPE_SCHANNEL:
@@ -322,19 +325,12 @@ NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
        }
 
        max_len -= *auth_len;
+       mod_len = (max_len % DCERPC_AUTH_PAD_ALIGNMENT);
+       max_len -= mod_len;
 
        *data_to_send = MIN(max_len, data_left);
 
-       mod_len = (header_len + *data_to_send) % pad_alignment;
-       if (mod_len) {
-               *pad_len = pad_alignment - mod_len;
-       } else {
-               *pad_len = 0;
-       }
-
-       if (*data_to_send + *pad_len > max_len) {
-               *data_to_send -= pad_alignment;
-       }
+       *pad_len = DCERPC_AUTH_PAD_LENGTH(*data_to_send);
 
        *frag_len = header_len + *data_to_send + *pad_len
                        + DCERPC_AUTH_TRAILER_LENGTH + *auth_len;
index 385ae25289b47384549da66953e57dfe52a527f0..78b1c5c7a30b6a26a76a1aa4b0256f687c56a766 100644 (file)
@@ -1282,7 +1282,6 @@ static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
        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)) {
index 7daff04f2ac8329086ef4293ea07f8f2911df796..9df41b46d820d91e2ed123fc985d8e805ccfc285 100644 (file)
@@ -141,7 +141,6 @@ static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
                                    DCERPC_RESPONSE_LENGTH,
                                    data_left,
                                    RPC_MAX_PDU_FRAG_LEN,
-                                   SERVER_NDR_PADDING_SIZE,
                                    &data_to_send, &frag_len,
                                    &auth_len, &pad_len);
        if (!NT_STATUS_IS_OK(status)) {