summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/locking/brlock.c5
-rw-r--r--source3/smbd/reply.c24
2 files changed, 29 insertions, 0 deletions
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index b021293c7b..22c6c9e5b3 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -333,6 +333,11 @@ NTSTATUS brl_lock_windows_default(struct byte_range_lock *br_lck,
SMB_ASSERT(plock->lock_type != UNLOCK_LOCK);
for (i=0; i < br_lck->num_locks; i++) {
+ if (locks[i].start + locks[i].size < locks[i].start) {
+ /* 64-bit wrap. Error. */
+ return NT_STATUS_INVALID_LOCK_RANGE;
+ }
+
/* Do any Windows or POSIX locks conflict ? */
if (brl_conflict(&locks[i], plock)) {
/* Remember who blocked us. */
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 030939f524..185f6014d1 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -7038,6 +7038,30 @@ NTSTATUS smbd_do_locking(struct smb_request *req,
if (type & LOCKING_ANDX_CANCEL_LOCK) {
struct blocking_lock_record *blr = NULL;
+ if (num_locks > 1) {
+ /*
+ * MS-CIFS (2.2.4.32.1) states that a cancel is honored if and only
+ * if the lock vector contains one entry. When given mutliple cancel
+ * requests in a single PDU we expect the server to return an
+ * error. Windows servers seem to accept the request but only
+ * cancel the first lock.
+ * JRA - Do what Windows does (tm) :-).
+ */
+
+#if 0
+ /* MS-CIFS (2.2.4.32.1) behavior. */
+ return NT_STATUS_DOS(ERRDOS,
+ ERRcancelviolation);
+#else
+ /* Windows behavior. */
+ if (i != 0) {
+ DEBUG(10,("smbd_do_locking: ignoring subsequent "
+ "cancel request\n"));
+ continue;
+ }
+#endif
+ }
+
if (lp_blocking_locks(SNUM(conn))) {
/* Schedule a message to ourselves to