mirror of
https://github.com/samba-team/samba.git
synced 2025-08-02 00:22:11 +03:00
Split out the client unix capabilities to those the server offered, and those the client asked for.
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.
This commit is contained in:
@ -332,7 +332,7 @@ static int cmd_pwd(void)
|
|||||||
|
|
||||||
static void normalize_name(char *newdir)
|
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,'/','\\');
|
string_replace(newdir,'/','\\');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,10 @@ struct cli_state {
|
|||||||
int win95;
|
int win95;
|
||||||
bool is_samba;
|
bool is_samba;
|
||||||
uint32 capabilities;
|
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;
|
bool dfsroot;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -320,7 +320,7 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
|
|||||||
DLIST_ADD_END(referring_cli, cli, struct cli_state *);
|
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;
|
uint16 major, minor;
|
||||||
uint32 caplow, caphigh;
|
uint32 caplow, caphigh;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
@ -564,7 +564,7 @@ static char *cli_dfs_make_full_path(TALLOC_CTX *ctx,
|
|||||||
dir++;
|
dir++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cli->posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
|
if (cli->requested_posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
|
||||||
path_sep = '/';
|
path_sep = '/';
|
||||||
}
|
}
|
||||||
return talloc_asprintf(ctx, "%c%s%c%s%c%s",
|
return talloc_asprintf(ctx, "%c%s%c%s%c%s",
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
struct cli_unix_extensions_version_state {
|
struct cli_unix_extensions_version_state {
|
||||||
|
struct cli_state *cli;
|
||||||
uint16_t setup[1];
|
uint16_t setup[1];
|
||||||
uint8_t param[2];
|
uint8_t param[2];
|
||||||
uint16_t major, minor;
|
uint16_t major, minor;
|
||||||
@ -47,6 +48,7 @@ struct tevent_req *cli_unix_extensions_version_send(TALLOC_CTX *mem_ctx,
|
|||||||
if (req == NULL) {
|
if (req == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
state->cli = cli;
|
||||||
SSVAL(state->setup, 0, TRANSACT2_QFSINFO);
|
SSVAL(state->setup, 0, TRANSACT2_QFSINFO);
|
||||||
SSVAL(state->param, 0, SMB_QUERY_CIFS_UNIX_INFO);
|
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;
|
*pminor = state->minor;
|
||||||
*pcaplow = state->caplow;
|
*pcaplow = state->caplow;
|
||||||
*pcaphigh = state->caphigh;
|
*pcaphigh = state->caphigh;
|
||||||
|
state->cli->server_posix_capabilities = *pcaplow;
|
||||||
return NT_STATUS_OK;
|
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,
|
status = cli_unix_extensions_version_recv(req, pmajor, pminor, pcaplow,
|
||||||
pcaphigh);
|
pcaphigh);
|
||||||
if (NT_STATUS_IS_OK(status)) {
|
|
||||||
cli->posix_capabilities = *pcaplow;
|
|
||||||
}
|
|
||||||
fail:
|
fail:
|
||||||
TALLOC_FREE(frame);
|
TALLOC_FREE(frame);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
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_set_unix_extensions_capabilities_state {
|
||||||
|
struct cli_state *cli;
|
||||||
uint16_t setup[1];
|
uint16_t setup[1];
|
||||||
uint8_t param[4];
|
uint8_t param[4];
|
||||||
uint8_t data[12];
|
uint8_t data[12];
|
||||||
@ -181,6 +182,7 @@ struct tevent_req *cli_set_unix_extensions_capabilities_send(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state->cli = cli;
|
||||||
SSVAL(state->setup+0, 0, TRANSACT2_SETFSINFO);
|
SSVAL(state->setup+0, 0, TRANSACT2_SETFSINFO);
|
||||||
|
|
||||||
SSVAL(state->param, 0, 0);
|
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(
|
static void cli_set_unix_extensions_capabilities_done(
|
||||||
struct tevent_req *subreq)
|
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,
|
NTSTATUS status = cli_trans_recv(subreq, NULL, NULL, 0, NULL,
|
||||||
NULL, 0, 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);
|
tevent_req_simple_finish_ntstatus(subreq, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,6 +255,8 @@ fail:
|
|||||||
TALLOC_FREE(ev);
|
TALLOC_FREE(ev);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
cli_set_error(cli, status);
|
cli_set_error(cli, status);
|
||||||
|
} else {
|
||||||
|
cli->requested_posix_capabilities = caplow;
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
static size_t cli_read_max_bufsize(struct cli_state *cli)
|
static size_t cli_read_max_bufsize(struct cli_state *cli)
|
||||||
{
|
{
|
||||||
if (!client_is_signing_on(cli) && !cli_encryption_on(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;
|
return CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE;
|
||||||
}
|
}
|
||||||
if (cli->capabilities & CAP_LARGE_READX) {
|
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 &&
|
if (write_mode == 0 &&
|
||||||
!client_is_signing_on(cli) &&
|
!client_is_signing_on(cli) &&
|
||||||
!cli_encryption_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)) {
|
(cli->capabilities & CAP_LARGE_FILES)) {
|
||||||
/* Only do massive writes if we can do them direct
|
/* Only do massive writes if we can do them direct
|
||||||
* with no signing or encrypting - not on a pipe. */
|
* with no signing or encrypting - not on a pipe. */
|
||||||
|
Reference in New Issue
Block a user