s3:libsmb/clireadwrite: calculate cli_write_max_bufsize() correct based on max_xmit
authorStefan Metzmacher <metze@samba.org>
Wed, 8 Jun 2011 17:01:13 +0000 (19:01 +0200)
committerJeremy Allison <jra@samba.org>
Fri, 10 Jun 2011 17:27:05 +0000 (19:27 +0200)
This is important in order to support DCERPC over ncacn_np against NT4 servers,
where max_xmit is just 4356.

metze

source3/libsmb/clireadwrite.c

index e8baeba588cd08ffce02e94d84fe5c45a25521d9..14b6401051e63624120f4c065755f29c02a951bd 100644 (file)
@@ -54,7 +54,9 @@ static size_t cli_read_max_bufsize(struct cli_state *cli)
 /****************************************************************************
   Calculate the recommended write buffer size
 ****************************************************************************/
-static size_t cli_write_max_bufsize(struct cli_state *cli, uint16_t write_mode)
+static size_t cli_write_max_bufsize(struct cli_state *cli,
+                                   uint16_t write_mode,
+                                   uint8_t wct)
 {
         if (write_mode == 0 &&
            !client_is_signing_on(cli) &&
@@ -73,13 +75,15 @@ static size_t cli_write_max_bufsize(struct cli_state *cli, uint16_t write_mode)
        if (((cli->capabilities & CAP_LARGE_WRITEX) == 0)
            || client_is_signing_on(cli)
            || strequal(cli->dev, "LPT1:")) {
+               size_t data_offset = smb_size - 4;
+               size_t useable_space;
 
-               /*
-                * Printer devices are restricted to max_xmit writesize in
-                * Vista and XPSP3 as are signing connections.
-                */
+               data_offset += wct * sizeof(uint16_t);
+               data_offset += 1; /* pad */
+
+               useable_space = cli->max_xmit - data_offset;
 
-               return (cli->max_xmit - (smb_size+32)) & ~1023;
+               return useable_space;
        }
 
        return CLI_WINDOWS_MAX_LARGE_WRITEX_SIZE;
@@ -795,7 +799,7 @@ struct tevent_req *cli_write_andx_create(TALLOC_CTX *mem_ctx,
        struct cli_write_andx_state *state;
        bool bigoffset = ((cli->capabilities & CAP_LARGE_FILES) != 0);
        uint8_t wct = bigoffset ? 14 : 12;
-       size_t max_write = cli_write_max_bufsize(cli, mode);
+       size_t max_write = cli_write_max_bufsize(cli, mode, wct);
        uint16_t *vwv;
 
        req = tevent_req_create(mem_ctx, &state, struct cli_write_andx_state);
@@ -1148,7 +1152,7 @@ struct tevent_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
        state->pending = 0;
        state->next_offset = start_offset;
 
-       state->chunk_size = cli_write_max_bufsize(cli, mode);
+       state->chunk_size = cli_write_max_bufsize(cli, mode, 14);
 
        if (window_size == 0) {
                window_size = cli->max_mux * state->chunk_size;