summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2010-04-08 22:15:55 -0700
committerJeremy Allison <jra@samba.org>2010-04-08 22:15:55 -0700
commit08b24e923dff99d3d3c0618903a7ed2959640470 (patch)
treeacfc07cc9c3aec2d1d78287b4fc58dbe143de627
parent3491f6d119d1f4c7e0a259a9993ce96783b77e23 (diff)
downloadsamba-08b24e923dff99d3d3c0618903a7ed2959640470.tar.gz
samba-08b24e923dff99d3d3c0618903a7ed2959640470.tar.bz2
samba-08b24e923dff99d3d3c0618903a7ed2959640470.zip
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.
-rw-r--r--source3/include/smb.h6
-rw-r--r--source3/smbd/blocking.c14
-rw-r--r--source3/smbd/globals.h17
-rw-r--r--source3/smbd/process.c1
-rw-r--r--source3/smbd/smb2_glue.c14
-rw-r--r--source3/smbd/smb2_lock.c20
6 files changed, 72 insertions, 0 deletions
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 751f3a46a4..48ab2f2283 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 cb48cc8c1c..2a0024c493 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 033a77783a..5eea0ce311 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 3e5cee83c5..ddafdff3a2 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 d5a6217aa3..3ecc790bba 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 908e1cf8a4..129bb2f330 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;
+}