[SCM] Samba Shared Repository - branch master updated
Jeremy Allison
jra at samba.org
Fri Apr 11 15:56:03 MDT 2014
The branch, master has been updated
via e49bae7 s3:smb2_server: remove unused get_min_receive_file_size() wrapper function
via 535103e s3:smb2_server: only allocate the required buffer in the smb2 recvfile() code path
via 80de72b s3:smb2_server: prepare smbd_smb2_request_verify_sizes() for the optimized recvfile() case
via 1f767b2 s3:smb2_write: allow SMBD_SMB2_IN_DYN_LEN() to be 0 for the recvfile case.
via 95df39b s3:smb2_server: make sure we don't try recvfile for special NBT messages
via 7968749 s3:smb2_server: use the same logic to avoid recvfile() for IPC/PRINT shares
via 77b6860 s3:smbd: use smb1srv_open_lookup() in is_valid_writeX_buffer()
via 8d45b75 s3:smbXsrv_open: allow now==0 to skip the idle_time update.
via f717802 s3:lib: use stack buffers in drain_socket() and default_sys_recvfile()
from 4daf7d4 libs: s3 and s4: make our dns lookup code signal-safe.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit e49bae7ac9fb0be4cbb4530d75a4431cbbb495c8
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Apr 11 01:37:42 2014 +0200
s3:smb2_server: remove unused get_min_receive_file_size() wrapper function
smb2req always comes from talloc_zero().
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
Autobuild-User(master): Jeremy Allison <jra at samba.org>
Autobuild-Date(master): Fri Apr 11 23:55:17 CEST 2014 on sn-devel-104
commit 535103e7a38e175fec082a658c2b70dbdd9af33e
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Nov 15 09:12:40 2013 +0100
s3:smb2_server: only allocate the required buffer in the smb2 recvfile() code path
This way the buffer will likely be allocated within the existing talloc_pool,
which avoids one malloc() per request.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 80de72bb57520a1a14c3d3db3f31dc588d0afd64
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Nov 18 13:46:10 2013 +0100
s3:smb2_server: prepare smbd_smb2_request_verify_sizes() for the optimized recvfile() case
For recvfile we haven't read and may not allocated the dyn buffer.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 1f767b29a89e15c4d7187cd0bc9b0c2e3152edd7
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Nov 18 13:45:37 2013 +0100
s3:smb2_write: allow SMBD_SMB2_IN_DYN_LEN() to be 0 for the recvfile case.
For recvfile we haven't read and may not allocated the dyn buffer.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 95df39b99f17810cb230c4a6a0d0952919cd0b81
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Apr 11 01:05:21 2014 +0200
s3:smb2_server: make sure we don't try recvfile for special NBT messages
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 796874912d9935e202b8c767ca33d557dce9c43e
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Apr 11 00:43:46 2014 +0200
s3:smb2_server: use the same logic to avoid recvfile() for IPC/PRINT shares
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 77b6860668437bbb3bb66f57f75ea4fc378de49b
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Apr 11 00:51:32 2014 +0200
s3:smbd: use smb1srv_open_lookup() in is_valid_writeX_buffer()
It's more logical to check the fnum instead of tid here.
This will make it easier to reuse the logic for SMB2 and
allows per fsp recvfile detection.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 8d45b75df31d5c382345186791a375e2b800066e
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Apr 11 00:29:48 2014 +0200
s3:smbXsrv_open: allow now==0 to skip the idle_time update.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit f71780202a3e736432020cf894b138a06e4bb869
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Dec 5 11:20:49 2013 +0100
s3:lib: use stack buffers in drain_socket() and default_sys_recvfile()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
-----------------------------------------------------------------------
Summary of changes:
source3/lib/recvfile.c | 18 +------
source3/smbd/globals.h | 1 +
source3/smbd/reply.c | 29 +++++++---
source3/smbd/smb2_server.c | 116 +++++++++++++++++++++++++++++++------------
source3/smbd/smb2_write.c | 20 +++++++-
source3/smbd/smbXsrv_open.c | 4 +-
6 files changed, 128 insertions(+), 60 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/lib/recvfile.c b/source3/lib/recvfile.c
index 72f4257..500a7e4 100644
--- a/source3/lib/recvfile.c
+++ b/source3/lib/recvfile.c
@@ -51,7 +51,7 @@ static ssize_t default_sys_recvfile(int fromfd,
size_t total = 0;
size_t bufsize = MIN(TRANSFER_BUF_SIZE,count);
size_t total_written = 0;
- char *buffer = NULL;
+ char buffer[bufsize];
DEBUG(10,("default_sys_recvfile: from = %d, to = %d, "
"offset=%.0f, count = %lu\n",
@@ -70,11 +70,6 @@ static ssize_t default_sys_recvfile(int fromfd,
}
}
- buffer = SMB_MALLOC_ARRAY(char, bufsize);
- if (buffer == NULL) {
- return -1;
- }
-
while (total < count) {
size_t num_written = 0;
ssize_t read_ret;
@@ -84,7 +79,6 @@ static ssize_t default_sys_recvfile(int fromfd,
read_ret = sys_read(fromfd, buffer, toread);
if (read_ret <= 0) {
/* EOF or socket error. */
- free(buffer);
return -1;
}
@@ -119,7 +113,6 @@ static ssize_t default_sys_recvfile(int fromfd,
total += read_ret;
}
- free(buffer);
if (saved_errno) {
/* Return the correct write error. */
errno = saved_errno;
@@ -247,21 +240,15 @@ ssize_t drain_socket(int sockfd, size_t count)
{
size_t total = 0;
size_t bufsize = MIN(TRANSFER_BUF_SIZE,count);
- char *buffer = NULL;
+ char buffer[bufsize];
int old_flags = 0;
if (count == 0) {
return 0;
}
- buffer = SMB_MALLOC_ARRAY(char, bufsize);
- if (buffer == NULL) {
- return -1;
- }
-
old_flags = fcntl(sockfd, F_GETFL, 0);
if (set_blocking(sockfd, true) == -1) {
- free(buffer);
return -1;
}
@@ -281,7 +268,6 @@ ssize_t drain_socket(int sockfd, size_t count)
out:
- free(buffer);
if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
return -1;
}
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 3baa048..cd99fe7 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -768,6 +768,7 @@ struct smbd_server_connection {
struct iovec vector;
bool doing_receivefile;
size_t min_recv_size;
+ size_t pktfull;
size_t pktlen;
uint8_t *pktbuf;
} request_read_state;
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index e58735e..da59ca7 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -4598,12 +4598,12 @@ bool is_valid_writeX_buffer(struct smbd_server_connection *sconn,
const uint8_t *inbuf)
{
size_t numtowrite;
- connection_struct *conn = NULL;
unsigned int doff = 0;
size_t len = smb_len_large(inbuf);
- struct smbXsrv_tcon *tcon;
+ uint16_t fnum;
+ struct smbXsrv_open *op = NULL;
+ struct files_struct *fsp = NULL;
NTSTATUS status;
- NTTIME now = 0;
if (is_encrypted_packet(sconn, inbuf)) {
/* Can't do this on encrypted
@@ -4622,19 +4622,30 @@ bool is_valid_writeX_buffer(struct smbd_server_connection *sconn,
return false;
}
- status = smb1srv_tcon_lookup(sconn->conn, SVAL(inbuf, smb_tid),
- now, &tcon);
+ fnum = SVAL(inbuf, smb_vwv2);
+ status = smb1srv_open_lookup(sconn->conn,
+ fnum,
+ 0, /* now */
+ &op);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10,("is_valid_writeX_buffer: bad tid\n"));
+ DEBUG(10,("is_valid_writeX_buffer: bad fnum\n"));
+ return false;
+ }
+ fsp = op->compat;
+ if (fsp == NULL) {
+ DEBUG(10,("is_valid_writeX_buffer: bad fsp\n"));
+ return false;
+ }
+ if (fsp->conn == NULL) {
+ DEBUG(10,("is_valid_writeX_buffer: bad fsp->conn\n"));
return false;
}
- conn = tcon->compat;
- if (IS_IPC(conn)) {
+ if (IS_IPC(fsp->conn)) {
DEBUG(10,("is_valid_writeX_buffer: IPC$ tid\n"));
return false;
}
- if (IS_PRINT(conn)) {
+ if (IS_PRINT(fsp->conn)) {
DEBUG(10,("is_valid_writeX_buffer: printing tid\n"));
return false;
}
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 3c46efd..4a7abcb 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -1870,6 +1870,15 @@ NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
case SMB2_OP_GETINFO:
min_dyn_size = 0;
break;
+ case SMB2_OP_WRITE:
+ if (req->smb1req != NULL && req->smb1req->unread_bytes > 0) {
+ if (req->smb1req->unread_bytes < min_dyn_size) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ min_dyn_size = 0;
+ }
+ break;
}
/*
@@ -2828,20 +2837,21 @@ NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn,
return NT_STATUS_OK;
}
-static size_t get_min_receive_file_size(struct smbd_smb2_request *smb2_req)
-{
- if (smb2_req->do_signing) {
- return 0;
- }
- if (smb2_req->do_encryption) {
- return 0;
- }
- return (size_t)lp_min_receive_file_size();
-}
-
static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
{
+ NTSTATUS status;
uint32_t flags;
+ uint64_t file_id_persistent;
+ uint64_t file_id_volatile;
+ struct smbXsrv_open *op = NULL;
+ struct files_struct *fsp = NULL;
+ const uint8_t *body = NULL;
+
+ /*
+ * This is only called with a pktbuf
+ * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
+ * bytes
+ */
if (IVAL(state->pktbuf, 0) == SMB2_TF_MAGIC) {
/* Transform header. Cannot recvfile. */
@@ -2873,9 +2883,37 @@ static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
return false;
}
+ body = &state->pktbuf[SMB2_HDR_BODY];
+
+ file_id_persistent = BVAL(body, 0x10);
+ file_id_volatile = BVAL(body, 0x18);
+
+ status = smb2srv_open_lookup(state->req->sconn->conn,
+ file_id_persistent,
+ file_id_volatile,
+ 0, /* now */
+ &op);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ fsp = op->compat;
+ if (fsp == NULL) {
+ return false;
+ }
+ if (fsp->conn == NULL) {
+ return false;
+ }
+
+ if (IS_IPC(fsp->conn)) {
+ return false;
+ }
+ if (IS_PRINT(fsp->conn)) {
+ return false;
+ }
+
DEBUG(10,("Doing recvfile write len = %u\n",
- (unsigned int)(state->pktlen -
- SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN)));
+ (unsigned int)(state->pktfull - state->pktlen)));
return true;
}
@@ -2920,7 +2958,7 @@ static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *s
return NT_STATUS_NO_MEMORY;
}
state->req->sconn = sconn;
- state->min_recv_size = get_min_receive_file_size(state->req);
+ state->min_recv_size = lp_min_receive_file_size();
TEVENT_FD_READABLE(sconn->smb2.fde);
@@ -3213,10 +3251,21 @@ again:
* Read the rest of the data.
*/
state->doing_receivefile = false;
+
+ state->pktbuf = talloc_realloc(state->req,
+ state->pktbuf,
+ uint8_t,
+ state->pktfull);
+ if (state->pktbuf == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
state->vector.iov_base = (void *)(state->pktbuf +
- SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN);
- state->vector.iov_len = (state->pktlen -
- SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN);
+ state->pktlen);
+ state->vector.iov_len = (state->pktfull -
+ state->pktlen);
+
+ state->pktlen = state->pktfull;
goto again;
}
@@ -3230,24 +3279,20 @@ again:
/*
* Now we analyze the NBT header
*/
- state->pktlen = smb2_len(state->hdr.nbt);
- if (state->pktlen == 0) {
- goto got_full;
+ if (state->hdr.nbt[0] != 0x00) {
+ state->min_recv_size = 0;
}
-
- state->pktbuf = talloc_array(state->req, uint8_t, state->pktlen);
- if (state->pktbuf == NULL) {
- return NT_STATUS_NO_MEMORY;
+ state->pktfull = smb2_len(state->hdr.nbt);
+ if (state->pktfull == 0) {
+ goto got_full;
}
- state->vector.iov_base = (void *)state->pktbuf;
-
if (state->min_recv_size != 0) {
min_recvfile_size = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
min_recvfile_size += state->min_recv_size;
}
- if (state->pktlen > min_recvfile_size) {
+ if (state->pktfull > min_recvfile_size) {
/*
* Might be a receivefile write. Read the SMB2 HEADER +
* SMB2_WRITE header first. Set 'doing_receivefile'
@@ -3256,12 +3301,20 @@ again:
* not suitable then we'll just read the rest of the data
* the next time this function is called.
*/
- state->vector.iov_len = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
+ state->pktlen = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
state->doing_receivefile = true;
} else {
- state->vector.iov_len = state->pktlen;
+ state->pktlen = state->pktfull;
}
+ state->pktbuf = talloc_array(state->req, uint8_t, state->pktlen);
+ if (state->pktbuf == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ state->vector.iov_base = (void *)state->pktbuf;
+ state->vector.iov_len = state->pktlen;
+
goto again;
got_full:
@@ -3273,7 +3326,7 @@ got_full:
req = state->req;
ZERO_STRUCTP(state);
state->req = req;
- state->min_recv_size = get_min_receive_file_size(state->req);
+ state->min_recv_size = lp_min_receive_file_size();
req = NULL;
goto again;
}
@@ -3300,8 +3353,7 @@ got_full:
if (req->smb1req == NULL) {
return NT_STATUS_NO_MEMORY;
}
- req->smb1req->unread_bytes =
- state->pktlen - SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
+ req->smb1req->unread_bytes = state->pktfull - state->pktlen;
}
ZERO_STRUCTP(state);
diff --git a/source3/smbd/smb2_write.c b/source3/smbd/smb2_write.c
index 4e138fe..c61254f 100644
--- a/source3/smbd/smb2_write.c
+++ b/source3/smbd/smb2_write.c
@@ -48,6 +48,8 @@ NTSTATUS smbd_smb2_request_process_write(struct smbd_smb2_request *req)
uint64_t in_file_id_volatile;
struct files_struct *in_fsp;
uint32_t in_flags;
+ size_t in_dyn_len = 0;
+ uint8_t *in_dyn_ptr = NULL;
struct tevent_req *subreq;
status = smbd_smb2_request_verify_sizes(req, 0x31);
@@ -67,7 +69,15 @@ NTSTATUS smbd_smb2_request_process_write(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
- if (in_data_length > SMBD_SMB2_IN_DYN_LEN(req)) {
+ if (req->smb1req != NULL && req->smb1req->unread_bytes > 0) {
+ in_dyn_ptr = NULL;
+ in_dyn_len = req->smb1req->unread_bytes;
+ } else {
+ in_dyn_ptr = SMBD_SMB2_IN_DYN_PTR(req);
+ in_dyn_len = SMBD_SMB2_IN_DYN_LEN(req);
+ }
+
+ if (in_data_length > in_dyn_len) {
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
@@ -79,7 +89,10 @@ NTSTATUS smbd_smb2_request_process_write(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
- in_data_buffer.data = SMBD_SMB2_IN_DYN_PTR(req);
+ /*
+ * Note: that in_dyn_ptr is NULL for the recvfile case.
+ */
+ in_data_buffer.data = in_dyn_ptr;
in_data_buffer.length = in_data_length;
status = smbd_smb2_request_verify_creditcharge(req, in_data_length);
@@ -340,6 +353,9 @@ static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
+ /*
+ * Note: in_data.data is NULL for the recvfile case.
+ */
nwritten = write_file(smbreq, fsp,
(const char *)in_data.data,
in_offset,
diff --git a/source3/smbd/smbXsrv_open.c b/source3/smbd/smbXsrv_open.c
index b15be28..c3ff3bb 100644
--- a/source3/smbd/smbXsrv_open.c
+++ b/source3/smbd/smbXsrv_open.c
@@ -444,7 +444,9 @@ static NTSTATUS smbXsrv_open_local_lookup(struct smbXsrv_open_table *table,
return NT_STATUS_FILE_CLOSED;
}
- state.op->idle_time = now;
+ if (now != 0) {
+ state.op->idle_time = now;
+ }
*_open = state.op;
return state.op->status;
--
Samba Shared Repository
More information about the samba-cvs
mailing list