smbpid is 32 bit, and update SMB2 locking per MS-SMB2
authorAndrew Tridgell <tridge@samba.org>
Mon, 2 Jun 2008 01:04:13 +0000 (11:04 +1000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 2 Jun 2008 01:04:13 +0000 (11:04 +1000)
The UNLOCK bit is only used from the first lock structure
(This used to be commit 9483b7c137b61d3029a1e1e7d8d8d0723b541129)

source4/ntvfs/ntvfs.h
source4/ntvfs/ntvfs_generic.c
source4/ntvfs/posix/pvfs_lock.c

index 7a2edc7e2c2b5570bf3616b3e2120618d2d1141b..5de8a8b6491cd7e0f81915907de5b4fbc8153a47 100644 (file)
@@ -263,7 +263,7 @@ struct ntvfs_request {
        struct auth_session_info *session_info;
 
        /* the smb pid is needed for locking contexts */
-       uint16_t smbpid;
+       uint32_t smbpid;
 
        /*
         * client capabilities
index d70575847574f6a6ca361fdf2f32e99b6bb661bd..a3a8fcb1f42a966ab5498e979591b903e1dc631f 100644 (file)
@@ -986,8 +986,8 @@ NTSTATUS ntvfs_map_qpathinfo(struct ntvfs_module_context *ntvfs,
    NTVFS lock generic to any mapper
 */
 NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs,
-                                struct ntvfs_request *req,
-                                union smb_lock *lck)
+                       struct ntvfs_request *req,
+                       union smb_lock *lck)
 {
        union smb_lock *lck2;
        struct smb_lock_entry *locks;
@@ -1035,7 +1035,8 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs,
        case RAW_LOCK_SMB2: {
                /* this is only approximate! We need to change the
                   generic structure to fix this properly */
-               int i, j;
+               int i;
+               bool isunlock;
                if (lck->smb2.in.lock_count < 1) {
                        return NT_STATUS_INVALID_PARAMETER;
                }
@@ -1051,32 +1052,24 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs,
                if (lck2->generic.in.locks == NULL) {
                        return NT_STATUS_NO_MEMORY;
                }
-               for (i=0;i<lck->smb2.in.lock_count;i++) {
-                       if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK)) {
-                               break;
-                       }
-                       j = lck2->generic.in.ulock_cnt;
-                       if (lck->smb2.in.locks[i].flags & 
-                           (SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_EXCLUSIVE)) {
-                               return NT_STATUS_INVALID_PARAMETER;
-                       }
-                       lck2->generic.in.ulock_cnt++;
-                       lck2->generic.in.locks[j].pid = 0;
-                       lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset;
-                       lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length;
-                       lck2->generic.in.locks[j].pid = 0;
+               /* only the first lock gives the UNLOCK bit - see
+                  MS-SMB2 3.3.5.14 */
+               if (lck->smb2.in.locks[0].flags & SMB2_LOCK_FLAG_UNLOCK) {
+                       lck2->generic.in.ulock_cnt = lck->smb2.in.lock_count;
+                       isunlock = true;
+               } else {
+                       lck2->generic.in.lock_cnt = lck->smb2.in.lock_count;
+                       isunlock = false;
                }
-               for (;i<lck->smb2.in.lock_count;i++) {
-                       if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK) {
-                               /* w2008 requires unlocks to come first */
+               for (i=0;i<lck->smb2.in.lock_count;i++) {
+                       if (isunlock && 
+                           (lck->smb2.in.locks[i].flags & 
+                            (SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_EXCLUSIVE))) {
                                return NT_STATUS_INVALID_PARAMETER;
                        }
-                       j = lck2->generic.in.ulock_cnt + lck2->generic.in.lock_cnt;
-                       lck2->generic.in.lock_cnt++;
-                       lck2->generic.in.locks[j].pid = 0;
-                       lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset;
-                       lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length;
-                       lck2->generic.in.locks[j].pid = 0;
+                       lck2->generic.in.locks[i].pid = req->smbpid;
+                       lck2->generic.in.locks[i].offset = lck->smb2.in.locks[i].offset;
+                       lck2->generic.in.locks[i].count = lck->smb2.in.locks[i].length;
                        if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE)) {
                                lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK;
                        }
index 822b28246ad6f5a7a36cb8c490b78db7f0ccd26a..0054455838a98246df26b0410e20bd2666d6bd5f 100644 (file)
@@ -31,7 +31,7 @@
 */
 NTSTATUS pvfs_check_lock(struct pvfs_state *pvfs,
                         struct pvfs_file *f,
-                        uint16_t smbpid,
+                        uint32_t smbpid,
                         uint64_t offset, uint64_t count,
                         enum brl_type rw)
 {