Split out the client unix capabilities to those the server offered, and those the...
authorJeremy Allison <jra@samba.org>
Wed, 14 Apr 2010 01:41:14 +0000 (18:41 -0700)
committerJeremy Allison <jra@samba.org>
Wed, 14 Apr 2010 01:41:14 +0000 (18:41 -0700)
This fixes a bug when using encrypted transport and DFS links. Found
by my basic DFS torture test, which I'll check in next. Testing *rocks* :-).

Jeremy.

source3/client/client.c
source3/include/client.h
source3/libsmb/clidfs.c
source3/libsmb/clifsinfo.c
source3/libsmb/clireadwrite.c

index 7dc412fe3a92dcf8077559a6425b903537674d02..13617155c7f2aa803fc2303479e4c8e5d0a03d1d 100644 (file)
@@ -332,7 +332,7 @@ static int cmd_pwd(void)
 
 static void normalize_name(char *newdir)
 {
-       if (!(cli->posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP)) {
+       if (!(cli->requested_posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP)) {
                string_replace(newdir,'/','\\');
        }
 }
index 457c02a18fda9f4611f6a05ace5a157f402450f7..71232b35fa4806f11b61630611088aff8be85bf9 100644 (file)
@@ -248,7 +248,10 @@ struct cli_state {
        int win95;
        bool is_samba;
        uint32 capabilities;
-       uint32 posix_capabilities;
+       /* What the server offered. */
+       uint32_t server_posix_capabilities;
+       /* What the client requested. */
+       uint32_t requested_posix_capabilities;
        bool dfsroot;
 
 #if 0
index d5ae11ff8da7f606c3293094f1025630313eba48..345d0f92123b353fed8386eaba186224ce96780f 100644 (file)
@@ -320,7 +320,7 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
                DLIST_ADD_END(referring_cli, cli, struct cli_state *);
        }
 
-       if (referring_cli && referring_cli->posix_capabilities) {
+       if (referring_cli && referring_cli->requested_posix_capabilities) {
                uint16 major, minor;
                uint32 caplow, caphigh;
                NTSTATUS status;
@@ -564,7 +564,7 @@ static char *cli_dfs_make_full_path(TALLOC_CTX *ctx,
                dir++;
        }
 
-       if (cli->posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
+       if (cli->requested_posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
                path_sep = '/';
        }
        return talloc_asprintf(ctx, "%c%s%c%s%c%s",
index 3297ec76ca2342df8b410e02c5588f7ce698df6f..b8430a58702417b5dbc137f4ee0d9e0017b1b307 100644 (file)
@@ -27,6 +27,7 @@
 ****************************************************************************/
 
 struct cli_unix_extensions_version_state {
+       struct cli_state *cli;
        uint16_t setup[1];
        uint8_t param[2];
        uint16_t major, minor;
@@ -47,6 +48,7 @@ struct tevent_req *cli_unix_extensions_version_send(TALLOC_CTX *mem_ctx,
        if (req == NULL) {
                return NULL;
        }
+       state->cli = cli;
        SSVAL(state->setup, 0, TRANSACT2_QFSINFO);
        SSVAL(state->param, 0, SMB_QUERY_CIFS_UNIX_INFO);
 
@@ -104,6 +106,7 @@ NTSTATUS cli_unix_extensions_version_recv(struct tevent_req *req,
        *pminor = state->minor;
        *pcaplow = state->caplow;
        *pcaphigh = state->caphigh;
+       state->cli->server_posix_capabilities = *pcaplow;
        return NT_STATUS_OK;
 }
 
@@ -143,9 +146,6 @@ NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor,
 
        status = cli_unix_extensions_version_recv(req, pmajor, pminor, pcaplow,
                                                  pcaphigh);
-       if (NT_STATUS_IS_OK(status)) {
-               cli->posix_capabilities = *pcaplow;
-       }
  fail:
        TALLOC_FREE(frame);
        if (!NT_STATUS_IS_OK(status)) {
@@ -159,6 +159,7 @@ NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor,
 ****************************************************************************/
 
 struct cli_set_unix_extensions_capabilities_state {
+       struct cli_state *cli;
        uint16_t setup[1];
        uint8_t param[4];
        uint8_t data[12];
@@ -181,6 +182,7 @@ struct tevent_req *cli_set_unix_extensions_capabilities_send(
                return NULL;
        }
 
+       state->cli = cli;
        SSVAL(state->setup+0, 0, TRANSACT2_SETFSINFO);
 
        SSVAL(state->param, 0, 0);
@@ -207,8 +209,16 @@ struct tevent_req *cli_set_unix_extensions_capabilities_send(
 static void cli_set_unix_extensions_capabilities_done(
        struct tevent_req *subreq)
 {
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct cli_set_unix_extensions_capabilities_state *state = tevent_req_data(
+               req, struct cli_set_unix_extensions_capabilities_state);
+
        NTSTATUS status = cli_trans_recv(subreq, NULL, NULL, 0, NULL,
                                         NULL, 0, NULL, NULL, 0, NULL);
+       if (NT_STATUS_IS_OK(status)) {
+               state->cli->requested_posix_capabilities = IVAL(state->data, 4);
+       }
        tevent_req_simple_finish_ntstatus(subreq, status);
 }
 
@@ -245,6 +255,8 @@ fail:
        TALLOC_FREE(ev);
        if (!NT_STATUS_IS_OK(status)) {
                cli_set_error(cli, status);
+       } else {
+               cli->requested_posix_capabilities = caplow;
        }
        return status;
 }
index 7b688d4ff3328f03d4f7aed4ecf49e237af24003..e9a9e0ed3de9854e4a3292db24cb728d6348af06 100644 (file)
@@ -25,7 +25,7 @@
 static size_t cli_read_max_bufsize(struct cli_state *cli)
 {
        if (!client_is_signing_on(cli) && !cli_encryption_on(cli)
-           && (cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) {
+           && (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) {
                return CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE;
        }
        if (cli->capabilities & CAP_LARGE_READX) {
@@ -44,7 +44,7 @@ static size_t cli_write_max_bufsize(struct cli_state *cli, uint16_t write_mode)
         if (write_mode == 0 &&
            !client_is_signing_on(cli) &&
            !cli_encryption_on(cli) &&
-           (cli->posix_capabilities & CIFS_UNIX_LARGE_WRITE_CAP) &&
+           (cli->server_posix_capabilities & CIFS_UNIX_LARGE_WRITE_CAP) &&
            (cli->capabilities & CAP_LARGE_FILES)) {
                /* Only do massive writes if we can do them direct
                 * with no signing or encrypting - not on a pipe. */