summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/ntvfs/ntvfs.h2
-rw-r--r--source4/ntvfs/ntvfs_generic.c45
-rw-r--r--source4/ntvfs/posix/pvfs_lock.c2
3 files changed, 21 insertions, 28 deletions
diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h
index 7a2edc7e2c..5de8a8b649 100644
--- a/source4/ntvfs/ntvfs.h
+++ b/source4/ntvfs/ntvfs.h
@@ -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
diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c
index d705758475..a3a8fcb1f4 100644
--- a/source4/ntvfs/ntvfs_generic.c
+++ b/source4/ntvfs/ntvfs_generic.c
@@ -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;
}
diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c
index 822b28246a..0054455838 100644
--- a/source4/ntvfs/posix/pvfs_lock.c
+++ b/source4/ntvfs/posix/pvfs_lock.c
@@ -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)
{