summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2008-01-04 12:56:23 -0800
committerJeremy Allison <jra@samba.org>2008-01-04 12:56:23 -0800
commit9254bb4ef1c3c3a52ea8e935edb0e7a86ec3ea7a (patch)
treed4b770708ccb2a8b100d6817ee039f41b6e1ac00 /source3/smbd
parent517ad5318d3d196713b96f69eff8e2f5d38d922a (diff)
downloadsamba-9254bb4ef1c3c3a52ea8e935edb0e7a86ec3ea7a.tar.gz
samba-9254bb4ef1c3c3a52ea8e935edb0e7a86ec3ea7a.tar.bz2
samba-9254bb4ef1c3c3a52ea8e935edb0e7a86ec3ea7a.zip
Refactor the crypto code after a very helpful conversation
with Volker. Mostly making sure we have data on the incoming packet type, not stored in the smb header. Jeremy. (This used to be commit c4e5a505043965eec77b5bb9bc60957e8f3b97c8)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/aio.c27
-rw-r--r--source3/smbd/blocking.c34
-rw-r--r--source3/smbd/error.c4
-rw-r--r--source3/smbd/ipc.c53
-rw-r--r--source3/smbd/lanman.c2
-rw-r--r--source3/smbd/notify.c46
-rw-r--r--source3/smbd/nttrans.c39
-rw-r--r--source3/smbd/open.c4
-rw-r--r--source3/smbd/oplock.c26
-rw-r--r--source3/smbd/pipes.c3
-rw-r--r--source3/smbd/process.c173
-rw-r--r--source3/smbd/reply.c55
-rw-r--r--source3/smbd/seal.c44
-rw-r--r--source3/smbd/sesssetup.c2
-rw-r--r--source3/smbd/trans2.c69
15 files changed, 345 insertions, 236 deletions
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index a439c3a4f0..bc1761b0fd 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -236,7 +236,7 @@ bool schedule_aio_read_and_X(connection_struct *conn,
}
construct_reply_common((char *)req->inbuf, aio_ex->outbuf);
- srv_set_message((const char *)req->inbuf, aio_ex->outbuf, 12, 0, True);
+ srv_set_message(aio_ex->outbuf, 12, 0, True);
SCVAL(aio_ex->outbuf,smb_vwv0,0xFF); /* Never a chained reply. */
a = &aio_ex->acb;
@@ -356,8 +356,9 @@ bool schedule_aio_write_and_X(connection_struct *conn,
SSVAL(aio_ex->outbuf,smb_vwv2,numtowrite);
SSVAL(aio_ex->outbuf,smb_vwv4,(numtowrite>>16)&1);
show_msg(aio_ex->outbuf);
- if (!send_smb(smbd_server_fd(),aio_ex->outbuf)) {
- exit_server_cleanly("handle_aio_write: send_smb "
+ if (!srv_send_smb(smbd_server_fd(),aio_ex->outbuf,
+ IS_CONN_ENCRYPTED(fsp->conn))) {
+ exit_server_cleanly("handle_aio_write: srv_send_smb "
"failed.");
}
DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write "
@@ -387,7 +388,6 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
int ret = 0;
int outsize;
char *outbuf = aio_ex->outbuf;
- const char *inbuf = aio_ex->inbuf;
char *data = smb_buf(outbuf);
ssize_t nread = SMB_VFS_AIO_RETURN(aio_ex->fsp,&aio_ex->acb);
@@ -410,9 +410,9 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
ret = errno;
ERROR_NT(map_nt_error_from_unix(ret));
- outsize = srv_set_message(inbuf,outbuf,0,0,true);
+ outsize = srv_set_message(outbuf,0,0,true);
} else {
- outsize = srv_set_message(inbuf, outbuf,12,nread,False);
+ outsize = srv_set_message(outbuf,12,nread,False);
SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be * -1. */
SSVAL(outbuf,smb_vwv5,nread);
SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
@@ -425,10 +425,11 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
(int)aio_ex->acb.aio_nbytes, (int)nread ) );
}
- _smb_setlen(outbuf,outsize - 4);
+ smb_setlen(outbuf,outsize - 4);
show_msg(outbuf);
- if (!send_smb(smbd_server_fd(),outbuf)) {
- exit_server_cleanly("handle_aio_read_complete: send_smb "
+ if (!srv_send_smb(smbd_server_fd(),outbuf,
+ IS_CONN_ENCRYPTED(aio_ex->fsp->conn))) {
+ exit_server_cleanly("handle_aio_read_complete: srv_send_smb "
"failed.");
}
@@ -497,7 +498,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
ret = errno;
ERROR_BOTH(map_nt_error_from_unix(ret), ERRHRD, ERRdiskfull);
- srv_set_message(inbuf,outbuf,0,0,true);
+ srv_set_message(outbuf,0,0,true);
} else {
bool write_through = BITSETW(aio_ex->inbuf+smb_vwv7,0);
NTSTATUS status;
@@ -516,15 +517,15 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
ret = errno;
ERROR_BOTH(map_nt_error_from_unix(ret),
ERRHRD, ERRdiskfull);
- srv_set_message(inbuf,outbuf,0,0,true);
+ srv_set_message(outbuf,0,0,true);
DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n",
fsp->fsp_name, nt_errstr(status) ));
}
}
show_msg(outbuf);
- if (!send_smb(smbd_server_fd(),outbuf)) {
- exit_server_cleanly("handle_aio_write: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),outbuf,IS_CONN_ENCRYPTED(fsp->conn))) {
+ exit_server_cleanly("handle_aio_write: srv_send_smb failed.");
}
DEBUG(10,("handle_aio_write_complete: scheduled aio_write completed "
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 0078bb7d13..c56f635dde 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -41,6 +41,7 @@ typedef struct _blocking_lock_record {
enum brl_type lock_type;
char *inbuf;
int length;
+ bool encrypted;
} blocking_lock_record;
/* dlink list we store pending lock records on. */
@@ -149,7 +150,7 @@ static bool recalc_brl_timeout(void)
****************************************************************************/
bool push_blocking_lock_request( struct byte_range_lock *br_lck,
- const char *inbuf, int length,
+ const struct smb_request *req,
files_struct *fsp,
int lock_timeout,
int lock_num,
@@ -161,6 +162,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
uint32 blocking_pid)
{
static bool set_lock_msg;
+ size_t length = smb_len(req->inbuf)+4;
blocking_lock_record *blr;
NTSTATUS status;
@@ -188,7 +190,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
return False;
}
- blr->com_type = CVAL(inbuf,smb_com);
+ blr->com_type = CVAL(req->inbuf,smb_com);
blr->fsp = fsp;
if (lock_timeout == -1) {
blr->expire_time.tv_sec = 0;
@@ -204,8 +206,9 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
blr->lock_type = lock_type;
blr->offset = offset;
blr->count = count;
- memcpy(blr->inbuf, inbuf, length);
+ memcpy(blr->inbuf, req->inbuf, length);
blr->length = length;
+ blr->encrypted = req->encrypted;
/* Add a pending lock record for this. */
status = brl_lock(smbd_messaging_context(), br_lck,
@@ -242,7 +245,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
blr->fsp->fnum, blr->fsp->fsp_name ));
/* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(SVAL(inbuf,smb_mid));
+ srv_defer_sign_response(SVAL(req->inbuf,smb_mid));
return True;
}
@@ -259,7 +262,7 @@ static void reply_lockingX_success(blocking_lock_record *blr)
smb_panic("Could not allocate smb_request");
}
- init_smb_request(req, (uint8 *)blr->inbuf, 0);
+ init_smb_request(req, (uint8 *)blr->inbuf, 0, blr->encrypted);
reply_outbuf(req, 2, 0);
/*
@@ -272,8 +275,10 @@ static void reply_lockingX_success(blocking_lock_record *blr)
chain_reply(req);
- if (!send_smb(smbd_server_fd(),(char *)req->outbuf)) {
- exit_server_cleanly("send_blocking_reply: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(blr->fsp->conn))) {
+ exit_server_cleanly("send_blocking_reply: srv_send_smb failed.");
}
}
@@ -309,8 +314,9 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat
}
ERROR_NT(status);
- if (!send_smb(smbd_server_fd(),outbuf)) {
- exit_server_cleanly("generic_blocking_lock_error: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),outbuf,
+ IS_CONN_ENCRYPTED(blr->fsp->conn))) {
+ exit_server_cleanly("generic_blocking_lock_error: srv_send_smb failed.");
}
}
@@ -388,8 +394,10 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status
*/
SCVAL(outbuf,smb_com,SMBtrans2);
ERROR_NT(status);
- if (!send_smb(smbd_server_fd(),outbuf)) {
- exit_server_cleanly("blocking_lock_reply_error: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ outbuf,
+ IS_CONN_ENCRYPTED(blr->fsp->conn))) {
+ exit_server_cleanly("blocking_lock_reply_error: srv_send_smb failed.");
}
break;
}
@@ -531,12 +539,12 @@ static bool process_trans2(blocking_lock_record *blr)
return True;
}
- init_smb_request(req, (uint8 *)blr->inbuf, 0);
+ init_smb_request(req, (uint8 *)blr->inbuf, 0, blr->encrypted);
SCVAL(req->inbuf, smb_com, SMBtrans2);
SSVAL(params,0,0);
/* Fake up max_data_bytes here - we know it fits. */
- send_trans2_replies(req, params, 2, NULL, 0, 0xffff);
+ send_trans2_replies(blr->fsp->conn, req, params, 2, NULL, 0, 0xffff);
return True;
}
diff --git a/source3/smbd/error.c b/source3/smbd/error.c
index c669e74146..de2de088ec 100644
--- a/source3/smbd/error.c
+++ b/source3/smbd/error.c
@@ -81,9 +81,9 @@ void error_packet_set(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatu
}
}
-int error_packet(const char *inbuf, char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
+int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
{
- int outsize = srv_set_message(inbuf, outbuf,0,0,True);
+ int outsize = srv_set_message(outbuf,0,0,True);
error_packet_set(outbuf, eclass, ecode, ntstatus, line, file);
return outsize;
}
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index f28016ccb3..a89f5cbbfe 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -30,7 +30,7 @@ extern int max_send;
#define NERR_notsupported 50
-static void api_no_reply(struct smb_request *req);
+static void api_no_reply(connection_struct *conn, struct smb_request *req);
/*******************************************************************
copies parameters and data, as needed, into the smb buffer
@@ -81,7 +81,8 @@ static void copy_trans_params_and_data(char *outbuf, int align,
Send a trans reply.
****************************************************************************/
-void send_trans_reply(struct smb_request *req,
+void send_trans_reply(connection_struct *conn,
+ struct smb_request *req,
char *rparam, int rparam_len,
char *rdata, int rdata_len,
bool buffer_too_large)
@@ -129,8 +130,10 @@ void send_trans_reply(struct smb_request *req,
}
show_msg((char *)req->outbuf);
- if (!send_smb(smbd_server_fd(),(char *)req->outbuf))
- exit_server_cleanly("send_trans_reply: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(conn)))
+ exit_server_cleanly("send_trans_reply: srv_send_smb failed.");
TALLOC_FREE(req->outbuf);
@@ -175,8 +178,10 @@ void send_trans_reply(struct smb_request *req,
}
show_msg((char *)req->outbuf);
- if (!send_smb(smbd_server_fd(), (char *)req->outbuf))
- exit_server_cleanly("send_trans_reply: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(conn)))
+ exit_server_cleanly("send_trans_reply: srv_send_smb failed.");
tot_data_sent += this_ldata;
tot_param_sent += this_lparam;
@@ -188,7 +193,7 @@ void send_trans_reply(struct smb_request *req,
Start the first part of an RPC reply which began with an SMBtrans request.
****************************************************************************/
-static void api_rpc_trans_reply(struct smb_request *req, smb_np_struct *p)
+static void api_rpc_trans_reply(connection_struct *conn, struct smb_request *req, smb_np_struct *p)
{
bool is_data_outstanding;
char *rdata = (char *)SMB_MALLOC(p->max_trans_reply);
@@ -203,11 +208,11 @@ static void api_rpc_trans_reply(struct smb_request *req, smb_np_struct *p)
if((data_len = read_from_pipe( p, rdata, p->max_trans_reply,
&is_data_outstanding)) < 0) {
SAFE_FREE(rdata);
- api_no_reply(req);
+ api_no_reply(conn,req);
return;
}
- send_trans_reply(req, NULL, 0, rdata, data_len, is_data_outstanding);
+ send_trans_reply(conn, req, NULL, 0, rdata, data_len, is_data_outstanding);
SAFE_FREE(rdata);
return;
}
@@ -216,7 +221,7 @@ static void api_rpc_trans_reply(struct smb_request *req, smb_np_struct *p)
WaitNamedPipeHandleState
****************************************************************************/
-static void api_WNPHS(struct smb_request *req, smb_np_struct *p,
+static void api_WNPHS(connection_struct *conn, struct smb_request *req, smb_np_struct *p,
char *param, int param_len)
{
uint16 priority;
@@ -231,10 +236,10 @@ static void api_WNPHS(struct smb_request *req, smb_np_struct *p,
if (wait_rpc_pipe_hnd_state(p, priority)) {
/* now send the reply */
- send_trans_reply(req, NULL, 0, NULL, 0, False);
+ send_trans_reply(conn, req, NULL, 0, NULL, 0, False);
return;
}
- api_no_reply(req);
+ api_no_reply(conn,req);
}
@@ -242,7 +247,7 @@ static void api_WNPHS(struct smb_request *req, smb_np_struct *p,
SetNamedPipeHandleState
****************************************************************************/
-static void api_SNPHS(struct smb_request *req, smb_np_struct *p,
+static void api_SNPHS(connection_struct *conn, struct smb_request *req, smb_np_struct *p,
char *param, int param_len)
{
uint16 id;
@@ -257,10 +262,10 @@ static void api_SNPHS(struct smb_request *req, smb_np_struct *p,
if (set_rpc_pipe_hnd_state(p, id)) {
/* now send the reply */
- send_trans_reply(req, NULL, 0, NULL, 0, False);
+ send_trans_reply(conn, req, NULL, 0, NULL, 0, False);
return;
}
- api_no_reply(req);
+ api_no_reply(conn,req);
}
@@ -268,7 +273,7 @@ static void api_SNPHS(struct smb_request *req, smb_np_struct *p,
When no reply is generated, indicate unsupported.
****************************************************************************/
-static void api_no_reply(struct smb_request *req)
+static void api_no_reply(connection_struct *conn, struct smb_request *req)
{
char rparam[4];
@@ -279,7 +284,7 @@ static void api_no_reply(struct smb_request *req)
DEBUG(3,("Unsupported API fd command\n"));
/* now send the reply */
- send_trans_reply(req, rparam, 4, NULL, 0, False);
+ send_trans_reply(conn, req, rparam, 4, NULL, 0, False);
return;
}
@@ -321,7 +326,7 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid,
/* Win9x does this call with a unicode pipe name, not a pnum. */
/* Just return success for now... */
DEBUG(3,("Got TRANSACT_WAITNAMEDPIPEHANDLESTATE on text pipe name\n"));
- send_trans_reply(req, NULL, 0, NULL, 0, False);
+ send_trans_reply(conn, req, NULL, 0, NULL, 0, False);
return;
}
@@ -349,18 +354,18 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid,
/* dce/rpc command */
reply = write_to_pipe(p, data, tdscnt);
if (!reply) {
- api_no_reply(req);
+ api_no_reply(conn, req);
return;
}
- api_rpc_trans_reply(req, p);
+ api_rpc_trans_reply(conn, req, p);
break;
case TRANSACT_WAITNAMEDPIPEHANDLESTATE:
/* Wait Named Pipe Handle state */
- api_WNPHS(req, p, params, tpscnt);
+ api_WNPHS(conn, req, p, params, tpscnt);
break;
case TRANSACT_SETNAMEDPIPEHANDLESTATE:
/* Set Named Pipe Handle state */
- api_SNPHS(req, p, params, tpscnt);
+ api_SNPHS(conn, req, p, params, tpscnt);
break;
default:
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
@@ -472,8 +477,10 @@ static void handle_trans(connection_struct *conn, struct smb_request *req,
state->max_data_return,
state->max_param_return);
- if (state->close_on_completion)
+ if (state->close_on_completion) {
close_cnum(conn,state->vuid);
+ req->conn = NULL;
+ }
return;
}
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index 3ab216c062..5a6df1f139 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -4605,7 +4605,7 @@ void api_reply(connection_struct *conn, uint16 vuid,
/* If api_Unsupported returns false we can't return anything. */
if (reply) {
- send_trans_reply(req, rparam, rparam_len,
+ send_trans_reply(conn, req, rparam, rparam_len,
rdata, rdata_len, False);
}
diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index baab48f77e..7287210802 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -128,10 +128,10 @@ static bool notify_marshall_changes(int num_changes,
Setup the common parts of the return packet and send it.
*****************************************************************************/
-static void change_notify_reply_packet(const uint8 *request_buf,
+static void change_notify_reply_packet(connection_struct *conn,
+ const uint8 *request_buf,
NTSTATUS error_code)
{
- const char *inbuf = (const char *)request_buf;
char outbuf[smb_size+38];
memset(outbuf, '\0', sizeof(outbuf));
@@ -143,15 +143,18 @@ static void change_notify_reply_packet(const uint8 *request_buf,
* Seems NT needs a transact command with an error code
* in it. This is a longer packet than a simple error.
*/
- srv_set_message((const char *)request_buf, outbuf,18,0,False);
+ srv_set_message(outbuf,18,0,False);
show_msg(outbuf);
- if (!send_smb(smbd_server_fd(),outbuf))
- exit_server_cleanly("change_notify_reply_packet: send_smb "
+ if (!srv_send_smb(smbd_server_fd(),
+ outbuf,
+ IS_CONN_ENCRYPTED(conn)))
+ exit_server_cleanly("change_notify_reply_packet: srv_send_smb "
"failed.");
}
-void change_notify_reply(const uint8 *request_buf, uint32 max_param,
+void change_notify_reply(connection_struct *conn,
+ const uint8 *request_buf, uint32 max_param,
struct notify_change_buf *notify_buf)
{
prs_struct ps;
@@ -159,7 +162,7 @@ void change_notify_reply(const uint8 *request_buf, uint32 max_param,
uint8 tmp_request[smb_size];
if (notify_buf->num_changes == -1) {
- change_notify_reply_packet(request_buf, NT_STATUS_OK);
+ change_notify_reply_packet(conn, request_buf, NT_STATUS_OK);
notify_buf->num_changes = 0;
return;
}
@@ -172,12 +175,12 @@ void change_notify_reply(const uint8 *request_buf, uint32 max_param,
* We exceed what the client is willing to accept. Send
* nothing.
*/
- change_notify_reply_packet(request_buf, NT_STATUS_OK);
+ change_notify_reply_packet(conn, request_buf, NT_STATUS_OK);
goto done;
}
if (!(req = talloc(talloc_tos(), struct smb_request))) {
- change_notify_reply_packet(request_buf, NT_STATUS_NO_MEMORY);
+ change_notify_reply_packet(conn, request_buf, NT_STATUS_NO_MEMORY);
goto done;
}
@@ -190,9 +193,9 @@ void change_notify_reply(const uint8 *request_buf, uint32 max_param,
smb_setlen((char *)tmp_request, smb_size);
SCVAL(tmp_request, smb_wct, 0);
- init_smb_request(req, tmp_request,0);
+ init_smb_request(req, tmp_request,0, conn->encrypted_tid);
- send_nt_replies(req, NT_STATUS_OK, prs_data_p(&ps),
+ send_nt_replies(conn, req, NT_STATUS_OK, prs_data_p(&ps),
prs_offset(&ps), NULL, 0);
done:
@@ -243,9 +246,10 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter,
return status;
}
-NTSTATUS change_notify_add_request(const uint8 *inbuf, uint32 max_param,
- uint32 filter, bool recursive,
- struct files_struct *fsp)
+NTSTATUS change_notify_add_request(const struct smb_request *req,
+ uint32 max_param,
+ uint32 filter, bool recursive,
+ struct files_struct *fsp)
{
struct notify_change_request *request = NULL;
struct notify_mid_map *map = NULL;
@@ -259,7 +263,7 @@ NTSTATUS change_notify_add_request(const uint8 *inbuf, uint32 max_param,
request->mid_map = map;
map->req = request;
- memcpy(request->request_buf, inbuf, sizeof(request->request_buf));
+ memcpy(request->request_buf, req->inbuf, sizeof(request->request_buf));
request->max_param = max_param;
request->filter = filter;
request->fsp = fsp;
@@ -268,11 +272,11 @@ NTSTATUS change_notify_add_request(const uint8 *inbuf, uint32 max_param,
DLIST_ADD_END(fsp->notify->requests, request,
struct notify_change_request *);
- map->mid = SVAL(inbuf, smb_mid);
+ map->mid = SVAL(req->inbuf, smb_mid);
DLIST_ADD(notify_changes_by_mid, map);
/* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(SVAL(inbuf,smb_mid));
+ srv_defer_sign_response(SVAL(req->inbuf,smb_mid));
return NT_STATUS_OK;
}
@@ -325,7 +329,8 @@ void remove_pending_change_notify_requests_by_mid(uint16 mid)
return;
}
- change_notify_reply_packet(map->req->request_buf, NT_STATUS_CANCELLED);
+ change_notify_reply_packet(map->req->fsp->conn,
+ map->req->request_buf, NT_STATUS_CANCELLED);
change_notify_remove_request(map->req);
}
@@ -341,7 +346,7 @@ void remove_pending_change_notify_requests_by_fid(files_struct *fsp,
}
while (fsp->notify->requests != NULL) {
- change_notify_reply_packet(
+ change_notify_reply_packet(fsp->conn,
fsp->notify->requests->request_buf, status);
change_notify_remove_request(fsp->notify->requests);
}
@@ -435,7 +440,8 @@ static void notify_fsp(files_struct *fsp, uint32 action, const char *name)
* TODO: do we have to walk the lists of requests pending?
*/
- change_notify_reply(fsp->notify->requests->request_buf,
+ change_notify_reply(fsp->conn,
+ fsp->notify->requests->request_buf,
fsp->notify->requests->max_param,
fsp->notify);
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 69772b6bec..8ac0217dcd 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -66,7 +66,8 @@ static char *nttrans_realloc(char **ptr, size_t size)
HACK ! Always assumes smb_setup field is zero.
****************************************************************************/
-void send_nt_replies(struct smb_request *req, NTSTATUS nt_error,
+void send_nt_replies(connection_struct *conn,
+ struct smb_request *req, NTSTATUS nt_error,
char *params, int paramsize,
char *pdata, int datasize)
{
@@ -242,8 +243,10 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error,
/* Send the packet */
show_msg((char *)req->outbuf);
- if (!send_smb(smbd_server_fd(),(char *)req->outbuf)) {
- exit_server_cleanly("send_nt_replies: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(conn))) {
+ exit_server_cleanly("send_nt_replies: srv_send_smb failed.");
}
TALLOC_FREE(req->outbuf);
@@ -726,7 +729,7 @@ static void do_nt_transact_create_pipe(connection_struct *conn,
DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
/* Send the required number of replies */
- send_nt_replies(req, NT_STATUS_OK, params, param_len, *ppdata, 0);
+ send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
return;
}
@@ -1080,7 +1083,7 @@ static void call_nt_transact_create(connection_struct *conn,
DEBUG(5,("call_nt_transact_create: open name = %s\n", fname));
/* Send the required number of replies */
- send_nt_replies(req, NT_STATUS_OK, params, param_len, *ppdata, 0);
+ send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
return;
}
@@ -1474,7 +1477,7 @@ static void call_nt_transact_notify_change(connection_struct *conn,
* here.
*/
- change_notify_reply(req->inbuf, max_param_count, fsp->notify);
+ change_notify_reply(fsp->conn, req->inbuf, max_param_count, fsp->notify);
/*
* change_notify_reply() above has independently sent its
@@ -1487,7 +1490,9 @@ static void call_nt_transact_notify_change(connection_struct *conn,
* No changes pending, queue the request
*/
- status = change_notify_add_request(req->inbuf, max_param_count, filter,
+ status = change_notify_add_request(req,
+ max_param_count,
+ filter,
recursive, fsp);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@@ -1554,7 +1559,7 @@ static void call_nt_transact_rename(connection_struct *conn,
/*
* Rename was successful.
*/
- send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0);
+ send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n",
fsp->fsp_name, new_name));
@@ -1657,7 +1662,7 @@ static void call_nt_transact_query_security_desc(connection_struct *conn,
SIVAL(params,0,(uint32)sd_size);
if (max_data_count < sd_size) {
- send_nt_replies(req, NT_STATUS_BUFFER_TOO_SMALL,
+ send_nt_replies(conn, req, NT_STATUS_BUFFER_TOO_SMALL,
params, 4, *ppdata, 0);
TALLOC_FREE(frame);
return;
@@ -1686,7 +1691,7 @@ static void call_nt_transact_query_security_desc(connection_struct *conn,
SMB_ASSERT(sd_size == blob.length);
memcpy(data, blob.data, sd_size);
- send_nt_replies(req, NT_STATUS_OK, params, 4, data, (int)sd_size);
+ send_nt_replies(conn, req, NT_STATUS_OK, params, 4, data, (int)sd_size);
TALLOC_FREE(frame);
return;
@@ -1744,7 +1749,7 @@ static void call_nt_transact_set_security_desc(connection_struct *conn,
}
done:
- send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0);
+ send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
return;
}
@@ -1793,7 +1798,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
so we can know if we need to pre-allocate or not */
DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum));
- send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0);
+ send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
return;
case FSCTL_CREATE_OR_GET_OBJECT_ID:
@@ -1819,7 +1824,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
push_file_id_16(pdata, &fsp->file_id);
memcpy(pdata+16,create_volume_objectid(conn,objid),16);
push_file_id_16(pdata+32, &fsp->file_id);
- send_nt_replies(req, NT_STATUS_OK, NULL, 0,
+ send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0,
pdata, data_count);
return;
}
@@ -1964,7 +1969,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
talloc_destroy(shadow_data->mem_ctx);
- send_nt_replies(req, NT_STATUS_OK, NULL, 0,
+ send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0,
pdata, data_count);
return;
@@ -2020,7 +2025,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
*/
/* this works for now... */
- send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0);
+ send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
return;
}
default:
@@ -2306,7 +2311,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn,
break;
}
- send_nt_replies(req, nt_status, params, param_len,
+ send_nt_replies(conn, req, nt_status, params, param_len,
pdata, data_len);
}
@@ -2436,7 +2441,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn,
return;
}
- send_nt_replies(req, NT_STATUS_OK, params, param_len,
+ send_nt_replies(conn, req, NT_STATUS_OK, params, param_len,
pdata, data_len);
}
#endif /* HAVE_SYS_QUOTAS */
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index b6e6adde8a..e3fae02b83 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -2267,7 +2267,7 @@ NTSTATUS open_directory(connection_struct *conn,
return NT_STATUS_OK;
}
-NTSTATUS create_directory(connection_struct *conn, const char *directory)
+NTSTATUS create_directory(connection_struct *conn, struct smb_request *req, const char *directory)
{
NTSTATUS status;
SMB_STRUCT_STAT sbuf;
@@ -2275,7 +2275,7 @@ NTSTATUS create_directory(connection_struct *conn, const char *directory)
SET_STAT_INVALID(sbuf);
- status = open_directory(conn, NULL, directory, &sbuf,
+ status = open_directory(conn, req, directory, &sbuf,
FILE_READ_ATTRIBUTES, /* Just a stat open */
FILE_SHARE_NONE, /* Ignored for stat opens */
FILE_CREATE,
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index 8a5b1f4ecd..277e07c178 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -252,13 +252,7 @@ static char *new_break_smb_message(TALLOC_CTX *mem_ctx,
}
memset(result,'\0',smb_size);
- if (!srv_encryption_on()) {
- cli_set_message(result,8,0,true);
- } else {
- char inbuf[8];
- smb_set_enclen(inbuf,4,srv_enc_ctx());
- srv_set_message(inbuf,result,8,0,true);
- }
+ srv_set_message(result,8,0,true);
SCVAL(result,smb_com,SMBlockingX);
SSVAL(result,smb_tid,fsp->conn->cnum);
SSVAL(result,smb_pid,0xFFFF);
@@ -455,8 +449,10 @@ static void process_oplock_async_level2_break_message(struct messaging_context *
sign_state = srv_oplock_set_signing(False);
show_msg(break_msg);
- if (!send_smb(smbd_server_fd(), break_msg)) {
- exit_server_cleanly("oplock_break: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ break_msg,
+ IS_CONN_ENCRYPTED(fsp->conn))) {
+ exit_server_cleanly("oplock_break: srv_send_smb failed.");
}
/* Restore the sign state to what it was. */
@@ -560,8 +556,10 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
sign_state = srv_oplock_set_signing(False);
show_msg(break_msg);
- if (!send_smb(smbd_server_fd(), break_msg)) {
- exit_server_cleanly("oplock_break: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ break_msg,
+ IS_CONN_ENCRYPTED(fsp->conn))) {
+ exit_server_cleanly("oplock_break: srv_send_smb failed.");
}
/* Restore the sign state to what it was. */
@@ -637,8 +635,10 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx,
sign_state = srv_oplock_set_signing(False);
show_msg(break_msg);
- if (!send_smb(smbd_server_fd(), break_msg)) {
- exit_server_cleanly("oplock_break: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ break_msg,
+ IS_CONN_ENCRYPTED(fsp->conn))) {
+ exit_server_cleanly("oplock_break: srv_send_smb failed.");
}
/* Restore the sign state to what it was. */
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index 88b67c03e5..6b4b83d97d 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -291,8 +291,7 @@ void reply_pipe_read_and_X(struct smb_request *req)
return;
}
- srv_set_message((const char *)req->inbuf,
- (char *)req->outbuf, 12, nread, False);
+ srv_set_message((char *)req->outbuf, 12, nread, False);
SSVAL(req->outbuf,smb_vwv5,nread);
SSVAL(req->outbuf,smb_vwv6,smb_offset(data,req->outbuf));
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 48a6d18bc9..32d1d058e3 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -50,14 +50,52 @@ enum smb_read_errors *get_srv_read_error(void)
return &smb_read_error;
}
+/****************************************************************************
+ Send an smb to a fd.
+****************************************************************************/
+
+bool srv_send_smb(int fd, char *buffer, bool do_encrypt)
+{
+ size_t len;
+ size_t nwritten=0;
+ ssize_t ret;
+ char *buf_out = buffer;
+
+ /* Sign the outgoing packet if required. */
+ srv_calculate_sign_mac(buf_out);
+
+ if (do_encrypt) {
+ NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("send_smb: SMB encryption failed "
+ "on outgoing packet! Error %s\n",
+ nt_errstr(status) ));
+ return false;
+ }
+ }
+
+ len = smb_len(buf_out) + 4;
+
+ while (nwritten < len) {
+ ret = write_data(fd,buf_out+nwritten,len - nwritten);
+ if (ret <= 0) {
+ DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
+ (int)len,(int)ret, strerror(errno) ));
+ srv_free_enc_buffer(buf_out);
+ return false;
+ }
+ nwritten += ret;
+ }
+
+ srv_free_enc_buffer(buf_out);
+ return true;
+}
+
/*******************************************************************
Setup the word count and byte count for a smb message.
- copying the '0xFF X X X' bytes from incoming
- buffer (so we copy any encryption context).
********************************************************************/
-int srv_set_message(const char *frombuf,
- char *buf,
+int srv_set_message(char *buf,
int num_words,
int num_bytes,
bool zero)
@@ -67,22 +105,14 @@ int srv_set_message(const char *frombuf,
}
SCVAL(buf,smb_wct,num_words);
SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
- _smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
- if (buf != frombuf) {
- memcpy(buf+4, frombuf+4, 4);
- }
+ smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
return (smb_size + num_words*2 + num_bytes);
}
-static bool valid_smb_header(const char *inbuf)
+static bool valid_smb_header(const uint8_t *inbuf)
{
- if (srv_encryption_on()) {
- uint16_t enc_num;
- NTSTATUS status = get_enc_ctx_num(inbuf, &enc_num);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
- }
- return (enc_num == 0);
+ if (is_encrypted_packet(inbuf)) {
+ return true;
}
return (strncmp(smb_base(inbuf),"\377SMB",4) == 0);
}
@@ -162,7 +192,7 @@ static ssize_t read_packet_remainder(int fd,
(2*14) + /* word count (including bcc) */ \
1 /* pad byte */)
-ssize_t receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
+static ssize_t receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
const char lenbuf[4],
int fd,
char **buffer,
@@ -202,7 +232,7 @@ ssize_t receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
* valid writeX call.
*/
- if (is_valid_writeX_buffer(writeX_header)) {
+ if (is_valid_writeX_buffer((uint8_t *)writeX_header)) {
/*
* If the data offset is beyond what
* we've read, drain the extra bytes.
@@ -310,7 +340,7 @@ static ssize_t receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
return -1;
}
- if (CVAL(lenbuf,0) != SMBkeepalive &&
+ if (CVAL(lenbuf,0) == 0 &&
min_recv_size &&
smb_len_large(lenbuf) > min_recv_size && /* Could be a UNIX large writeX. */
!srv_is_signing_active()) {
@@ -350,18 +380,24 @@ static ssize_t receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
return len + 4;
}
-ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer,
- unsigned int timeout, size_t *p_unread)
+static ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx,
+ int fd,
+ char **buffer,
+ unsigned int timeout,
+ size_t *p_unread,
+ bool *p_encrypted)
{
ssize_t len;
+ *p_encrypted = false;
+
len = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout, p_unread);
if (len < 0) {
return -1;
}
- if (srv_encryption_on()) {
+ if (is_encrypted_packet((uint8_t *)*buffer)) {
NTSTATUS status = srv_decrypt_buffer(*buffer);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
@@ -371,6 +407,7 @@ ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer,
SMB_READ_BAD_DECRYPT);
return -1;
}
+ *p_encrypted = true;
}
/* Check the incoming SMB signature. */
@@ -390,7 +427,8 @@ ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer,
void init_smb_request(struct smb_request *req,
const uint8 *inbuf,
- size_t unread_bytes)
+ size_t unread_bytes,
+ bool encrypted)
{
size_t req_size = smb_len(inbuf) + 4;
/* Ensure we have at least smb_size bytes. */
@@ -406,6 +444,8 @@ void init_smb_request(struct smb_request *req,
req->tid = SVAL(inbuf, smb_tid);
req->wct = CVAL(inbuf, smb_wct);
req->unread_bytes = unread_bytes;
+ req->encrypted = encrypted;
+ req->conn = conn_find(req->tid);
/* Ensure we have at least wct words and 2 bytes of bcc. */
if (smb_size + req->wct*2 > req_size) {
@@ -463,6 +503,7 @@ static bool push_queued_message(struct smb_request *req,
msg->request_time = request_time;
msg->end_time = end_time;
+ msg->encrypted = req->encrypted;
if (private_data) {
msg->private_data = data_blob_talloc(msg, private_data,
@@ -738,7 +779,8 @@ static bool receive_message_or_smb(TALLOC_CTX *mem_ctx,
char **buffer,
size_t *buffer_len,
int timeout,
- size_t *p_unread)
+ size_t *p_unread,
+ bool *p_encrypted)
{
fd_set r_fds, w_fds;
int selrtn;
@@ -805,6 +847,7 @@ static bool receive_message_or_smb(TALLOC_CTX *mem_ctx,
return False;
}
*buffer_len = msg->buf.length;
+ *p_encrypted = msg->encrypted;
/* We leave this message on the queue so the open code can
know this is a retry. */
@@ -921,7 +964,8 @@ static bool receive_message_or_smb(TALLOC_CTX *mem_ctx,
goto again;
}
- len = receive_smb_talloc(mem_ctx, smbd_server_fd(), buffer, 0, p_unread);
+ len = receive_smb_talloc(mem_ctx, smbd_server_fd(),
+ buffer, 0, p_unread, p_encrypted);
if (len == -1) {
return False;
@@ -1288,8 +1332,7 @@ void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
}
construct_reply_common((char *)req->inbuf, (char *)req->outbuf);
- srv_set_message((const char *)req->inbuf,
- (char *)req->outbuf, num_words, num_bytes, false);
+ srv_set_message((char *)req->outbuf, num_words, num_bytes, false);
/*
* Zero out the word area, the caller has to take care of the bcc area
* himself
@@ -1347,11 +1390,11 @@ static void smb_dump(const char *name, int type, const char *data, ssize_t len)
find.
****************************************************************************/
-static void switch_message(uint8 type, struct smb_request *req, int size)
+static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
{
int flags;
uint16 session_tag;
- connection_struct *conn;
+ connection_struct *conn = NULL;
static uint16 last_session_tag = UID_FIELD_INVALID;
@@ -1359,7 +1402,7 @@ static void switch_message(uint8 type, struct smb_request *req, int size)
/* Make sure this is an SMB packet. smb_size contains NetBIOS header
* so subtract 4 from it. */
- if (!valid_smb_header((const char *)req->inbuf)
+ if (!valid_smb_header(req->inbuf)
|| (size < (smb_size - 4))) {
DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
smb_len(req->inbuf)));
@@ -1370,7 +1413,7 @@ static void switch_message(uint8 type, struct smb_request *req, int size)
DEBUG(0,("Unknown message type %d!\n",type));
smb_dump("Unknown", 1, (char *)req->inbuf, size);
reply_unknown_new(req, type);
- return;
+ return NULL;
}
flags = smb_messages[type].flags;
@@ -1378,7 +1421,7 @@ static void switch_message(uint8 type, struct smb_request *req, int size)
/* In share mode security we must ignore the vuid. */
session_tag = (lp_security() == SEC_SHARE)
? UID_FIELD_INVALID : req->vuid;
- conn = conn_find(req->tid);
+ conn = req->conn;
DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
(int)sys_getpid(), (unsigned long)conn));
@@ -1423,12 +1466,12 @@ static void switch_message(uint8 type, struct smb_request *req, int size)
} else {
reply_doserror(req, ERRSRV, ERRinvnid);
}
- return;
+ return NULL;
}
if (!change_to_user(conn,session_tag)) {
reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
- return;
+ return conn;
}
/* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
@@ -1436,13 +1479,13 @@ static void switch_message(uint8 type, struct smb_request *req, int size)
/* Does it need write permission? */
if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
- return;
+ return conn;
}
/* IPC services are limited */
if (IS_IPC(conn) && !(flags & CAN_IPC)) {
reply_doserror(req, ERRSRV,ERRaccess);
- return;
+ return conn;
}
} else {
/* This call needs to be run as root */
@@ -1451,21 +1494,24 @@ static void switch_message(uint8 type, struct smb_request *req, int size)
/* load service specific parameters */
if (conn) {
+ if (req->encrypted) {
+ conn->encrypted_tid = true;
+ /* encrypted required from now on. */
+ conn->encrypt_level = Required;
+ } else if (ENCRYPTION_REQUIRED(conn)) {
+ uint8 com = CVAL(req->inbuf,smb_com);
+ if (com != SMBtrans2 && com != SMBtranss2) {
+ exit_server_cleanly("encryption required "
+ "on connection");
+ return conn;
+ }
+ }
+
if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
(flags & (AS_USER|DO_CHDIR)
?True:False))) {
reply_doserror(req, ERRSRV, ERRaccess);
- return;
- }
-
- if (conn->encrypt_level == Required && SVAL(req->inbuf,4) != 0x45FF ) {
- /* An encrypted packet has 0xFF 'E' at offset 4
- * which is little endian 0x45FF */
- uint8 com = CVAL(req->inbuf,smb_com);
- if (com != SMBtrans2 && com != SMBtranss2) {
- reply_nterror(req, NT_STATUS_ACCESS_DENIED);
- return;
- }
+ return conn;
}
conn->num_smb_operations++;
}
@@ -1476,19 +1522,21 @@ static void switch_message(uint8 type, struct smb_request *req, int size)
!check_access(smbd_server_fd(), lp_hostsallow(-1),
lp_hostsdeny(-1)))) {
reply_doserror(req, ERRSRV, ERRaccess);
- return;
+ return conn;
}
smb_messages[type].fn_new(conn, req);
+ return req->conn;
}
/****************************************************************************
Construct a reply to the incoming packet.
****************************************************************************/
-static void construct_reply(char *inbuf, int size, size_t unread_bytes)
+static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool encrypted)
{
uint8 type = CVAL(inbuf,smb_com);
+ connection_struct *conn;
struct smb_request *req;
chain_size = 0;
@@ -1498,9 +1546,9 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes)
if (!(req = talloc(talloc_tos(), struct smb_request))) {
smb_panic("could not allocate smb_request");
}
- init_smb_request(req, (uint8 *)inbuf, unread_bytes);
+ init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
- switch_message(type, req, size);
+ conn = switch_message(type, req, size);
if (req->unread_bytes) {
/* writeX failed. drain socket. */
@@ -1519,8 +1567,10 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes)
show_msg((char *)req->outbuf);
}
- if (!send_smb(smbd_server_fd(), (char *)req->outbuf)) {
- exit_server_cleanly("construct_reply: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(conn)||req->encrypted)) {
+ exit_server_cleanly("construct_reply: srv_send_smb failed.");
}
TALLOC_FREE(req);
@@ -1532,7 +1582,7 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes)
Process an smb from the client
****************************************************************************/
-static void process_smb(char *inbuf, size_t nread, size_t unread_bytes)
+static void process_smb(char *inbuf, size_t nread, size_t unread_bytes, bool encrypted)
{
static int trans_num;
int msg_type = CVAL(inbuf,0);
@@ -1553,7 +1603,7 @@ static void process_smb(char *inbuf, size_t nread, size_t unread_bytes)
static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
DEBUG( 1, ( "Connection denied from %s\n",
client_addr(get_client_fd(),addr,sizeof(addr)) ) );
- (void)send_smb(smbd_server_fd(),(char *)buf);
+ (void)srv_send_smb(smbd_server_fd(),(char *)buf,false);
exit_server_cleanly("connection denied");
}
}
@@ -1574,7 +1624,7 @@ static void process_smb(char *inbuf, size_t nread, size_t unread_bytes)
show_msg(inbuf);
- construct_reply(inbuf,nread,unread_bytes);
+ construct_reply(inbuf,nread,unread_bytes,encrypted);
trans_num++;
}
@@ -1611,7 +1661,7 @@ void remove_from_common_flags2(uint32 v)
void construct_reply_common(const char *inbuf, char *outbuf)
{
- srv_set_message(inbuf,outbuf,0,0,false);
+ srv_set_message(outbuf,0,0,false);
SCVAL(outbuf,smb_com,CVAL(inbuf,smb_com));
SIVAL(outbuf,smb_rcls,0);
@@ -1734,7 +1784,7 @@ void chain_reply(struct smb_request *req)
if (!(req2 = talloc(talloc_tos(), struct smb_request))) {
smb_panic("could not allocate smb_request");
}
- init_smb_request(req2, (uint8 *)inbuf2,0);
+ init_smb_request(req2, (uint8 *)inbuf2,0, req->encrypted);
/* process the request */
switch_message(smb_com2, req2, new_size);
@@ -2020,6 +2070,7 @@ void smbd_process(void)
int num_echos;
char *inbuf;
size_t inbuf_len;
+ bool encrypted = false;
TALLOC_CTX *frame = talloc_stackframe();
errno = 0;
@@ -2035,7 +2086,9 @@ void smbd_process(void)
run_events(smbd_event_context(), 0, NULL, NULL);
while (!receive_message_or_smb(NULL, &inbuf, &inbuf_len,
- select_timeout, &unread_bytes)) {
+ select_timeout,
+ &unread_bytes,
+ &encrypted)) {
if(!timeout_processing(&select_timeout,
&last_timeout_processing_time))
return;
@@ -2054,7 +2107,7 @@ void smbd_process(void)
*/
num_echos = smb_echo_count;
- process_smb(inbuf, inbuf_len, unread_bytes);
+ process_smb(inbuf, inbuf_len, unread_bytes, encrypted);
TALLOC_FREE(inbuf);
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index c859efd370..b6efccdb15 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -391,7 +391,7 @@ void reply_special(char *inbuf)
/*
* We only really use 4 bytes of the outbuf, but for the smb_setlen
- * calculation & friends (send_smb uses that) we need the full smb
+ * calculation & friends (srv_send_smb uses that) we need the full smb
* header.
*/
char outbuf[smb_size];
@@ -470,7 +470,7 @@ void reply_special(char *inbuf)
DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
msg_type, msg_flags));
- send_smb(smbd_server_fd(), outbuf);
+ srv_send_smb(smbd_server_fd(), outbuf, false);
return;
}
@@ -523,6 +523,7 @@ void reply_tcon(connection_struct *conn, struct smb_request *req)
password_blob = data_blob(password, pwlen+1);
conn = make_connection(service,password_blob,dev,req->vuid,&nt_status);
+ req->conn = conn;
data_blob_clear_free(&password_blob);
@@ -578,6 +579,7 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
/* we might have to close an old one */
if ((tcon_flags & 0x1) && conn) {
close_cnum(conn,req->vuid);
+ req->conn = NULL;
}
if ((passlen > MAX_PASS_LEN) || (passlen >= smb_buflen(req->inbuf))) {
@@ -646,6 +648,7 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
conn = make_connection(service, password, client_devicetype,
req->vuid, &nt_status);
+ req->conn =conn;
data_blob_clear_free(&password);
@@ -2725,7 +2728,7 @@ void reply_readbraw(connection_struct *conn, struct smb_request *req)
START_PROFILE(SMBreadbraw);
- if (srv_is_signing_active() || srv_encryption_on()) {
+ if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - "
"raw reads/writes are disallowed.");
}
@@ -2951,8 +2954,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
return;
}
- srv_set_message((const char *)req->inbuf,
- (char *)req->outbuf, 5, nread+3, False);
+ srv_set_message((char *)req->outbuf, 5, nread+3, False);
SSVAL(req->outbuf,smb_vwv0,nread);
SSVAL(req->outbuf,smb_vwv5,nread+3);
@@ -3039,8 +3041,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
return;
}
- srv_set_message((const char *)req->inbuf,
- (char *)req->outbuf, 5, nread+3, False);
+ srv_set_message((char *)req->outbuf, 5, nread+3, False);
SSVAL(req->outbuf,smb_vwv0,nread);
SSVAL(req->outbuf,smb_vwv5,nread+3);
@@ -3058,12 +3059,12 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
Setup readX header.
****************************************************************************/
-static int setup_readX_header(const char *inbuf, char *outbuf, size_t smb_maxcnt)
+static int setup_readX_header(char *outbuf, size_t smb_maxcnt)
{
int outsize;
char *data;
- outsize = srv_set_message(inbuf, outbuf,12,smb_maxcnt,False);
+ outsize = srv_set_message(outbuf,12,smb_maxcnt,False);
data = smb_buf(outbuf);
memset(outbuf+smb_vwv0,'\0',24); /* valgrind init. */
@@ -3113,6 +3114,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
*/
if ((chain_size == 0) && (CVAL(req->inbuf,smb_vwv0) == 0xFF) &&
+ !is_encrypted_packet(req->inbuf) &&
lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
uint8 headerbuf[smb_size + 12 * 2];
DATA_BLOB header;
@@ -3126,8 +3128,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
header = data_blob_const(headerbuf, sizeof(headerbuf));
construct_reply_common((char *)req->inbuf, (char *)headerbuf);
- setup_readX_header((const char *)req->inbuf,
- (char *)headerbuf, smb_maxcnt);
+ setup_readX_header((char *)headerbuf, smb_maxcnt);
if ((nread = SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, smb_maxcnt)) == -1) {
/* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
@@ -3178,8 +3179,7 @@ normal_read:
uint8 headerbuf[smb_size + 2*12];
construct_reply_common((char *)req->inbuf, (char *)headerbuf);
- setup_readX_header((const char *)req->inbuf,
- (char *)headerbuf, smb_maxcnt);
+ setup_readX_header((char *)headerbuf, smb_maxcnt);
/* Send out the header. */
if (write_data(smbd_server_fd(), (char *)headerbuf,
@@ -3206,8 +3206,7 @@ normal_read:
return;
}
- setup_readX_header((const char *)req->inbuf,
- (char *)req->outbuf, nread);
+ setup_readX_header((char *)req->outbuf, nread);
DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
@@ -3272,7 +3271,7 @@ void reply_read_and_X(connection_struct *conn, struct smb_request *req)
return;
}
/* We currently don't do this on signed or sealed data. */
- if (srv_is_signing_active() || srv_encryption_on()) {
+ if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
END_PROFILE(SMBreadX);
return;
@@ -3463,13 +3462,15 @@ void reply_writebraw(connection_struct *conn, struct smb_request *req)
* it to send more bytes */
memcpy(buf, req->inbuf, smb_size);
- outsize = srv_set_message((const char *)req->inbuf, buf,
+ outsize = srv_set_message(buf,
Protocol>PROTOCOL_COREPLUS?1:0,0,True);
SCVAL(buf,smb_com,SMBwritebraw);
SSVALS(buf,smb_vwv0,0xFFFF);
show_msg(buf);
- if (!send_smb(smbd_server_fd(),buf)) {
- exit_server_cleanly("reply_writebraw: send_smb "
+ if (!srv_send_smb(smbd_server_fd(),
+ buf,
+ IS_CONN_ENCRYPTED(conn))) {
+ exit_server_cleanly("reply_writebraw: srv_send_smb "
"failed.");
}
@@ -3788,14 +3789,14 @@ void reply_write(connection_struct *conn, struct smb_request *req)
(2*14) + /* word count (including bcc) */ \
1 /* pad byte */)
-bool is_valid_writeX_buffer(const char *inbuf)
+bool is_valid_writeX_buffer(const uint8_t *inbuf)
{
size_t numtowrite;
connection_struct *conn = NULL;
unsigned int doff = 0;
size_t len = smb_len_large(inbuf);
- if (srv_encryption_on()) {
+ if (is_encrypted_packet(inbuf)) {
/* Can't do this on encrypted
* connections. */
return false;
@@ -4476,6 +4477,7 @@ void reply_tdis(connection_struct *conn, struct smb_request *req)
conn->used = False;
close_cnum(conn,req->vuid);
+ req->conn = NULL;
reply_outbuf(req, 0, 0);
END_PROFILE(SMBtdis);
@@ -4526,8 +4528,10 @@ void reply_echo(connection_struct *conn, struct smb_request *req)
SSVAL(req->outbuf,smb_vwv0,seq_num);
show_msg((char *)req->outbuf);
- if (!send_smb(smbd_server_fd(),(char *)req->outbuf))
- exit_server_cleanly("reply_echo: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(conn)||req->encrypted))
+ exit_server_cleanly("reply_echo: srv_send_smb failed.");
}
DEBUG(3,("echo %d times\n", smb_reverb));
@@ -4830,7 +4834,7 @@ void reply_mkdir(connection_struct *conn, struct smb_request *req)
return;
}
- status = create_directory(conn, directory);
+ status = create_directory(conn, req, directory);
DEBUG(5, ("create_directory returned %s\n", nt_errstr(status)));
@@ -6803,8 +6807,7 @@ void reply_lockingX(connection_struct *conn, struct smb_request *req)
* onto the blocking lock queue.
*/
if(push_blocking_lock_request(br_lck,
- (char *)req->inbuf,
- smb_len(req->inbuf)+4,
+ req,
fsp,
lock_timeout,
i,
diff --git a/source3/smbd/seal.c b/source3/smbd/seal.c
index 24ecb77fd5..21fca73fea 100644
--- a/source3/smbd/seal.c
+++ b/source3/smbd/seal.c
@@ -36,24 +36,37 @@ static struct smb_srv_trans_enc_ctx *partial_srv_trans_enc_ctx;
static struct smb_srv_trans_enc_ctx *srv_trans_enc_ctx;
/******************************************************************************
- Is server encryption on ?
+ Return global enc context - this must change if we ever do multiple contexts.
******************************************************************************/
-bool srv_encryption_on(void)
+uint16_t srv_enc_ctx(void)
{
- if (srv_trans_enc_ctx) {
- return common_encryption_on(srv_trans_enc_ctx->es);
- }
- return false;
+ return srv_trans_enc_ctx->es->enc_ctx_num;
}
/******************************************************************************
- Return global enc context - this must change if we ever do multiple contexts.
+ Is this an incoming encrypted packet ?
******************************************************************************/
-uint16 srv_enc_ctx(void)
+bool is_encrypted_packet(const uint8_t *inbuf)
{
- return srv_trans_enc_ctx->es->enc_ctx_num;
+ NTSTATUS status;
+ uint16_t enc_num;
+
+ /* Ignore non-session messages. */
+ if(CVAL(inbuf,0)) {
+ return false;
+ }
+
+ status = get_enc_ctx_num(inbuf, &enc_num);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ if (srv_trans_enc_ctx && enc_num == srv_enc_ctx()) {
+ return true;
+ }
+ return false;
}
/******************************************************************************
@@ -292,9 +305,9 @@ void srv_free_enc_buffer(char *buf)
{
/* We know this is an smb buffer, and we
* didn't malloc, only copy, for a keepalive,
- * so ignore session keepalives. */
+ * so ignore non-session messages. */
- if(CVAL(buf,0) == SMBkeepalive) {
+ if(CVAL(buf,0)) {
return;
}
@@ -309,8 +322,8 @@ void srv_free_enc_buffer(char *buf)
NTSTATUS srv_decrypt_buffer(char *buf)
{
- /* Ignore session keepalives. */
- if(CVAL(buf,0) == SMBkeepalive) {
+ /* Ignore non-session messages. */
+ if(CVAL(buf,0)) {
return NT_STATUS_OK;
}
@@ -329,8 +342,8 @@ NTSTATUS srv_encrypt_buffer(char *buf, char **buf_out)
{
*buf_out = buf;
- /* Ignore session keepalives. */
- if(CVAL(buf,0) == SMBkeepalive) {
+ /* Ignore non-session messages. */
+ if(CVAL(buf,0)) {
return NT_STATUS_OK;
}
@@ -698,6 +711,7 @@ NTSTATUS srv_encryption_start(connection_struct *conn)
srv_trans_enc_ctx->es->enc_on = true;
partial_srv_trans_enc_ctx = NULL;
+
return NT_STATUS_OK;
}
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 8ca012ff24..e44a540554 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -139,7 +139,7 @@ static void reply_sesssetup_blob(connection_struct *conn,
}
show_msg((char *)req->outbuf);
- send_smb(smbd_server_fd(),(char *)req->outbuf);
+ srv_send_smb(smbd_server_fd(),(char *)req->outbuf,req->encrypted);
TALLOC_FREE(req->outbuf);
}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index eba8cb50f0..1e421a70b6 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -575,7 +575,8 @@ static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *
HACK ! Always assumes smb_setup field is zero.
****************************************************************************/
-void send_trans2_replies(struct smb_request *req,
+void send_trans2_replies(connection_struct *conn,
+ struct smb_request *req,
const char *params,
int paramsize,
const char *pdata,
@@ -737,8 +738,10 @@ void send_trans2_replies(struct smb_request *req,
/* Send the packet */
show_msg((char *)req->outbuf);
- if (!send_smb(smbd_server_fd(),(char *)req->outbuf))
- exit_server_cleanly("send_trans2_replies: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(conn)))
+ exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
TALLOC_FREE(req->outbuf);
@@ -956,7 +959,7 @@ static void call_trans2open(connection_struct *conn,
}
/* Send the required number of replies */
- send_trans2_replies(req, params, 30, *ppdata, 0, max_data_bytes);
+ send_trans2_replies(conn, req, params, 30, *ppdata, 0, max_data_bytes);
}
/*********************************************************
@@ -2026,7 +2029,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
SSVAL(params,6,0); /* Never an EA error */
SSVAL(params,8,last_entry_off);
- send_trans2_replies(req, params, 10, pdata, PTR_DIFF(p,pdata),
+ send_trans2_replies(conn, req, params, 10, pdata, PTR_DIFF(p,pdata),
max_data_bytes);
if ((! *directory) && dptr_path(dptr_num)) {
@@ -2350,7 +2353,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
SSVAL(params,4,0); /* Never an EA error */
SSVAL(params,6,last_entry_off);
- send_trans2_replies(req, params, 8, pdata, PTR_DIFF(p,pdata),
+ send_trans2_replies(conn, req, params, 8, pdata, PTR_DIFF(p,pdata),
max_data_bytes);
return;
@@ -2389,13 +2392,23 @@ static void call_trans2qfsinfo(connection_struct *conn,
info_level = SVAL(params,0);
- if (IS_IPC(conn) ||
- (conn->encrypt_level == Required && SVAL(req->inbuf,4) != 0x45FF )) {
+ if (IS_IPC(conn)) {
+ if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
+ DEBUG(0,("call_trans2qfsinfo: not an allowed "
+ "info level (0x%x) on IPC$.\n",
+ (unsigned int)info_level));
+ reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return;
+ }
+ }
+
+ if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
DEBUG(0,("call_trans2qfsinfo: encryption required "
"and info level 0x%x sent.\n",
(unsigned int)info_level));
- reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+ exit_server_cleanly("encryption required "
+ "on connection");
return;
}
}
@@ -2906,7 +2919,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
}
- send_trans2_replies(req, params, 0, pdata, data_len,
+ send_trans2_replies(conn, req, params, 0, pdata, data_len,
max_data_bytes);
DEBUG( 4, ( "%s info_level = %d\n",
@@ -2952,12 +2965,13 @@ static void call_trans2setfsinfo(connection_struct *conn,
}
}
- if (conn->encrypt_level == Required && SVAL(req->inbuf,4) != 0x45FF ) {
+ if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION) {
DEBUG(0,("call_trans2setfsinfo: encryption required "
"and info level 0x%x sent.\n",
(unsigned int)info_level));
- reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+ exit_server_cleanly("encryption required "
+ "on connection");
return;
}
}
@@ -3048,7 +3062,7 @@ cap_low = 0x%x, cap_high = 0x%x\n",
return;
}
- send_trans2_replies(req,
+ send_trans2_replies(conn, req,
*pparams,
param_len,
*ppdata,
@@ -3524,7 +3538,7 @@ static void call_trans2qpipeinfo(connection_struct *conn,
return;
}
- send_trans2_replies(req, params, param_size, *ppdata, data_size,
+ send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
max_data_bytes);
return;
@@ -4456,7 +4470,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
return;
}
- send_trans2_replies(req, params, param_size, *ppdata, data_size,
+ send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
max_data_bytes);
return;
@@ -5160,8 +5174,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn,
****************************************************************************/
static NTSTATUS smb_set_posix_lock(connection_struct *conn,
- const uint8 *inbuf,
- int length,
+ const struct smb_request *req,
const char *pdata,
int total_data,
files_struct *fsp)
@@ -5171,6 +5184,7 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn,
uint32 lock_pid;
bool blocking_lock = False;
enum brl_type lock_type;
+
NTSTATUS status = NT_STATUS_OK;
if (fsp == NULL || fsp->fh->fd == -1) {
@@ -5258,7 +5272,7 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn,
* onto the blocking lock queue.
*/
if(push_blocking_lock_request(br_lck,
- (char *)inbuf, length,
+ req,
fsp,
-1, /* infinite timeout. */
0,
@@ -6316,7 +6330,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
SSVAL(params,0,0);
- send_trans2_replies(req, params, 2,
+ send_trans2_replies(conn, req, params, 2,
*ppdata, 0,
max_data_bytes);
return;
@@ -6606,8 +6620,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
return;
}
- status = smb_set_posix_lock(conn, req->inbuf,
- smb_len(req->inbuf) + 4,
+ status = smb_set_posix_lock(conn, req,
pdata, total_data, fsp);
break;
}
@@ -6675,7 +6688,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
}
SSVAL(params,0,0);
- send_trans2_replies(req, params, 2, *ppdata, data_return_size,
+ send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size,
max_data_bytes);
return;
@@ -6767,7 +6780,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
return;
}
- status = create_directory(conn, directory);
+ status = create_directory(conn, req, directory);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@@ -6793,7 +6806,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
SSVAL(params,0,0);
- send_trans2_replies(req, params, 2, *ppdata, 0, max_data_bytes);
+ send_trans2_replies(conn, req, params, 2, *ppdata, 0, max_data_bytes);
return;
}
@@ -6847,7 +6860,7 @@ static void call_trans2findnotifyfirst(connection_struct *conn,
if(fnf_handle == 0)
fnf_handle = 257;
- send_trans2_replies(req, params, 6, *ppdata, 0, max_data_bytes);
+ send_trans2_replies(conn, req, params, 6, *ppdata, 0, max_data_bytes);
return;
}
@@ -6878,7 +6891,7 @@ static void call_trans2findnotifynext(connection_struct *conn,
SSVAL(params,0,0); /* No changes */
SSVAL(params,2,0); /* No EA errors */
- send_trans2_replies(req, params, 4, *ppdata, 0, max_data_bytes);
+ send_trans2_replies(conn, req, params, 4, *ppdata, 0, max_data_bytes);
return;
}
@@ -6928,7 +6941,7 @@ static void call_trans2getdfsreferral(connection_struct *conn,
SSVAL(req->inbuf, smb_flg2,
SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
- send_trans2_replies(req,0,0,*ppdata,reply_size, max_data_bytes);
+ send_trans2_replies(conn, req,0,0,*ppdata,reply_size, max_data_bytes);
return;
}
@@ -6975,7 +6988,7 @@ static void call_trans2ioctl(connection_struct *conn,
srvstr_push(pdata, req->flags2, pdata+18,
lp_servicename(SNUM(conn)), 13,
STR_ASCII|STR_TERMINATE); /* Service name */
- send_trans2_replies(req, *pparams, 0, *ppdata, 32,
+ send_trans2_replies(conn, req, *pparams, 0, *ppdata, 32,
max_data_bytes);
return;
}