s3-dcerpc: Make function to guess pdu sizes common.
authorSimo Sorce <idra@samba.org>
Fri, 30 Jul 2010 15:27:40 +0000 (11:27 -0400)
committerSimo Sorce <idra@samba.org>
Fri, 30 Jul 2010 18:55:27 +0000 (14:55 -0400)
source3/librpc/rpc/dcerpc.h
source3/librpc/rpc/dcerpc_helpers.c
source3/rpc_client/cli_pipe.c

index d170daad9fa0f661e41dc219c71dafafe00be0d6..fd80dbeb04acc288f3ca335177dabd142052f429 100644 (file)
@@ -139,6 +139,10 @@ NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
                                 const DATA_BLOB *blob,
                                 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 *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,
                                size_t pad_len, DATA_BLOB *rpc_out);
 NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
index 26b44de5ea2c3ce870d27432054e72430f3adae9..161154fe3b4e13553b21a683f1f2d6e1807fbab6 100644 (file)
@@ -241,6 +241,123 @@ NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK;
 }
 
+/**
+* @brief Calculate how much data we can in a packet, including calculating
+*       auth token and pad lengths.
+*
+* @param auth          The pipe_auth_data structure for this pipe.
+* @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
+*
+* @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 *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;
+       enum dcerpc_AuthType auth_type;
+       void *auth_ctx;
+       bool seal = false;
+       NTSTATUS status;
+
+       /* no auth token cases first */
+       switch (auth->auth_level) {
+       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);
+               *pad_len = 0;
+               *auth_len = 0;
+               *frag_len = DCERPC_REQUEST_LENGTH + *data_to_send;
+               return NT_STATUS_OK;
+
+       case DCERPC_AUTH_LEVEL_PRIVACY:
+               seal = true;
+               break;
+
+       case DCERPC_AUTH_LEVEL_INTEGRITY:
+               break;
+
+       default:
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+
+       /* Sign/seal case, calculate auth and pad lengths */
+
+       max_len = max_xmit_frag
+                       - DCERPC_REQUEST_LENGTH
+                       - DCERPC_AUTH_TRAILER_LENGTH;
+
+       /* Treat the same for all authenticated rpc requests. */
+       switch (auth->auth_type) {
+       case DCERPC_AUTH_TYPE_SPNEGO:
+               status = spnego_get_negotiated_mech(auth->a_u.spnego_state,
+                                                   &auth_type, &auth_ctx);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+               switch (auth_type) {
+               case DCERPC_AUTH_TYPE_NTLMSSP:
+                       *auth_len = NTLMSSP_SIG_SIZE;
+                       break;
+
+               case DCERPC_AUTH_TYPE_KRB5:
+                       gse_ctx = talloc_get_type(auth_ctx,
+                                                 struct gse_context);
+                       if (!gse_ctx) {
+                               return NT_STATUS_INVALID_PARAMETER;
+                       }
+                       *auth_len = gse_get_signature_length(gse_ctx,
+                                                            seal, max_len);
+                       break;
+
+               default:
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+               break;
+
+       case DCERPC_AUTH_TYPE_NTLMSSP:
+               *auth_len = NTLMSSP_SIG_SIZE;
+               break;
+
+       case DCERPC_AUTH_TYPE_SCHANNEL:
+               *auth_len = NL_AUTH_SIGNATURE_SIZE;
+               break;
+
+       case DCERPC_AUTH_TYPE_KRB5:
+               *auth_len = gse_get_signature_length(auth->a_u.gssapi_state,
+                                                    seal, max_len);
+               break;
+
+       default:
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       data_space = max_len - *auth_len;
+
+       *data_to_send = MIN(data_space, data_left);
+       mod_len = *data_to_send % CLIENT_NDR_PADDING_SIZE;
+       if (mod_len) {
+               *pad_len = CLIENT_NDR_PADDING_SIZE - mod_len;
+       } else {
+               *pad_len = 0;
+       }
+       *frag_len = DCERPC_REQUEST_LENGTH + *data_to_send + *pad_len
+                               + DCERPC_AUTH_TRAILER_LENGTH + *auth_len;
+
+       return NT_STATUS_OK;
+}
+
 /*******************************************************************
  Create and add the NTLMSSP sign/seal auth data.
  ********************************************************************/
index 02e4ec6ae249368d90ea173925f2818d0b902f05..99e856dfd826afc572e8491f0a60a7fa36dfebad 100644 (file)
@@ -1184,109 +1184,6 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
        return ret;
 }
 
