diff options
author | Andrew Tridgell <tridge@samba.org> | 2008-05-27 17:22:02 +1000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2008-05-27 17:22:02 +1000 |
commit | beac55a88fd28b6003ba163f32539a7bdc2df1a6 (patch) | |
tree | 30e7f30163af16e2f84d4242bf2299dc16208bc6 /source4/ntvfs | |
parent | cb36437db2d75e7facc91cf0089f2caa20bf0ca0 (diff) | |
download | samba-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')
-rw-r--r-- | source4/ntvfs/ntvfs_generic.c | 56 |
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 */ |