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