-/*******************************************************************
- Calculate how much data we're going to send in this packet, also
- work out any sign/seal padding length.
- ********************************************************************/
-
-static NTSTATUS calculate_data_len_tosend(struct rpc_pipe_client *cli,
-                                         uint32_t data_left,
-                                         uint32_t *data_to_send,
-                                         uint16_t *p_frag_len,
-                                         uint16_t *p_auth_len,
-                                         uint32_t *p_ss_padding)
-{
-       uint32_t data_space, data_len;
-       size_t max_len;
-       struct gse_context *gse_ctx;
-       enum dcerpc_AuthType auth_type;
-       void *auth_ctx;
-       NTSTATUS status;
-
-       switch (cli->auth->auth_level) {
-       case DCERPC_AUTH_LEVEL_NONE:
-       case DCERPC_AUTH_LEVEL_CONNECT:
-       case DCERPC_AUTH_LEVEL_PACKET:
-               data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH;
-               data_len = MIN(data_space, data_left);
-               *p_ss_padding = 0;
-               *p_auth_len = 0;
-               *p_frag_len = DCERPC_REQUEST_LENGTH + data_len;
-               *data_to_send = data_len;
-               return NT_STATUS_OK;
-
-       case DCERPC_AUTH_LEVEL_INTEGRITY:
-       case DCERPC_AUTH_LEVEL_PRIVACY:
-               max_len = cli->max_xmit_frag
-                               - DCERPC_REQUEST_LENGTH
-                               - DCERPC_AUTH_TRAILER_LENGTH;
-
-               /* Treat the same for all authenticated rpc requests. */
-               switch(cli->auth->auth_type) {
-               case DCERPC_AUTH_TYPE_SPNEGO:
-                       status = spnego_get_negotiated_mech(
-                                       cli->auth->a_u.spnego_state,
-                                       &auth_type, &auth_ctx);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               return status;
-                       }
-                       switch (auth_type) {
-                       case DCERPC_AUTH_TYPE_NTLMSSP:
-                               *p_auth_len = NTLMSSP_SIG_SIZE;
-                               break;
-                       case DCERPC_AUTH_TYPE_KRB5:
-                               gse_ctx = talloc_get_type(auth_ctx,
-                                                         struct gse_context);
-                               if (!gse_ctx) {
-                                       return NT_STATUS_INVALID_PARAMETER;
-                               }
-                               *p_auth_len = gse_get_signature_length(gse_ctx,
-                                               (cli->auth->auth_level ==
-                                                 DCERPC_AUTH_LEVEL_PRIVACY),
-                                               max_len);
-                               break;
-                       default:
-                               return NT_STATUS_INVALID_PARAMETER;
-                       }
-                       break;
-               case DCERPC_AUTH_TYPE_NTLMSSP:
-                       *p_auth_len = NTLMSSP_SIG_SIZE;
-                       break;
-               case DCERPC_AUTH_TYPE_SCHANNEL:
-                       *p_auth_len = NL_AUTH_SIGNATURE_SIZE;
-                       break;
-               case DCERPC_AUTH_TYPE_KRB5:
-                       *p_auth_len = gse_get_signature_length(
-                                       cli->auth->a_u.gssapi_state,
-                                       (cli->auth->auth_level ==
-                                               DCERPC_AUTH_LEVEL_PRIVACY),
-                                       max_len);
-                       break;
-               default:
-                       return NT_STATUS_INVALID_PARAMETER;
-               }
-
-               data_space = max_len - *p_auth_len;
-
-               data_len = MIN(data_space, data_left);
-               *p_ss_padding = 0;
-               if (data_len % CLIENT_NDR_PADDING_SIZE) {
-                       *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
-               }
-               *p_frag_len = DCERPC_REQUEST_LENGTH
-                               + data_len + *p_ss_padding
-                               + DCERPC_AUTH_TRAILER_LENGTH
-                               + *p_auth_len;
-               *data_to_send = data_len;
-               return NT_STATUS_OK;
-
-       default:
-               break;
-       }
-
-       return NT_STATUS_INVALID_PARAMETER;
-}
-
 /*******************************************************************
  External interface.
  Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
@@ -1378,21 +1275,21 @@ struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
                                  bool *is_last_frag)
 {
-       uint32_t data_sent_thistime;
-       uint16_t auth_len;
-       uint16_t frag_len;
+       size_t data_sent_thistime;
+       size_t auth_len;
+       size_t frag_len;
        uint8_t flags = 0;
-       uint32_t pad_len;
-       uint32_t data_left;
+       size_t pad_len;
+       size_t data_left;
        NTSTATUS status;
        union dcerpc_payload u;
 
        data_left = state->req_data->length - state->req_data_sent;
 
-       status = calculate_data_len_tosend(state->cli, data_left,
-                                          &data_sent_thistime,
-                                          &frag_len, &auth_len,
-                                          &pad_len);
+       status = dcerpc_guess_sizes(state->cli->auth, data_left,
+                                   state->cli->max_xmit_frag,
+                                   &data_sent_thistime,
+                                   &frag_len, &auth_len, &pad_len);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }