summaryrefslogtreecommitdiffstats
path: root/source3/libsmb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/async_smb.c133
-rw-r--r--source3/libsmb/cliconnect.c168
-rw-r--r--source3/libsmb/clidfs.c7
-rw-r--r--source3/libsmb/clientgen.c2
-rw-r--r--source3/libsmb/clifile.c4
-rw-r--r--source3/libsmb/clireadwrite.c63
-rw-r--r--source3/libsmb/clitrans.c6
-rw-r--r--source3/libsmb/libsmb_server.c4
-rw-r--r--source3/libsmb/libsmb_xattr.c3
-rw-r--r--source3/libsmb/nmblib.c8
-rw-r--r--source3/libsmb/passchange.c6
11 files changed, 246 insertions, 158 deletions
diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c
index fd2fe930f84..fdcbb002061 100644
--- a/source3/libsmb/async_smb.c
+++ b/source3/libsmb/async_smb.c
@@ -127,7 +127,7 @@ static char *cli_request_print(TALLOC_CTX *mem_ctx, struct async_req *req)
static int cli_request_destructor(struct cli_request *req)
{
if (req->enc_state != NULL) {
- common_free_enc_buffer(req->enc_state, req->outbuf);
+ common_free_enc_buffer(req->enc_state, (char *)req->outbuf);
}
DLIST_REMOVE(req->cli->outstanding_requests, req);
if (req->cli->outstanding_requests == NULL) {
@@ -187,7 +187,7 @@ static bool is_andx_req(uint8_t cmd)
* to the chain. Find the offset to the place where we have to put our cmd.
*/
-static bool find_andx_cmd_ofs(char *buf, size_t *pofs)
+static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
{
uint8_t cmd;
size_t ofs;
@@ -231,12 +231,12 @@ static bool find_andx_cmd_ofs(char *buf, size_t *pofs)
* *poutbuf.
*/
-bool smb_splice_chain(char **poutbuf, uint8_t smb_command,
+bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
uint8_t wct, const uint16_t *vwv,
size_t bytes_alignment,
- uint16_t num_bytes, const uint8_t *bytes)
+ uint32_t num_bytes, const uint8_t *bytes)
{
- char *outbuf;
+ uint8_t *outbuf;
size_t old_size, new_size;
size_t ofs;
size_t chain_padding = 0;
@@ -269,18 +269,18 @@ bool smb_splice_chain(char **poutbuf, uint8_t smb_command,
new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
- bytes_padding = bytes_alignment + (new_size % bytes_alignment);
+ bytes_padding = bytes_alignment - (new_size % bytes_alignment);
}
new_size += bytes_padding + num_bytes;
- if (new_size > 0xffff) {
+ if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
DEBUG(1, ("splice_chain: %u bytes won't fit\n",
(unsigned)new_size));
return false;
}
- outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, char, new_size);
+ outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
if (outbuf == NULL) {
DEBUG(0, ("talloc failed\n"));
return false;
@@ -295,7 +295,7 @@ bool smb_splice_chain(char **poutbuf, uint8_t smb_command,
if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
DEBUG(1, ("invalid command chain\n"));
*poutbuf = TALLOC_REALLOC_ARRAY(
- NULL, *poutbuf, char, old_size);
+ NULL, *poutbuf, uint8_t, old_size);
return false;
}
@@ -310,20 +310,42 @@ bool smb_splice_chain(char **poutbuf, uint8_t smb_command,
ofs = old_size;
+ /*
+ * Push the chained request:
+ *
+ * wct field
+ */
+
SCVAL(outbuf, ofs, wct);
ofs += 1;
+ /*
+ * vwv array
+ */
+
memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
ofs += sizeof(uint16_t) * wct;
+ /*
+ * bcc (byte count)
+ */
+
SSVAL(outbuf, ofs, num_bytes + bytes_padding);
ofs += sizeof(uint16_t);
+ /*
+ * padding
+ */
+
if (bytes_padding != 0) {
memset(outbuf + ofs, 0, bytes_padding);
ofs += bytes_padding;
}
+ /*
+ * The bytes field
+ */
+
memcpy(outbuf + ofs, bytes, num_bytes);
return true;
@@ -379,6 +401,7 @@ static int cli_async_req_destructor(struct async_req *req)
* @param[in] additional_flags open_and_x wants to add oplock header flags
* @param[in] wct How many words?
* @param[in] vwv The words, already in network order
+ * @param[in] bytes_alignment How shall we align "bytes"?
* @param[in] num_bytes How many bytes?
* @param[in] bytes The data the request ships
*
@@ -394,7 +417,8 @@ static struct async_req *cli_request_chain(TALLOC_CTX *mem_ctx,
uint8_t smb_command,
uint8_t additional_flags,
uint8_t wct, const uint16_t *vwv,
- uint16_t num_bytes,
+ size_t bytes_alignment,
+ uint32_t num_bytes,
const uint8_t *bytes)
{
struct async_req **tmp_reqs;
@@ -423,7 +447,7 @@ static struct async_req *cli_request_chain(TALLOC_CTX *mem_ctx,
cli_async_req_destructor);
if (!smb_splice_chain(&req->outbuf, smb_command, wct, vwv,
- 0, num_bytes, bytes)) {
+ bytes_alignment, num_bytes, bytes)) {
goto fail;
}
@@ -489,11 +513,12 @@ bool cli_chain_cork(struct cli_state *cli, struct event_context *ev,
if (size_hint == 0) {
size_hint = 100;
}
- req->outbuf = talloc_array(req, char, smb_wct + size_hint);
+ req->outbuf = talloc_array(req, uint8_t, smb_wct + size_hint);
if (req->outbuf == NULL) {
goto fail;
}
- req->outbuf = TALLOC_REALLOC_ARRAY(NULL, req->outbuf, char, smb_wct);
+ req->outbuf = TALLOC_REALLOC_ARRAY(NULL, req->outbuf, uint8_t,
+ smb_wct);
req->num_async = 0;
req->async = NULL;
@@ -502,7 +527,7 @@ bool cli_chain_cork(struct cli_state *cli, struct event_context *ev,
req->recv_helper.fn = NULL;
SSVAL(req->outbuf, smb_tid, cli->cnum);
- cli_setup_packet_buf(cli, req->outbuf);
+ cli_setup_packet_buf(cli, (char *)req->outbuf);
req->mid = cli_new_mid(cli);
@@ -536,22 +561,23 @@ void cli_chain_uncork(struct cli_state *cli)
cli->chain_accumulator = NULL;
SSVAL(req->outbuf, smb_mid, req->mid);
- smb_setlen(req->outbuf, talloc_get_size(req->outbuf) - 4);
+ smb_setlen((char *)req->outbuf, talloc_get_size(req->outbuf) - 4);
- cli_calculate_sign_mac(cli, req->outbuf);
+ cli_calculate_sign_mac(cli, (char *)req->outbuf);
if (cli_encryption_on(cli)) {
NTSTATUS status;
char *enc_buf;
- status = cli_encrypt_message(cli, req->outbuf, &enc_buf);
+ status = cli_encrypt_message(cli, (char *)req->outbuf,
+ &enc_buf);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("Error in encrypting client message. "
"Error %s\n", nt_errstr(status)));
TALLOC_FREE(req);
return;
}
- req->outbuf = enc_buf;
+ req->outbuf = (uint8_t *)enc_buf;
req->enc_state = cli->trans_enc_state;
}
@@ -569,6 +595,7 @@ void cli_chain_uncork(struct cli_state *cli)
* @param[in] additional_flags open_and_x wants to add oplock header flags
* @param[in] wct How many words?
* @param[in] vwv The words, already in network order
+ * @param[in] bytes_alignment How shall we align "bytes"?
* @param[in] num_bytes How many bytes?
* @param[in] bytes The data the request ships
*
@@ -581,7 +608,8 @@ struct async_req *cli_request_send(TALLOC_CTX *mem_ctx,
uint8_t smb_command,
uint8_t additional_flags,
uint8_t wct, const uint16_t *vwv,
- uint16_t num_bytes, const uint8_t *bytes)
+ size_t bytes_alignment,
+ uint32_t num_bytes, const uint8_t *bytes)
{
struct async_req *result;
bool uncork = false;
@@ -596,7 +624,7 @@ struct async_req *cli_request_send(TALLOC_CTX *mem_ctx,
}
result = cli_request_chain(mem_ctx, ev, cli, smb_command,
- additional_flags, wct, vwv,
+ additional_flags, wct, vwv, bytes_alignment,
num_bytes, bytes);
if (result == NULL) {
@@ -955,6 +983,39 @@ static void cli_state_handler(struct event_context *event_ctx,
DEBUG(11, ("cli_state_handler called with flags %d\n", flags));
+ if (flags & EVENT_FD_WRITE) {
+ size_t to_send;
+ ssize_t sent;
+
+ for (req = cli->outstanding_requests; req; req = req->next) {
+ to_send = smb_len(req->outbuf)+4;
+ if (to_send > req->sent) {
+ break;
+ }
+ }
+
+ if (req == NULL) {
+ if (cli->fd_event != NULL) {
+ event_fd_set_not_writeable(cli->fd_event);
+ }
+ return;
+ }
+
+ sent = sys_send(cli->fd, req->outbuf + req->sent,
+ to_send - req->sent, 0);
+
+ if (sent < 0) {
+ status = map_nt_error_from_unix(errno);
+ goto sock_error;
+ }
+
+ req->sent += sent;
+
+ if (req->sent == to_send) {
+ return;
+ }
+ }
+
if (flags & EVENT_FD_READ) {
int res, available;
size_t old_size, new_size;
@@ -1020,38 +1081,6 @@ static void cli_state_handler(struct event_context *event_ctx,
}
}
- if (flags & EVENT_FD_WRITE) {
- size_t to_send;
- ssize_t sent;
-
- for (req = cli->outstanding_requests; req; req = req->next) {
- to_send = smb_len(req->outbuf)+4;
- if (to_send > req->sent) {
- break;
- }
- }
-
- if (req == NULL) {
- if (cli->fd_event != NULL) {
- event_fd_set_not_writeable(cli->fd_event);
- }
- return;
- }
-
- sent = sys_send(cli->fd, req->outbuf + req->sent,
- to_send - req->sent, 0);
-
- if (sent < 0) {
- status = map_nt_error_from_unix(errno);
- goto sock_error;
- }
-
- req->sent += sent;
-
- if (req->sent == to_send) {
- return;
- }
- }
return;
sock_error:
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 125345fccbb..5892bdc8592 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -1206,7 +1206,7 @@ bool cli_tdis(struct cli_state *cli)
Send a negprot command.
****************************************************************************/
-void cli_negprot_send(struct cli_state *cli)
+void cli_negprot_sendsync(struct cli_state *cli)
{
char *p;
int numprots;
@@ -1241,75 +1241,89 @@ void cli_negprot_send(struct cli_state *cli)
Send a negprot command.
****************************************************************************/
-bool cli_negprot(struct cli_state *cli)
+struct async_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli)
{
- char *p;
+ struct async_req *result;
+ uint8_t *bytes = NULL;
int numprots;
- int plength;
if (cli->protocol < PROTOCOL_NT1)
cli->use_spnego = False;
- memset(cli->outbuf,'\0',smb_size);
-
- plength = 0;
-
/* setup the protocol strings */
for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
+ uint8_t c = 2;
if (prots[numprots].prot > cli->protocol) {
break;
}
- plength += strlen(prots[numprots].name)+2;
- }
-
- cli_set_message(cli->outbuf,0,plength,True);
-
- p = smb_buf(cli->outbuf);
- for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
- if (prots[numprots].prot > cli->protocol) {
- break;
+ bytes = (uint8_t *)talloc_append_blob(
+ talloc_tos(), bytes, data_blob_const(&c, sizeof(c)));
+ if (bytes == NULL) {
+ return NULL;
+ }
+ bytes = smb_bytes_push_str(bytes, false, prots[numprots].name);
+ if (bytes == NULL) {
+ return NULL;
}
- *p++ = 2;
- p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
}
- SCVAL(cli->outbuf,smb_com,SMBnegprot);
- cli_setup_packet(cli);
+ result = cli_request_send(mem_ctx, ev, cli, SMBnegprot, 0, 0, NULL, 0,
+ talloc_get_size(bytes), bytes);
+ TALLOC_FREE(bytes);
+ return result;
+}
- SCVAL(smb_buf(cli->outbuf),0,2);
+NTSTATUS cli_negprot_recv(struct async_req *req)
+{
+ struct cli_request *cli_req = talloc_get_type_abort(
+ req->private_data, struct cli_request);
+ struct cli_state *cli = cli_req->cli;
+ uint8_t wct;
+ uint16_t *vwv;
+ uint16_t num_bytes;
+ uint8_t *bytes;
+ NTSTATUS status;
+ uint16_t protnum;
- cli_send_smb(cli);
- if (!cli_receive_smb(cli))
- return False;
+ if (async_req_is_error(req, &status)) {
+ return status;
+ }
- show_msg(cli->inbuf);
+ status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ protnum = SVAL(vwv, 0);
- if (cli_is_error(cli) ||
- ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) {
- return(False);
+ if ((protnum >= ARRAY_SIZE(prots))
+ || (prots[protnum].prot > cli_req->cli->protocol)) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
- cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot;
+ cli->protocol = prots[protnum].prot;
if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) {
DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
- return False;
+ return NT_STATUS_ACCESS_DENIED;
}
if (cli->protocol >= PROTOCOL_NT1) {
struct timespec ts;
/* NT protocol */
- cli->sec_mode = CVAL(cli->inbuf,smb_vwv1);
- cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1);
- cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1);
- cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1);
- cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1);
+ cli->sec_mode = CVAL(vwv + 1, 0);
+ cli->max_mux = SVAL(vwv + 1, 1);
+ cli->max_xmit = IVAL(vwv + 3, 1);
+ cli->sesskey = IVAL(vwv + 7, 1);
+ cli->serverzone = SVALS(vwv + 15, 1);
cli->serverzone *= 60;
/* this time arrives in real GMT */
- ts = interpret_long_date(cli->inbuf+smb_vwv11+1);
+ ts = interpret_long_date(((char *)(vwv+11))+1);
cli->servertime = ts.tv_sec;
- cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf));
- cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1);
+ cli->secblob = data_blob(bytes, num_bytes);
+ cli->capabilities = IVAL(vwv + 9, 1);
if (cli->capabilities & CAP_RAW_MODE) {
cli->readbraw_supported = True;
cli->writebraw_supported = True;
@@ -1317,9 +1331,10 @@ bool cli_negprot(struct cli_state *cli)
/* work out if they sent us a workgroup */
if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
smb_buflen(cli->inbuf) > 8) {
- clistr_pull(cli, cli->server_domain,
- smb_buf(cli->inbuf)+8, sizeof(cli->server_domain),
- smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN);
+ clistr_pull(cli, cli->server_domain,
+ bytes+8, sizeof(cli->server_domain),
+ num_bytes-8,
+ STR_UNICODE|STR_NOALIGN);
}
/*
@@ -1331,7 +1346,7 @@ bool cli_negprot(struct cli_state *cli)
/* Fail if server says signing is mandatory and we don't want to support it. */
if (!cli->sign_info.allow_smb_signing) {
DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
- return False;
+ return NT_STATUS_ACCESS_DENIED;
}
cli->sign_info.negotiated_smb_signing = True;
cli->sign_info.mandatory_signing = True;
@@ -1339,7 +1354,7 @@ bool cli_negprot(struct cli_state *cli)
/* Fail if client says signing is mandatory and the server doesn't support it. */
if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
- return False;
+ return NT_STATUS_ACCESS_DENIED;
}
cli->sign_info.negotiated_smb_signing = True;
cli->sign_info.mandatory_signing = True;
@@ -1357,17 +1372,18 @@ bool cli_negprot(struct cli_state *cli)
} else if (cli->protocol >= PROTOCOL_LANMAN1) {
cli->use_spnego = False;
- cli->sec_mode = SVAL(cli->inbuf,smb_vwv1);
- cli->max_xmit = SVAL(cli->inbuf,smb_vwv2);
- cli->max_mux = SVAL(cli->inbuf, smb_vwv3);
- cli->sesskey = IVAL(cli->inbuf,smb_vwv6);
- cli->serverzone = SVALS(cli->inbuf,smb_vwv10);
+ cli->sec_mode = SVAL(vwv + 1, 0);
+ cli->max_xmit = SVAL(vwv + 2, 0);
+ cli->max_mux = SVAL(vwv + 3, 0);
+ cli->sesskey = IVAL(vwv + 6, 0);
+ cli->serverzone = SVALS(vwv + 10, 0);
cli->serverzone *= 60;
/* this time is converted to GMT by make_unix_date */
- cli->servertime = cli_make_unix_date(cli,cli->inbuf+smb_vwv8);
- cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0);
- cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0);
- cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf));
+ cli->servertime = cli_make_unix_date(
+ cli, (char *)(vwv + 8));
+ cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
+ cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
+ cli->secblob = data_blob(bytes, num_bytes);
} else {
/* the old core protocol */
cli->use_spnego = False;
@@ -1381,7 +1397,42 @@ bool cli_negprot(struct cli_state *cli)
if (getenv("CLI_FORCE_ASCII"))
cli->capabilities &= ~CAP_UNICODE;
- return True;
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_negprot(struct cli_state *cli)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct async_req *req;
+ NTSTATUS status = NT_STATUS_NO_MEMORY;
+
+ if (cli->fd_event != NULL) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ cli_set_error(cli, NT_STATUS_INVALID_PARAMETER);
+ goto fail;
+ }
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ goto fail;
+ }
+
+ req = cli_negprot_send(frame, ev, cli);
+ if (req == NULL) {
+ goto fail;
+ }
+
+ while (req->state < ASYNC_REQ_DONE) {
+ event_loop_once(ev);
+ }
+
+ status = cli_negprot_recv(req);
+ fail:
+ TALLOC_FREE(frame);
+ return status;
}
/****************************************************************************
@@ -1667,12 +1718,9 @@ again:
cli->fallback_after_kerberos = true;
}
- if (!cli_negprot(cli)) {
- DEBUG(1,("failed negprot\n"));
- nt_status = cli_nt_error(cli);
- if (NT_STATUS_IS_OK(nt_status)) {
- nt_status = NT_STATUS_UNSUCCESSFUL;
- }
+ nt_status = cli_negprot(cli);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
cli_shutdown(cli);
return nt_status;
}
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index f0ac39fed05..4597e63c98f 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -195,8 +195,11 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
DEBUG(4,(" session request ok\n"));
- if (!cli_negprot(c)) {
- d_printf("protocol negotiation failed\n");
+ status = cli_negprot(c);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("protocol negotiation failed: %s\n",
+ nt_errstr(status));
cli_shutdown(c);
return NULL;
}
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index d94427809ce..ff01b6798f9 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -705,7 +705,7 @@ struct async_req *cli_echo_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
return NULL;
}
- result = cli_request_send(mem_ctx, ev, cli, SMBecho, 0, 1, vwv,
+ result = cli_request_send(mem_ctx, ev, cli, SMBecho, 0, 1, vwv, 0,
data.length, data.data);
if (result == NULL) {
TALLOC_FREE(data_copy);
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 733abb6510c..7c758264141 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -895,7 +895,7 @@ struct async_req *cli_open_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
}
result = cli_request_send(mem_ctx, ev, cli, SMBopenX, additional_flags,
- 15, vwv, talloc_get_size(bytes), bytes);
+ 15, vwv, 0, talloc_get_size(bytes), bytes);
TALLOC_FREE(bytes);
return result;
}
@@ -974,7 +974,7 @@ struct async_req *cli_close_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
SSVAL(vwv+0, 0, fnum);
SIVALS(vwv+1, 0, -1);
- return cli_request_send(mem_ctx, ev, cli, SMBclose, 0, 3, vwv,
+ return cli_request_send(mem_ctx, ev, cli, SMBclose, 0, 3, vwv, 0,
0, NULL);
}
diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c
index 1c2a0d56c4c..0c655057932 100644
--- a/source3/libsmb/clireadwrite.c
+++ b/source3/libsmb/clireadwrite.c
@@ -36,6 +36,41 @@ static size_t cli_read_max_bufsize(struct cli_state *cli)
return (cli->max_xmit - (smb_size+32)) & ~1023;
}
+/****************************************************************************
+ Calculate the recommended write buffer size
+****************************************************************************/
+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->capabilities & CAP_LARGE_FILES)) {
+ /* Only do massive writes if we can do them direct
+ * with no signing or encrypting - not on a pipe. */
+ return CLI_SAMBA_MAX_POSIX_LARGE_WRITEX_SIZE;
+ }
+
+ if (cli->is_samba) {
+ return CLI_SAMBA_MAX_LARGE_WRITEX_SIZE;
+ }
+
+ if (((cli->capabilities & CAP_LARGE_WRITEX) == 0)
+ || client_is_signing_on(cli)
+ || strequal(cli->dev, "LPT1:")) {
+
+ /*
+ * Printer devices are restricted to max_xmit writesize in
+ * Vista and XPSP3 as are signing connections.
+ */
+
+ return (cli->max_xmit - (smb_size+32)) & ~1023;
+ }
+
+ return CLI_WINDOWS_MAX_LARGE_WRITEX_SIZE;
+}
+
+
/*
* Send a read&x request
*/
@@ -77,7 +112,7 @@ struct async_req *cli_read_andx_send(TALLOC_CTX *mem_ctx,
wct += 2;
}
- result = cli_request_send(mem_ctx, ev, cli, SMBreadX, 0, wct, vwv,
+ result = cli_request_send(mem_ctx, ev, cli, SMBreadX, 0, wct, vwv, 0,
0, NULL);
if (result == NULL) {
return NULL;
@@ -614,31 +649,7 @@ ssize_t cli_write(struct cli_state *cli,
mpx = 1;
}
- /* Default (small) writesize. */
- writesize = (cli->max_xmit - (smb_size+32)) & ~1023;
-
- if (write_mode == 0 &&
- !client_is_signing_on(cli) &&
- !cli_encryption_on(cli) &&
- (cli->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. */
- writesize = CLI_SAMBA_MAX_POSIX_LARGE_WRITEX_SIZE;
- } else if ((cli->capabilities & CAP_LARGE_WRITEX) &&
- (strcmp(cli->dev, "LPT1:") != 0)) {
-
- /* Printer devices are restricted to max_xmit
- * writesize in Vista and XPSP3. */
-
- if (cli->is_samba) {
- writesize = CLI_SAMBA_MAX_LARGE_WRITEX_SIZE;
- } else if (!client_is_signing_on(cli)) {
- /* Windows restricts signed writes to max_xmit.
- * Found by Volker. */
- writesize = CLI_WINDOWS_MAX_LARGE_WRITEX_SIZE;
- }
- }
+ writesize = cli_write_max_bufsize(cli, write_mode);
blocks = (size + (writesize-1)) / writesize;
diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c
index 120b6c0e293..baa73aeb14e 100644
--- a/source3/libsmb/clitrans.c
+++ b/source3/libsmb/clitrans.c
@@ -918,7 +918,7 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx,
* Primary request, retrieve our mid
*/
result = cli_request_send(mem_ctx, state->ev, state->cli,
- cmd, 0, wct, vwv,
+ cmd, 0, wct, vwv, 0,
talloc_get_size(bytes), bytes);
if (result == NULL) {
goto fail;
@@ -936,8 +936,8 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx,
wct * sizeof(uint16_t) + num_bytes + 3)) {
goto fail;
}
- result = cli_request_send(mem_ctx, state->ev, state->cli,
- cmd, 0, wct, vwv, num_bytes, bytes);
+ result = cli_request_send(mem_ctx, state->ev, state->cli, cmd,
+ 0, wct, vwv, 0, num_bytes, bytes);
if (result == NULL) {
goto fail;
}
diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c
index 5e37871deb1..f4714346d1d 100644
--- a/source3/libsmb/libsmb_server.c
+++ b/source3/libsmb/libsmb_server.c
@@ -433,7 +433,9 @@ again:
DEBUG(4,(" session request ok\n"));
- if (!cli_negprot(c)) {
+ status = cli_negprot(c);
+
+ if (!NT_STATUS_IS_OK(status)) {
cli_shutdown(c);
errno = ETIMEDOUT;
return NULL;
diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c
index ea2c46953c7..49830189116 100644
--- a/source3/libsmb/libsmb_xattr.c
+++ b/source3/libsmb/libsmb_xattr.c
@@ -199,12 +199,13 @@ convert_sid_to_string(struct cli_state *ipc_cli,
return;
}
- TALLOC_FREE(ctx);
/* Converted OK */
slprintf(str, sizeof(fstring) - 1, "%s%s%s",
domains[0], lp_winbind_separator(),
names[0]);
+
+ TALLOC_FREE(ctx);
}
/* convert a string to a SID, either numeric or username/group */
diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c
index bfe5e7b97bd..02b13ae63e9 100644
--- a/source3/libsmb/nmblib.c
+++ b/source3/libsmb/nmblib.c
@@ -21,9 +21,6 @@
#include "includes.h"
-int num_good_sends = 0;
-int num_good_receives = 0;
-
static const struct opcode_names {
const char *nmb_opcode_name;
int opcode;
@@ -796,8 +793,6 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type)
packet->fd = fd;
- num_good_receives++;
-
DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
length, inet_ntoa(packet->ip), packet->port ) );
@@ -838,9 +833,6 @@ static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
inet_ntoa(ip),port,strerror(errno)));
- if (ret)
- num_good_sends++;
-
return(ret);
}
diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c
index 4c76234e0c0..2746a4681e3 100644
--- a/source3/libsmb/passchange.c
+++ b/source3/libsmb/passchange.c
@@ -71,10 +71,12 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
cli->protocol = PROTOCOL_NT1;
- if (!cli_negprot(cli)) {
+ result = cli_negprot(cli);
+
+ if (!NT_STATUS_IS_OK(result)) {
asprintf(err_str, "machine %s rejected the negotiate "
"protocol. Error was : %s.\n",
- remote_machine, cli_errstr(cli) );
+ remote_machine, nt_errstr(result));
result = cli_nt_error(cli);
cli_shutdown(cli);
return result;