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