Make Samba3 pass the RAW-LOCK test as Windows.
authorJeremy Allison <jra@samba.org>
Fri, 4 Dec 2009 22:04:08 +0000 (14:04 -0800)
committerJeremy Allison <jra@samba.org>
Fri, 4 Dec 2009 22:04:08 +0000 (14:04 -0800)
Implement the win7 NT_STATUS_INVALID_LOCK_RANGE.
Make smbd behave as Windows does in canceling locks.

Jeremy.

source3/locking/brlock.c
source3/smbd/reply.c

index b021293c7b8c64f3f1260dab7e28ee2cf6f57b72..22c6c9e5b3312655c9412b5294b0271c05965fa0 100644 (file)
@@ -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. */
index 030939f5240efdaccf4f3d66c224d464e8ab6ef1..185f6014d1a38d16173e86839250a547c03e26dc 100644 (file)
@@ -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