summaryrefslogtreecommitdiff
path: root/source4/ntvfs/ntvfs_generic.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2008-05-27 17:22:02 +1000
committerAndrew Tridgell <tridge@samba.org>2008-05-27 17:22:02 +1000
commitbeac55a88fd28b6003ba163f32539a7bdc2df1a6 (patch)
tree30e7f30163af16e2f84d4242bf2299dc16208bc6 /source4/ntvfs/ntvfs_generic.c
parentcb36437db2d75e7facc91cf0089f2caa20bf0ca0 (diff)
downloadsamba-beac55a88fd28b6003ba163f32539a7bdc2df1a6.tar.gz
samba-beac55a88fd28b6003ba163f32539a7bdc2df1a6.tar.bz2
samba-beac55a88fd28b6003ba163f32539a7bdc2df1a6.zip
enforce lock ordering in SMB2
(This used to be commit 3bec932a89006521ba74bde7943b8cd5b4a660d8)
Diffstat (limited to 'source4/ntvfs/ntvfs_generic.c')
-rw-r--r--source4/ntvfs/ntvfs_generic.c56
1 files changed, 29 insertions, 27 deletions
diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c
index a1c89e7df4..3d92c0be33 100644
--- a/source4/ntvfs/ntvfs_generic.c
+++ b/source4/ntvfs/ntvfs_generic.c
@@ -1027,7 +1027,7 @@ 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;
+ int i, j;
if (lck->smb2.in.lock_count < 1) {
return NT_STATUS_INVALID_PARAMETER;
}
@@ -1044,34 +1044,36 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs,
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) {
- int 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;
+ 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;
}
- for (i=0;i<lck->smb2.in.lock_count;i++) {
- if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK)) {
- int 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;
- if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE)) {
- lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK;
- }
- if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_FAIL_IMMEDIATELY) {
- lck2->generic.in.timeout = 0;
- }
+ 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 */
+ 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;
+ if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE)) {
+ lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK;
+ }
+ if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_FAIL_IMMEDIATELY) {
+ lck2->generic.in.timeout = 0;
}
}
/* initialize output value */