#include "libcli/security/security.h"
#include "../lib/util/tevent_ntstatus.h"
#include "rpc_server/srv_pipe_hnd.h"
+#include "lib/sys_rw_data.h"
static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
static void smbd_smb2_request_read_done(struct tevent_req *subreq);
NTSTATUS smbd_smb2_request_process_read(struct smbd_smb2_request *req)
{
+ struct smbXsrv_connection *xconn = req->xconn;
NTSTATUS status;
const uint8_t *inbody;
uint32_t in_length;
in_remaining_bytes = IVAL(inbody, 0x28);
/* check the max read size */
- if (in_length > req->sconn->smb2.max_read) {
+ if (in_length > xconn->smb2.server.max_read) {
DEBUG(2,("smbd_smb2_request_process_read: "
"client ignored max read: %s: 0x%08X: 0x%08X\n",
- __location__, in_length, req->sconn->smb2.max_read));
+ __location__, in_length, xconn->smb2.server.max_read));
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
if (!NT_STATUS_IS_OK(status)) {
error = smbd_smb2_request_error(req, status);
if (!NT_STATUS_IS_OK(error)) {
- smbd_server_connection_terminate(req->sconn,
+ smbd_server_connection_terminate(req->xconn,
nt_errstr(error));
return;
}
if (outbody.data == NULL) {
error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
if (!NT_STATUS_IS_OK(error)) {
- smbd_server_connection_terminate(req->sconn,
+ smbd_server_connection_terminate(req->xconn,
nt_errstr(error));
return;
}
error = smbd_smb2_request_done(req, outbody, &outdyn);
if (!NT_STATUS_IS_OK(error)) {
- smbd_server_connection_terminate(req->sconn,
+ smbd_server_connection_terminate(req->xconn,
nt_errstr(error));
return;
}
uint64_t in_offset = state->in_offset;
files_struct *fsp = state->fsp;
const DATA_BLOB *hdr = state->smb2req->queue_entry.sendfile_header;
+ NTSTATUS *pstatus = state->smb2req->queue_entry.sendfile_status;
+ struct smbXsrv_connection *xconn = state->smb2req->xconn;
ssize_t nread;
ssize_t ret;
+ int saved_errno;
- nread = SMB_VFS_SENDFILE(fsp->conn->sconn->sock,
+ nread = SMB_VFS_SENDFILE(xconn->transport.sock,
fsp,
hdr,
in_offset,
fsp_str_dbg(fsp) ));
if (nread == -1) {
+ saved_errno = errno;
+
/*
* Returning ENOSYS means no data at all was sent.
Do this as a normal read. */
* Fake this up by doing read/write calls.
*/
set_use_sendfile(SNUM(fsp->conn), false);
- nread = fake_sendfile(fsp, in_offset, in_length);
+ nread = fake_sendfile(xconn, fsp, in_offset, in_length);
if (nread == -1) {
- DEBUG(0,("smb2_sendfile_send_data: "
- "fake_sendfile failed for "
- "file %s (%s).\n",
- fsp_str_dbg(fsp),
- strerror(errno)));
- exit_server_cleanly("smb2_sendfile_send_data: "
- "fake_sendfile failed");
+ saved_errno = errno;
+ DEBUG(0,("smb2_sendfile_send_data: fake_sendfile "
+ "failed for file %s (%s) for client %s. "
+ "Terminating\n",
+ fsp_str_dbg(fsp), strerror(saved_errno),
+ smbXsrv_connection_dbg(xconn)));
+ *pstatus = map_nt_error_from_unix_common(saved_errno);
+ return 0;
}
goto out;
}
DEBUG(0,("smb2_sendfile_send_data: sendfile failed for file "
- "%s (%s). Terminating\n",
- fsp_str_dbg(fsp),
- strerror(errno)));
- exit_server_cleanly("smb2_sendfile_send_data: sendfile failed");
+ "%s (%s) for client %s. Terminating\n",
+ fsp_str_dbg(fsp), strerror(saved_errno),
+ smbXsrv_connection_dbg(xconn)));
+ *pstatus = map_nt_error_from_unix_common(saved_errno);
+ return 0;
} else if (nread == 0) {
/*
* Some sendfile implementations return 0 to indicate
normal_read:
/* Send out the header. */
- ret = write_data(fsp->conn->sconn->sock,
+ ret = write_data(xconn->transport.sock,
(const char *)hdr->data, hdr->length);
if (ret != hdr->length) {
- char addr[INET6_ADDRSTRLEN];
- /*
- * Try and give an error message saying what
- * client failed.
- */
- DEBUG(0, ("smb2_sendfile_send_data: write_data failed "
- "for client %s. Error %s\n",
- get_peer_addr(fsp->conn->sconn->sock, addr,
- sizeof(addr)),
- strerror(errno)));
-
+ saved_errno = errno;
DEBUG(0,("smb2_sendfile_send_data: write_data failed for file "
- "%s (%s). Terminating\n", fsp_str_dbg(fsp),
- strerror(errno)));
- exit_server_cleanly("smb2_sendfile_send_data: write_data failed");
+ "%s (%s) for client %s. Terminating\n",
+ fsp_str_dbg(fsp), strerror(saved_errno),
+ smbXsrv_connection_dbg(xconn)));
+ *pstatus = map_nt_error_from_unix_common(saved_errno);
+ return 0;
}
- nread = fake_sendfile(fsp, in_offset, in_length);
+ nread = fake_sendfile(xconn, fsp, in_offset, in_length);
if (nread == -1) {
- DEBUG(0,("smb2_sendfile_send_data: "
- "fake_sendfile failed for file "
- "%s (%s). Terminating\n",
- fsp_str_dbg(fsp),
- strerror(errno)));
- exit_server_cleanly("smb2_sendfile_send_data: "
- "fake_sendfile failed");
+ saved_errno = errno;
+ DEBUG(0,("smb2_sendfile_send_data: fake_sendfile "
+ "failed for file %s (%s) for client %s. "
+ "Terminating\n",
+ fsp_str_dbg(fsp), strerror(saved_errno),
+ smbXsrv_connection_dbg(xconn)));
+ *pstatus = map_nt_error_from_unix_common(saved_errno);
+ return 0;
}
out:
if (nread < in_length) {
- sendfile_short_send(fsp, nread, hdr->length, in_length);
+ ret = sendfile_short_send(xconn, fsp, nread,
+ hdr->length, in_length);
+ if (ret == -1) {
+ saved_errno = errno;
+ DEBUG(0,("%s: sendfile_short_send "
+ "failed for file %s (%s) for client %s. "
+ "Terminating\n",
+ __func__,
+ fsp_str_dbg(fsp), strerror(saved_errno),
+ smbXsrv_connection_dbg(xconn)));
+ *pstatus = map_nt_error_from_unix_common(saved_errno);
+ return 0;
+ }
}
init_strict_lock_struct(fsp,
&lock);
SMB_VFS_STRICT_UNLOCK(fsp->conn, fsp, &lock);
+
+ *pstatus = NT_STATUS_OK;
return 0;
}