summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/blocking.c142
1 files changed, 54 insertions, 88 deletions
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 6bb73e1b76..555033b7df 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -29,7 +29,6 @@
typedef struct blocking_lock_record {
struct blocking_lock_record *next;
struct blocking_lock_record *prev;
- int com_type;
files_struct *fsp;
struct timeval expire_time;
int lock_num;
@@ -39,9 +38,7 @@ typedef struct blocking_lock_record {
uint32_t blocking_pid; /* PID that blocks us. */
enum brl_flavour lock_flav;
enum brl_type lock_type;
- char *inbuf;
- int length;
- bool encrypted;
+ struct smb_request *req;
} blocking_lock_record;
/* dlink list we store pending lock records on. */
@@ -140,7 +137,7 @@ static bool recalc_brl_timeout(void)
****************************************************************************/
bool push_blocking_lock_request( struct byte_range_lock *br_lck,
- const struct smb_request *req,
+ struct smb_request *req,
files_struct *fsp,
int lock_timeout,
int lock_num,
@@ -152,7 +149,6 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
uint32_t blocking_pid)
{
static bool set_lock_msg;
- size_t length = smb_len(req->inbuf)+4;
blocking_lock_record *blr;
NTSTATUS status;
@@ -175,14 +171,6 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
blr->next = NULL;
blr->prev = NULL;
- blr->inbuf = TALLOC_ARRAY(blr, char, length);
- if (blr->inbuf == NULL) {
- DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" ));
- TALLOC_FREE(blr);
- return False;
- }
-
- blr->com_type = req->cmd;
blr->fsp = fsp;
if (lock_timeout == -1) {
blr->expire_time.tv_sec = 0;
@@ -198,9 +186,6 @@ 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, 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,
@@ -220,6 +205,8 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
return False;
}
+ blr->req = talloc_move(blr, &req);
+
DLIST_ADD_END(blocking_lock_queue, blr, blocking_lock_record *);
recalc_brl_timeout();
@@ -230,14 +217,14 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
set_lock_msg = True;
}
- DEBUG(3,("push_blocking_lock_request: lock request length=%u blocked with "
+ DEBUG(3,("push_blocking_lock_request: lock request blocked with "
"expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s\n",
- (unsigned int)length, (unsigned int)blr->expire_time.tv_sec,
+ (unsigned int)blr->expire_time.tv_sec,
(unsigned int)blr->expire_time.tv_usec, lock_timeout,
blr->fsp->fnum, blr->fsp->fsp_name ));
/* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(SVAL(req->inbuf,smb_mid));
+ srv_defer_sign_response(blr->req->mid);
return True;
}
@@ -248,15 +235,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
static void reply_lockingX_success(blocking_lock_record *blr)
{
- struct smb_request *req;
-
- if (!(req = talloc(talloc_tos(), struct smb_request))) {
- smb_panic("Could not allocate smb_request");
- }
-
- init_smb_request(req, (uint8 *)blr->inbuf, 0, blr->encrypted);
- req->inbuf = (uint8_t *)(blr->inbuf);
- reply_outbuf(req, 2, 0);
+ reply_outbuf(blr->req, 2, 0);
/*
* As this message is a lockingX call we must handle
@@ -266,13 +245,14 @@ static void reply_lockingX_success(blocking_lock_record *blr)
* that here and must set up the chain info manually.
*/
- chain_reply(req);
+ chain_reply(blr->req);
- if (!srv_send_smb(smbd_server_fd(),
- (char *)req->outbuf,
+ if (!srv_send_smb(smbd_server_fd(), (char *)blr->req->outbuf,
IS_CONN_ENCRYPTED(blr->fsp->conn))) {
exit_server_cleanly("send_blocking_reply: srv_send_smb failed.");
}
+
+ TALLOC_FREE(blr->req->outbuf);
}
/****************************************************************************
@@ -281,11 +261,6 @@ static void reply_lockingX_success(blocking_lock_record *blr)
static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS status)
{
- char outbuf[smb_size];
- char *inbuf = blr->inbuf;
-
- construct_reply_common(inbuf, outbuf);
-
/* whenever a timeout is given w2k maps LOCK_NOT_GRANTED to
FILE_LOCK_CONFLICT! (tridge) */
if (NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED)) {
@@ -308,10 +283,12 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat
}
}
- ERROR_NT(status);
- if (!srv_send_smb(smbd_server_fd(),outbuf, blr->encrypted)) {
+ reply_nterror(blr->req, status);
+ if (!srv_send_smb(smbd_server_fd(), (char *)blr->req->outbuf,
+ blr->req->encrypted)) {
exit_server_cleanly("generic_blocking_lock_error: srv_send_smb failed.");
}
+ TALLOC_FREE(blr->req->outbuf);
}
/****************************************************************************
@@ -321,17 +298,16 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat
static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status)
{
- char *inbuf = blr->inbuf;
files_struct *fsp = blr->fsp;
- uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
+ uint16 num_ulocks = SVAL(blr->req->vwv+6, 0);
uint64_t count = (uint64_t)0, offset = (uint64_t) 0;
uint32 lock_pid;
- unsigned char locktype = CVAL(inbuf,smb_vwv3);
+ unsigned char locktype = CVAL(blr->req->vwv+3, 0);
bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
uint8_t *data;
int i;
- data = (uint8_t *)smb_buf(inbuf)
+ data = (uint8_t *)blr->req->buf
+ ((large_file_format ? 20 : 10)*num_ulocks);
/*
@@ -374,28 +350,28 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status)
static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status)
{
- switch(blr->com_type) {
+ switch(blr->req->cmd) {
case SMBlockingX:
reply_lockingX_error(blr, status);
break;
case SMBtrans2:
case SMBtranss2:
- {
- char outbuf[smb_size];
- char *inbuf = blr->inbuf;
- construct_reply_common(inbuf, outbuf);
- /* construct_reply_common has done us the favor to pre-fill the
- * command field with SMBtranss2 which is wrong :-)
- */
- SCVAL(outbuf,smb_com,SMBtrans2);
- ERROR_NT(status);
- 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;
+ reply_nterror(blr->req, status);
+
+ /*
+ * construct_reply_common has done us the favor to pre-fill
+ * the command field with SMBtranss2 which is wrong :-)
+ */
+ SCVAL(blr->req->outbuf,smb_com,SMBtrans2);
+
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)blr->req->outbuf,
+ IS_CONN_ENCRYPTED(blr->fsp->conn))) {
+ exit_server_cleanly("blocking_lock_reply_error: "
+ "srv_send_smb failed.");
}
+ TALLOC_FREE(blr->req->outbuf);
+ break;
default:
DEBUG(0,("blocking_lock_reply_error: PANIC - unknown type on blocking lock queue - exiting.!\n"));
exit_server("PANIC - unknown type on blocking lock queue");
@@ -409,18 +385,17 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status
static bool process_lockingX(blocking_lock_record *blr)
{
- char *inbuf = blr->inbuf;
- unsigned char locktype = CVAL(inbuf,smb_vwv3);
+ unsigned char locktype = CVAL(blr->req->vwv+3, 0);
files_struct *fsp = blr->fsp;
- uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
- uint16 num_locks = SVAL(inbuf,smb_vwv7);
+ uint16 num_ulocks = SVAL(blr->req->vwv+6, 0);
+ uint16 num_locks = SVAL(blr->req->vwv+7, 0);
uint64_t count = (uint64_t)0, offset = (uint64_t)0;
uint32 lock_pid;
bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
uint8_t *data;
NTSTATUS status = NT_STATUS_OK;
- data = (uint8_t *)smb_buf(inbuf)
+ data = (uint8_t *)blr->req->buf
+ ((large_file_format ? 20 : 10)*num_ulocks);
/*
@@ -501,7 +476,6 @@ Waiting....\n",
static bool process_trans2(blocking_lock_record *blr)
{
- struct smb_request *req;
char params[2];
NTSTATUS status;
struct byte_range_lock *br_lck = do_lock(smbd_messaging_context(),
@@ -531,18 +505,10 @@ static bool process_trans2(blocking_lock_record *blr)
/* We finally got the lock, return success. */
- if (!(req = talloc(talloc_tos(), struct smb_request))) {
- blocking_lock_reply_error(blr, NT_STATUS_NO_MEMORY);
- return True;
- }
-
- init_smb_request(req, (uint8 *)blr->inbuf, 0, blr->encrypted);
- req->inbuf = (uint8_t *)(blr->inbuf);
-
- SCVAL(req->inbuf, smb_com, SMBtrans2);
+ SCVAL(blr->req->inbuf, smb_com, SMBtrans2);
SSVAL(params,0,0);
/* Fake up max_data_bytes here - we know it fits. */
- send_trans2_replies(blr->fsp->conn, req, params, 2, NULL, 0, 0xffff);
+ send_trans2_replies(blr->fsp->conn, blr->req, params, 2, NULL, 0, 0xffff);
return True;
}
@@ -554,7 +520,7 @@ static bool process_trans2(blocking_lock_record *blr)
static bool blocking_lock_record_process(blocking_lock_record *blr)
{
- switch(blr->com_type) {
+ switch(blr->req->cmd) {
case SMBlockingX:
return process_lockingX(blr);
case SMBtrans2:
@@ -583,13 +549,13 @@ void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lo
continue;
}
- if (blr->com_type == SMBlockingX) {
- locktype = CVAL(blr->inbuf,smb_vwv3);
+ if (blr->req->cmd == SMBlockingX) {
+ locktype = CVAL(blr->req->vwv+3, 0);
}
DEBUG(10, ("remove_pending_lock_requests_by_fid - removing "
"request type %d for file %s fnum = %d\n",
- blr->com_type, fsp->fsp_name, fsp->fnum));
+ blr->req->cmd, fsp->fsp_name, fsp->fnum));
brl_lock_cancel(br_lck,
blr->lock_pid,
@@ -626,7 +592,7 @@ void remove_pending_lock_requests_by_mid(int mid)
next = blr->next;
- if (SVAL(blr->inbuf,smb_mid) != mid) {
+ if (blr->req->mid != mid) {
continue;
}
@@ -636,7 +602,7 @@ void remove_pending_lock_requests_by_mid(int mid)
if (br_lck) {
DEBUG(10, ("remove_pending_lock_requests_by_mid - "
"removing request type %d for file %s fnum "
- "= %d\n", blr->com_type, fsp->fsp_name,
+ "= %d\n", blr->req->cmd, fsp->fsp_name,
fsp->fnum ));
brl_lock_cancel(br_lck,
@@ -664,7 +630,7 @@ bool blocking_lock_was_deferred(int mid)
for(blr = blocking_lock_queue; blr; blr = next) {
next = blr->next;
- if(SVAL(blr->inbuf,smb_mid) == mid) {
+ if(blr->req->mid == mid) {
return True;
}
}
@@ -713,9 +679,9 @@ static void process_blocking_lock_queue(void)
chain_size = 0;
fsp = blr->fsp;
- conn = conn_find(SVAL(blr->inbuf,smb_tid));
- vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID :
- SVAL(blr->inbuf,smb_uid);
+ conn = conn_find(blr->req->tid);
+ vuid = (lp_security() == SEC_SHARE)
+ ? UID_FIELD_INVALID : blr->req->vuid;
DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n",
fsp->fnum, fsp->fsp_name ));
@@ -746,7 +712,7 @@ static void process_blocking_lock_queue(void)
continue;
}
- if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) {
+ if(!set_current_service(conn,SVAL(blr->req->inbuf,smb_flg),True)) {
struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp);
/*
@@ -915,9 +881,9 @@ bool blocking_lock_cancel(files_struct *fsp,
}
/* Check the flags are right. */
- if (blr->com_type == SMBlockingX &&
+ if (blr->req->cmd == SMBlockingX &&
(locktype & LOCKING_ANDX_LARGE_FILES) !=
- (CVAL(blr->inbuf,smb_vwv3) & LOCKING_ANDX_LARGE_FILES)) {
+ (CVAL(blr->req->vwv+3, 0) & LOCKING_ANDX_LARGE_FILES)) {
return False;
}