From 08b24e923dff99d3d3c0618903a7ed2959640470 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 8 Apr 2010 22:15:55 -0700 Subject: [PATCH] Stop smb2 from calling into smb1 blocking lock request code. Allocate a uint16_t internal SMB1 mid for an SMB2 request. Add a back pointer from the faked up smb_request struct to the smb2 request. Getting ready to add restart code for blocking locks, share mode violations and oplocks in SMB2. Jeremy. --- source3/include/smb.h | 6 ++++++ source3/smbd/blocking.c | 14 ++++++++++++++ source3/smbd/globals.h | 17 +++++++++++++++++ source3/smbd/process.c | 1 + source3/smbd/smb2_glue.c | 14 ++++++++++++++ source3/smbd/smb2_lock.c | 20 ++++++++++++++++++++ 6 files changed, 72 insertions(+) diff --git a/source3/include/smb.h b/source3/include/smb.h index 751f3a46a4b..48ab2f22833 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -623,6 +623,7 @@ struct current_user { NT_USER_TOKEN *nt_user_token; }; +struct smbd_smb2_request; struct smb_request { uint8_t cmd; @@ -670,6 +671,11 @@ struct smb_request { void *async_priv; bool done; + + /* + * Back pointer to smb2 request. + */ + struct smbd_smb2_request *smb2req; }; /* Defines for the sent_oplock_break field above. */ diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index cb48cc8c1ce..2a0024c4934 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -158,6 +158,20 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, struct blocking_lock_record *blr; NTSTATUS status; + if (req->smb2req) { + return smb2_push_blocking_lock_request(br_lck, + req, + fsp, + lock_timeout, + lock_num, + lock_pid, + lock_type, + lock_flav, + offset, + count, + blocking_pid); + } + if(req_is_in_chain(req)) { DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n")); return False; diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 033a77783a7..5eea0ce311a 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -321,6 +321,17 @@ NTSTATUS smbd_smb2_request_process_break(struct smbd_smb2_request *req); void send_smb2_break_message(files_struct *fsp, uint8_t level); void schedule_deferred_open_smb2_message(uint16 mid); +bool smb2_push_blocking_lock_request( struct byte_range_lock *br_lck, + struct smb_request *req, + files_struct *fsp, + int lock_timeout, + int lock_num, + uint32_t lock_pid, + enum brl_type lock_type, + enum brl_flavour lock_flav, + uint64_t offset, + uint64_t count, + uint32_t blocking_pid); struct smbd_smb2_request { struct smbd_smb2_request *prev, *next; @@ -338,6 +349,11 @@ struct smbd_smb2_request { int current_idx; bool do_signing; + /* + * mid used for compatibility with SMB1 code. + * Server allocated, never seen by client. + */ + uint16_t compat_mid; struct files_struct *compat_chain_fsp; @@ -535,6 +551,7 @@ struct smbd_server_connection { struct smbd_smb2_session *list; } sessions; struct smbd_smb2_request *requests; + uint16_t next_compat_mid; } smb2; }; diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 3e5cee83c59..ddafdff3a2e 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -467,6 +467,7 @@ static bool init_smb_request(struct smb_request *req, const uint8 *inbuf, req->chain_fsp = NULL; req->chain_outbuf = NULL; req->done = false; + req->smb2req = NULL; smb_init_perfcount_data(&req->pcd); /* Ensure we have at least wct words and 2 bytes of bcc. */ diff --git a/source3/smbd/smb2_glue.c b/source3/smbd/smb2_glue.c index d5a6217aa31..3ecc790bba4 100644 --- a/source3/smbd/smb2_glue.c +++ b/source3/smbd/smb2_glue.c @@ -22,6 +22,18 @@ #include "smbd/globals.h" #include "../libcli/smb/smb_common.h" +static uint16_t allocate_next_mid(void) +{ + struct smbd_server_connection *sconn = smbd_server_conn; + + sconn->smb2.next_compat_mid++; + /* Avoid mid == 0 and mid == 0xffff. */ + if (sconn->smb2.next_compat_mid == 0xFFFF) { + sconn->smb2.next_compat_mid += 2; + } + return sconn->smb2.next_compat_mid; +} + struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req) { struct smb_request *smbreq; @@ -46,7 +58,9 @@ struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req) if (IVAL(inhdr, SMB2_HDR_FLAGS) & SMB2_HDR_FLAG_DFS) { smbreq->flags2 |= FLAGS2_DFS_PATHNAMES; } + req->compat_mid = smbreq->mid = allocate_next_mid(); smbreq->chain_fsp = req->compat_chain_fsp; + smbreq->smb2req = req; return smbreq; } diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index 908e1cf8a4d..129bb2f330a 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -381,3 +381,23 @@ static NTSTATUS smbd_smb2_lock_recv(struct tevent_req *req) tevent_req_received(req); return NT_STATUS_OK; } + +/* + * Dummy (for now) function to cope with SMB2 blocking lock + * requests. + */ + +bool smb2_push_blocking_lock_request( struct byte_range_lock *br_lck, + struct smb_request *req, + files_struct *fsp, + int lock_timeout, + int lock_num, + uint32_t lock_pid, + enum brl_type lock_type, + enum brl_flavour lock_flav, + uint64_t offset, + uint64_t count, + uint32_t blocking_pid) +{ + return false; +} -- 2.34.1