1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 /* 27 * SMB: locking_andx 28 * 29 * SMB_COM_LOCKING_ANDX allows both locking and/or unlocking of file range(s). 30 * 31 * Client Request Description 32 * ================================== ================================= 33 * 34 * UCHAR WordCount; Count of parameter words = 8 35 * UCHAR AndXCommand; Secondary (X) command; 0xFF = none 36 * UCHAR AndXReserved; Reserved (must be 0) 37 * USHORT AndXOffset; Offset to next command WordCount 38 * USHORT Fid; File handle 39 * UCHAR LockType; See LockType table below 40 * UCHAR OplockLevel; The new oplock level 41 * ULONG Timeout; Milliseconds to wait for unlock 42 * USHORT NumberOfUnlocks; Num. unlock range structs following 43 * USHORT NumberOfLocks; Num. lock range structs following 44 * USHORT ByteCount; Count of data bytes 45 * LOCKING_ANDX_RANGE Unlocks[]; Unlock ranges 46 * LOCKING_ANDX_RANGE Locks[]; Lock ranges 47 * 48 * LockType Flag Name Value Description 49 * ============================ ===== ================================ 50 * 51 * LOCKING_ANDX_SHARED_LOCK 0x01 Read-only lock 52 * LOCKING_ANDX_OPLOCK_RELEASE 0x02 Oplock break notification 53 * LOCKING_ANDX_CHANGE_LOCKTYPE 0x04 Change lock type 54 * LOCKING_ANDX_CANCEL_LOCK 0x08 Cancel outstanding request 55 * LOCKING_ANDX_LARGE_FILES 0x10 Large file locking format 56 * 57 * LOCKING_ANDX_RANGE Format 58 * ===================================================================== 59 * 60 * USHORT Pid; PID of process "owning" lock 61 * ULONG Offset; Offset to bytes to [un]lock 62 * ULONG Length; Number of bytes to [un]lock 63 * 64 * Large File LOCKING_ANDX_RANGE Format 65 * ===================================================================== 66 * 67 * USHORT Pid; PID of process "owning" lock 68 * USHORT Pad; Pad to DWORD align (mbz) 69 * ULONG OffsetHigh; Offset to bytes to [un]lock 70 * (high) 71 * ULONG OffsetLow; Offset to bytes to [un]lock (low) 72 * ULONG LengthHigh; Number of bytes to [un]lock 73 * (high) 74 * ULONG LengthLow; Number of bytes to [un]lock (low) 75 * 76 * Server Response Description 77 * ================================== ================================= 78 * 79 * UCHAR WordCount; Count of parameter words = 2 80 * UCHAR AndXCommand; Secondary (X) command; 0xFF = 81 * none 82 * UCHAR AndXReserved; Reserved (must be 0) 83 * USHORT AndXOffset; Offset to next command WordCount 84 * USHORT ByteCount; Count of data bytes = 0 85 * 86 * Locking is a simple mechanism for excluding other processes read/write 87 * access to regions of a file. The locked regions can be anywhere in the 88 * logical file. Locking beyond end-of-file is permitted. Any process 89 * using the Fid specified in this request's Fid has access to the locked 90 * bytes, other processes will be denied the locking of the same bytes. 91 * 92 * The proper method for using locks is not to rely on being denied read or 93 * write access on any of the read/write protocols but rather to attempt 94 * the locking protocol and proceed with the read/write only if the locks 95 * succeeded. 96 * 97 * Locking a range of bytes will fail if any subranges or overlapping 98 * ranges are locked. In other words, if any of the specified bytes are 99 * already locked, the lock will fail. 100 * 101 * If NumberOfUnlocks is non-zero, the Unlocks vector contains 102 * NumberOfUnlocks elements. Each element requests that a lock at Offset 103 * of Length be released. If NumberOfLocks is nonzero, the Locks vector 104 * contains NumberOfLocks elements. Each element requests the acquisition 105 * of a lock at Offset of Length. 106 * 107 * Timeout is the maximum amount of time to wait for the byte range(s) 108 * specified to become unlocked. A timeout value of 0 indicates that the 109 * server should fail immediately if any lock range specified is locked. A 110 * 111 * timeout value of -1 indicates that the server should wait as long as it 112 * takes for each byte range specified to become unlocked so that it may be 113 * again locked by this protocol. Any other value of smb_timeout specifies 114 * the maximum number of milliseconds to wait for all lock range(s) 115 * specified to become available. 116 * 117 * If any of the lock ranges timeout because of the area to be locked is 118 * already locked (or the lock fails), the other ranges in the protocol 119 * request which were successfully locked as a result of this protocol will 120 * be unlocked (either all requested ranges will be locked when this 121 * protocol returns to the client or none). 122 * 123 * If LockType has the LOCKING_ANDX_SHARED_LOCK flag set, the lock is 124 * specified as a shared lock. Locks for both read and write (where 125 * LOCKING_ANDX_SHARED_LOCK is clear) should be prohibited, but other 126 * shared locks should be permitted. If shared locks can not be supported 127 * by a server, the server should map the lock to a lock for both read and 128 * write. Closing a file with locks still in force causes the locks to be 129 * released in no defined order. 130 * 131 * If LockType has the LOCKING_ANDX_LARGE_FILES flag set and if the 132 * negotiated protocol is NT LM 0.12 or later, then the Locks and Unlocks 133 * vectors are in the Large File LOCKING_ANDX_RANGE format. This allows 134 * specification of 64 bit offsets for very large files. 135 * 136 * If the one and only member of the Locks vector has the 137 * LOCKING_ANDX_CANCEL_LOCK flag set in the LockType field, the client is 138 * requesting the server to cancel a previously requested, but not yet 139 * responded to, lock. 140 * 141 * If LockType has the LOCKING_ANDX_CHANGE_LOCKTYPE flag set, the client is 142 * requesting that the server atomically change the lock type from a shared 143 * lock to an exclusive lock or vice versa. If the server can not do this 144 * in an atomic fashion, the server must reject this request. NT and W95 145 * servers do not support this capability. 146 * 147 * Oplocks are described in the "Opportunistic Locks" section elsewhere in 148 * this document. A client requests an oplock by setting the appropriate 149 * bit in the SMB_COM_OPEN_ANDX request when the file is being opened in a 150 * mode which is not exclusive. The server responds by setting the 151 * appropriate bit in the response SMB indicating whether or not the oplock 152 * was granted. By granting the oplock, the server tells the client the 153 * file is currently only being used by this one client process at the 154 * current time. The client can therefore safely do read ahead and write 155 * behind as well as local caching of file locks knowing that the file will 156 * not be accessed/changed in any way by another process while the oplock 157 * is in effect. The client will be notified when any other process 158 * attempts to open or modify the oplocked file. 159 * 160 * When another user attempts to open or otherwise modify the file which a 161 * client has oplocked, the server delays the second attempt and notifies 162 * the client via an SMB_LOCKING_ANDX SMB asynchronously sent from the 163 * server to the client. This message has the LOCKING_ANDX_OPLOCK_RELEASE 164 * flag set indicating to the client that the oplock is being broken. 165 * 166 * OplockLevel indicates the type of oplock the client now owns. If 167 * OplockLevel is 0, the client possesses no oplocks on the file at all, if 168 * OplockLevel is 1 the client possesses a Level II oplock. The client is 169 * expected to flush any dirty buffers to the server, submit any file locks 170 * and respond to the server with either an SMB_LOCKING_ANDX SMB having the 171 * LOCKING_ANDX_OPLOCK_RELEASE flag set, or with a file close if the file 172 * is no longer in use by the client. If the client sends an 173 * SMB_LOCKING_ANDX SMB with the LOCKING_ANDX_OPLOCK_RELEASE flag set and 174 * NumberOfLocks is zero, the server does not send a response. Since a 175 * close being sent to the server and break oplock notification from the 176 * server could cross on the wire, if the client gets an oplock 177 * notification on a file which it does not have open, that notification 178 * should be ignored. 179 * 180 * Due to timing, the client could get an "oplock broken" notification in a 181 * user's data buffer as a result of this notification crossing on the wire 182 * with a SMB_COM_READ_RAW request. The client must detect this (use 183 * length of msg, "FFSMB", MID of -1 and Command of SMB_COM_LOCKING_ANDX) 184 * and honor the "oplock broken" notification as usual. The server must 185 * also note on receipt of an SMB_COM_READ_RAW request that there is an 186 * outstanding (unanswered) "oplock broken" notification to the client and 187 * return a zero length response denoting failure of the read raw request. 188 * The client should (after responding to the "oplock broken" 189 * notification), use a standard read protocol to redo the read request. 190 * This allows a file to actually contain data matching an "oplock broken" 191 * notification and still be read correctly. 192 * 193 * The entire message sent and received including the optional second 194 * protocol must fit in the negotiated maximum transfer size. The 195 * following are the only valid SMB commands for AndXCommand for 196 * SMB_COM_LOCKING_ANDX: 197 * 198 * SMB_COM_READ SMB_COM_READ_ANDX 199 * SMB_COM_WRITE SMB_COM_WRITE_ANDX 200 * SMB_COM_FLUSH 201 * 202 * 4.2.6.1 Errors 203 * 204 * ERRDOS/ERRbadfile 205 * ERRDOS/ERRbadfid 206 * ERRDOS/ERRlock 207 * ERRDOS/ERRinvdevice 208 * ERRSRV/ERRinvid 209 * ERRSRV/ERRbaduid 210 */ 211 212 #include <smbsrv/smb_kproto.h> 213 214 smb_sdrc_t 215 smb_pre_locking_andx(smb_request_t *sr) 216 { 217 DTRACE_SMB_1(op__LockingX__start, smb_request_t *, sr); 218 return (SDRC_SUCCESS); 219 } 220 221 void 222 smb_post_locking_andx(smb_request_t *sr) 223 { 224 DTRACE_SMB_1(op__LockingX__done, smb_request_t *, sr); 225 } 226 227 smb_sdrc_t 228 smb_com_locking_andx(smb_request_t *sr) 229 { 230 unsigned short i; 231 unsigned char lock_type; /* See lock_type table above */ 232 unsigned char oplock_level; /* The new oplock level */ 233 uint32_t timeout; /* Milliseconds to wait for lock */ 234 unsigned short unlock_num; /* # unlock range structs */ 235 unsigned short lock_num; /* # lock range structs */ 236 unsigned short pid; /* Process Id of owner */ 237 uint32_t offset32, length32; 238 uint64_t offset64; 239 uint64_t length64; 240 DWORD result; 241 int rc; 242 uint32_t ltype; 243 smb_ofile_t *ofile; 244 uint8_t brk; 245 246 rc = smbsr_decode_vwv(sr, "4.wbblww", &sr->smb_fid, &lock_type, 247 &oplock_level, &timeout, &unlock_num, &lock_num); 248 if (rc != 0) 249 return (SDRC_ERROR); 250 251 smbsr_lookup_file(sr); 252 if (sr->fid_ofile == NULL) { 253 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid); 254 return (SDRC_ERROR); 255 } 256 ofile = sr->fid_ofile; 257 258 if (lock_type & LOCKING_ANDX_SHARED_LOCK) 259 ltype = SMB_LOCK_TYPE_READONLY; 260 else 261 ltype = SMB_LOCK_TYPE_READWRITE; 262 263 pid = sr->smb_pid; /* Save the original pid */ 264 265 if (lock_type & LOCKING_ANDX_OPLOCK_RELEASE) { 266 if (oplock_level == 0) 267 brk = SMB_OPLOCK_BREAK_TO_NONE; 268 else 269 brk = SMB_OPLOCK_BREAK_TO_LEVEL_II; 270 smb_oplock_ack(ofile->f_node, ofile, brk); 271 if (unlock_num == 0 && lock_num == 0) 272 return (SDRC_NO_REPLY); 273 } 274 275 /* 276 * No support for changing locktype (although we could probably 277 * implement this) 278 */ 279 if (lock_type & LOCKING_ANDX_CHANGE_LOCK_TYPE) { 280 smbsr_error(sr, 0, ERRDOS, 281 ERROR_ATOMIC_LOCKS_NOT_SUPPORTED); 282 return (SDRC_ERROR); 283 } 284 285 /* 286 * No support for cancel lock (smbtorture expects this) 287 */ 288 if (lock_type & LOCKING_ANDX_CANCEL_LOCK) { 289 smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 290 ERRDOS, ERROR_INVALID_PARAMETER); 291 return (SDRC_ERROR); 292 } 293 294 if (lock_type & LOCKING_ANDX_LARGE_FILES) { 295 /* 296 * negotiated protocol should be NT LM 0.12 or later 297 */ 298 if (sr->session->dialect < NT_LM_0_12) { 299 smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 300 ERRDOS, ERROR_INVALID_PARAMETER); 301 return (SDRC_ERROR); 302 } 303 304 for (i = 0; i < unlock_num; i++) { 305 rc = smb_mbc_decodef(&sr->smb_data, "w2.QQ", 306 &sr->smb_pid, &offset64, &length64); 307 if (rc) { 308 /* 309 * This is the error returned by Windows 2000 310 * even when STATUS32 has been negotiated. 311 */ 312 smbsr_error(sr, 0, ERRSRV, ERRerror); 313 return (SDRC_ERROR); 314 } 315 316 result = smb_unlock_range(sr, sr->fid_ofile->f_node, 317 offset64, length64); 318 if (result != NT_STATUS_SUCCESS) { 319 smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED, 320 ERRDOS, ERROR_NOT_LOCKED); 321 return (SDRC_ERROR); 322 } 323 } 324 325 for (i = 0; i < lock_num; i++) { 326 rc = smb_mbc_decodef(&sr->smb_data, "w2.QQ", 327 &sr->smb_pid, &offset64, &length64); 328 if (rc) { 329 smbsr_error(sr, 0, ERRSRV, ERRerror); 330 return (SDRC_ERROR); 331 } 332 333 result = smb_lock_range(sr, offset64, length64, timeout, 334 ltype); 335 if (result != NT_STATUS_SUCCESS) { 336 smb_lock_range_error(sr, result); 337 return (SDRC_ERROR); 338 } 339 } 340 } else { 341 for (i = 0; i < unlock_num; i++) { 342 rc = smb_mbc_decodef(&sr->smb_data, "wll", &sr->smb_pid, 343 &offset32, &length32); 344 if (rc) { 345 smbsr_error(sr, 0, ERRSRV, ERRerror); 346 return (SDRC_ERROR); 347 } 348 349 result = smb_unlock_range(sr, sr->fid_ofile->f_node, 350 (uint64_t)offset32, (uint64_t)length32); 351 if (result != NT_STATUS_SUCCESS) { 352 smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED, 353 ERRDOS, ERROR_NOT_LOCKED); 354 return (SDRC_ERROR); 355 } 356 } 357 358 for (i = 0; i < lock_num; i++) { 359 rc = smb_mbc_decodef(&sr->smb_data, "wll", &sr->smb_pid, 360 &offset32, &length32); 361 if (rc) { 362 smbsr_error(sr, 0, ERRSRV, ERRerror); 363 return (SDRC_ERROR); 364 } 365 366 result = smb_lock_range(sr, (uint64_t)offset32, 367 (uint64_t)length32, timeout, ltype); 368 if (result != NT_STATUS_SUCCESS) { 369 smb_lock_range_error(sr, result); 370 return (SDRC_ERROR); 371 } 372 } 373 } 374 375 sr->smb_pid = pid; 376 if (smbsr_encode_result(sr, 2, 0, "bb.ww", 2, sr->andx_com, 7, 0)) 377 return (SDRC_ERROR); 378 return (SDRC_SUCCESS); 379 } 380