xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_open_andx.c (revision 93bc28dbaee6387120d48b12b3dc1ba5f7418e6e)
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 /*
22cb174861Sjoyce mcintosh  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23*93bc28dbSGordon Ross  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
24da6c28aaSamw  */
25da6c28aaSamw 
26bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h>
27c5f48fa5SGordon Ross #include <smbsrv/smb_fsops.h>
28da6c28aaSamw #include <smbsrv/smb_vops.h>
292c2961f8Sjose borrego 
302c2961f8Sjose borrego int smb_open_dsize_check = 0;
31da6c28aaSamw 
32da6c28aaSamw /*
33da6c28aaSamw  *  Client Request                     Description
34da6c28aaSamw  *  ================================== =================================
35da6c28aaSamw  *
36da6c28aaSamw  *  UCHAR WordCount;                   Count of parameter words = 15
37da6c28aaSamw  *  UCHAR AndXCommand;                 Secondary (X) command;  0xFF =
38da6c28aaSamw  *                                      none
39da6c28aaSamw  *  UCHAR AndXReserved;                Reserved (must be 0)
40da6c28aaSamw  *  USHORT AndXOffset;                 Offset to next command WordCount
41da6c28aaSamw  *  USHORT Flags;                      Additional information: bit set-
42da6c28aaSamw  *                                      0 - return additional info
43da6c28aaSamw  *                                      1 - exclusive oplock requested
44da6c28aaSamw  *                                      2 - batch oplock requested
45da6c28aaSamw  *  USHORT DesiredAccess;              File open mode
46da6c28aaSamw  *  USHORT SearchAttributes;
47da6c28aaSamw  *  USHORT FileAttributes;
48da6c28aaSamw  *  UTIME CreationTime;                Creation timestamp for file if it
49da6c28aaSamw  *                                      gets created
50da6c28aaSamw  *  USHORT OpenFunction;               Action to take if file exists
51da6c28aaSamw  *  ULONG AllocationSize;              Bytes to reserve on create or
52da6c28aaSamw  *                                      truncate
53da6c28aaSamw  *  ULONG Reserved[2];                 Must be 0
54da6c28aaSamw  *  USHORT ByteCount;                  Count of data bytes;    min = 1
55da6c28aaSamw  *  UCHAR BufferFormat                 0x04
56da6c28aaSamw  *  STRING FileName;
57da6c28aaSamw  *
58da6c28aaSamw  *  Server Response                    Description
59da6c28aaSamw  *  ================================== =================================
60da6c28aaSamw  *
61da6c28aaSamw  *  UCHAR WordCount;                   Count of parameter words = 15
62da6c28aaSamw  *  UCHAR AndXCommand;                 Secondary (X) command;  0xFF =
63da6c28aaSamw  *                                      none
64da6c28aaSamw  *  UCHAR AndXReserved;                Reserved (must be 0)
65da6c28aaSamw  *  USHORT AndXOffset;                 Offset to next command WordCount
66da6c28aaSamw  *  USHORT Fid;                        File handle
67da6c28aaSamw  *  USHORT FileAttributes;
68da6c28aaSamw  *  UTIME LastWriteTime;
69da6c28aaSamw  *  ULONG DataSize;                    Current file size
70da6c28aaSamw  *  USHORT GrantedAccess;              Access permissions actually
71da6c28aaSamw  *                                      allowed
72da6c28aaSamw  *  USHORT FileType;                   Type of file opened
73da6c28aaSamw  *  USHORT DeviceState;                State of the named pipe
74da6c28aaSamw  *  USHORT Action;                     Action taken
75da6c28aaSamw  *  ULONG ServerFid;                   Server unique file id
76da6c28aaSamw  *  USHORT Reserved;                   Reserved (must be 0)
77da6c28aaSamw  *  USHORT ByteCount;                  Count of data bytes = 0
78da6c28aaSamw  *
79da6c28aaSamw  * DesiredAccess describes the access the client desires for the file (see
80da6c28aaSamw  * section 3.6 -  Access Mode Encoding).
81da6c28aaSamw  *
82da6c28aaSamw  * OpenFunction specifies the action to be taken depending on whether or
83da6c28aaSamw  * not the file exists (see section 3.8 -  Open Function Encoding).  Action
84da6c28aaSamw  *
85da6c28aaSamw  * in the response specifies the action as a result of the Open request
86da6c28aaSamw  * (see section 3.9 -  Open Action Encoding).
87da6c28aaSamw  *
88da6c28aaSamw  * SearchAttributes indicates the attributes that the file must have to be
89da6c28aaSamw  * found while searching to see if it exists.  The encoding of this field
90da6c28aaSamw  * is described in the "File Attribute Encoding" section elsewhere in this
91da6c28aaSamw  * document.  If SearchAttributes is zero then only normal files are
92da6c28aaSamw  * returned.  If the system file, hidden or directory attributes are
93da6c28aaSamw  * specified then the search is inclusive -- both the specified type(s) of
94da6c28aaSamw  * files and normal files are returned.
95da6c28aaSamw  *
96da6c28aaSamw  * FileType returns the kind of resource actually opened:
97da6c28aaSamw  *
98da6c28aaSamw  *  Name                       Value  Description
99da6c28aaSamw  *  ========================== ====== ==================================
100da6c28aaSamw  *
101da6c28aaSamw  *  FileTypeDisk               0      Disk file or directory as defined
102da6c28aaSamw  *                                     in the attribute field
103da6c28aaSamw  *  FileTypeByteModePipe       1      Named pipe in byte mode
104da6c28aaSamw  *  FileTypeMessageModePipe    2      Named pipe in message mode
105da6c28aaSamw  *  FileTypePrinter            3      Spooled printer
106da6c28aaSamw  *  FileTypeUnknown            0xFFFF Unrecognized resource type
107da6c28aaSamw  *
108da6c28aaSamw  * If bit0 of Flags is clear, the FileAttributes, LastWriteTime, DataSize,
109da6c28aaSamw  * FileType, and DeviceState have indeterminate values in the response.
110da6c28aaSamw  *
111da6c28aaSamw  * This SMB can request an oplock on the opened file.  Oplocks are fully
112da6c28aaSamw  * described in the "Oplocks" section elsewhere in this document, and there
113da6c28aaSamw  * is also discussion of oplocks in the SMB_COM_LOCKING_ANDX SMB
114da6c28aaSamw  * description.  Bit1 and bit2 of the Flags field are used to request
115da6c28aaSamw  * oplocks during open.
116da6c28aaSamw  *
117da6c28aaSamw  * The following SMBs may follow SMB_COM_OPEN_ANDX:
118da6c28aaSamw  *
119da6c28aaSamw  *    SMB_COM_READ    SMB_COM_READ_ANDX
120da6c28aaSamw  *    SMB_COM_IOCTL
121da6c28aaSamw  */
122da6c28aaSamw 
123da6c28aaSamw /*
124da6c28aaSamw  * This message is sent to obtain a file handle for a data file.  This
125da6c28aaSamw  * returned Fid is used in subsequent client requests such as read, write,
126da6c28aaSamw  * close, etc.
127da6c28aaSamw  *
128da6c28aaSamw  * Client Request                     Description
129da6c28aaSamw  * ================================== =================================
130da6c28aaSamw  *
131da6c28aaSamw  * UCHAR WordCount;                   Count of parameter words = 2
132da6c28aaSamw  * USHORT DesiredAccess;              Mode - read/write/share
133da6c28aaSamw  * USHORT SearchAttributes;
134da6c28aaSamw  * USHORT ByteCount;                  Count of data bytes;    min = 2
135da6c28aaSamw  * UCHAR BufferFormat;                0x04
136da6c28aaSamw  * STRING FileName[];                 File name
137da6c28aaSamw  *
138da6c28aaSamw  * FileName is the fully qualified file name, relative to the root of the
139da6c28aaSamw  * share specified in the Tid field of the SMB header.  If Tid in the SMB
140da6c28aaSamw  * header refers to a print share, this SMB creates a new file which will
141da6c28aaSamw  * be spooled to the printer when closed.  In this case, FileName is
142da6c28aaSamw  * ignored.
143da6c28aaSamw  *
144da6c28aaSamw  * SearchAttributes specifies the type of file desired.  The encoding is
145da6c28aaSamw  * described in the "File Attribute Encoding" section.
146da6c28aaSamw  *
147da6c28aaSamw  * DesiredAccess controls the mode under which the file is opened, and the
148da6c28aaSamw  * file will be opened only if the client has the appropriate permissions.
149da6c28aaSamw  * The encoding of DesiredAccess is discussed in the section entitled
150da6c28aaSamw  * "Access Mode Encoding".
151da6c28aaSamw  *
152da6c28aaSamw  * Server Response                    Description
153da6c28aaSamw  * ================================== =================================
154da6c28aaSamw  *
155da6c28aaSamw  * UCHAR WordCount;                   Count of parameter words = 7
156da6c28aaSamw  * USHORT Fid;                        File handle
157da6c28aaSamw  * USHORT FileAttributes;             Attributes of opened file
158da6c28aaSamw  * UTIME LastWriteTime;               Time file was last written
159da6c28aaSamw  * ULONG DataSize;                    File size
160da6c28aaSamw  * USHORT GrantedAccess;              Access allowed
161da6c28aaSamw  * USHORT ByteCount;                  Count of data bytes = 0
162da6c28aaSamw  *
163da6c28aaSamw  * Fid is the handle value which should be used for subsequent file
164da6c28aaSamw  * operations.
165da6c28aaSamw  *
166da6c28aaSamw  * FileAttributes specifies the type of file obtained.  The encoding is
167da6c28aaSamw  * described in the "File Attribute Encoding" section.
168da6c28aaSamw  *
169da6c28aaSamw  * GrantedAccess indicates the access permissions actually allowed, and may
170da6c28aaSamw  * have one of the following values:
171da6c28aaSamw  *
172da6c28aaSamw  *    0  read-only
173da6c28aaSamw  *    1  write-only
174da6c28aaSamw  *    2 read/write
175da6c28aaSamw  *
176da6c28aaSamw  * File Handles (Fids) are scoped per client.  A Pid may reference any Fid
177da6c28aaSamw  * established by itself or any other Pid on the client (so far as the
178da6c28aaSamw  * server is concerned).  The actual accesses allowed through the Fid
179da6c28aaSamw  * depends on the open and deny modes specified when the file was opened
180da6c28aaSamw  * (see below).
181da6c28aaSamw  *
182da6c28aaSamw  * The MS-DOS compatibility mode of file open provides exclusion at the
183da6c28aaSamw  * client level.  A file open in compatibility mode may be opened (also in
184da6c28aaSamw  * compatibility mode) any number of times for any combination of reading
185da6c28aaSamw  * and writing (subject to the user's permissions) by any Pid on the same
186da6c28aaSamw  * client.  If the first client has the file open for writing, then the
187da6c28aaSamw  * file may not be opened in any way by any other client.  If the first
188da6c28aaSamw  * client has the file open only for reading, then other clients may open
189da6c28aaSamw  * the file, in compatibility mode, for reading..  The above
190da6c28aaSamw  * notwithstanding, if the filename has an extension of .EXE, .DLL, .SYM,
191da6c28aaSamw  * or .COM other clients are permitted to open the file regardless of
192da6c28aaSamw  * read/write open modes of other compatibility mode opens.  However, once
193da6c28aaSamw  * multiple clients have the file open for reading, no client is permitted
194da6c28aaSamw  * to open the file for writing and no other client may open the file in
195da6c28aaSamw  * any mode other than compatibility mode.
196da6c28aaSamw  *
197da6c28aaSamw  * The other file exclusion modes (Deny read/write, Deny write, Deny read,
198da6c28aaSamw  * Deny none) provide exclusion at the file level.  A file opened in any
199da6c28aaSamw  * "Deny" mode may be opened again only for the accesses allowed by the
200da6c28aaSamw  * Deny mode (subject to the user's permissions).  This is true regardless
201da6c28aaSamw  * of the identity of the second opener -a different client, a Pid from the
202da6c28aaSamw  * same client, or the Pid that already has the file open.  For example, if
203da6c28aaSamw  * a file is open in "Deny write" mode a second open may only obtain read
204da6c28aaSamw  * permission to the file.
205da6c28aaSamw  *
206da6c28aaSamw  * Although Fids are available to all Pids on a client, Pids other than the
207da6c28aaSamw  * owner may not have the full access rights specified in the open mode by
208da6c28aaSamw  * the Fid's creator.  If the open creating the Fid specified a deny mode,
209da6c28aaSamw  * then any Pid using the Fid, other than the creating Pid, will have only
210da6c28aaSamw  * those access rights determined by "anding" the open mode rights and the
211da6c28aaSamw  * deny mode rights, i.e., the deny mode is checked on all file accesses.
212da6c28aaSamw  * For example, if a file is opened for Read/Write in Deny write mode, then
213da6c28aaSamw  * other clients may only read the file and cannot write; if a file is
214da6c28aaSamw  * opened for Read in Deny read mode, then the other clients can neither
215da6c28aaSamw  * read nor write the file.
216da6c28aaSamw  */
217da6c28aaSamw 
2187b59d02dSjb150015 smb_sdrc_t
219faa1795aSjb150015 smb_pre_open(smb_request_t *sr)
220faa1795aSjb150015 {
221faa1795aSjb150015 	struct open_param *op = &sr->arg.open;
222faa1795aSjb150015 	int rc;
223faa1795aSjb150015 
224faa1795aSjb150015 	bzero(op, sizeof (sr->arg.open));
225faa1795aSjb150015 
226eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	rc = smbsr_decode_vwv(sr, "ww", &op->omode, &op->fqi.fq_sattr);
227faa1795aSjb150015 	if (rc == 0)
228eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		rc = smbsr_decode_data(sr, "%S", sr, &op->fqi.fq_path.pn_path);
229faa1795aSjb150015 
230*93bc28dbSGordon Ross 	DTRACE_SMB_START(op__Open, smb_request_t *, sr); /* arg.open */
231faa1795aSjb150015 
232faa1795aSjb150015 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
233faa1795aSjb150015 }
234faa1795aSjb150015 
235faa1795aSjb150015 void
236faa1795aSjb150015 smb_post_open(smb_request_t *sr)
237faa1795aSjb150015 {
238*93bc28dbSGordon Ross 	DTRACE_SMB_DONE(op__Open, smb_request_t *, sr);
239faa1795aSjb150015 }
240faa1795aSjb150015 
241faa1795aSjb150015 smb_sdrc_t
242faa1795aSjb150015 smb_com_open(smb_request_t *sr)
243da6c28aaSamw {
244da6c28aaSamw 	struct open_param *op = &sr->arg.open;
2455fd03bc0SGordon Ross 	smb_ofile_t *of;
246037cac00Sjoyce mcintosh 	smb_attr_t attr;
247a90cf9f2SGordon Ross 	uint32_t status;
248da6c28aaSamw 	uint16_t file_attr;
2497b59d02dSjb150015 	int rc;
250da6c28aaSamw 
251da6c28aaSamw 	op->desired_access = smb_omode_to_amask(op->omode);
252eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	op->share_access = smb_denymode_to_sharemode(op->omode,
253eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    op->fqi.fq_path.pn_path);
2548c10a865Sas200622 	op->crtime.tv_sec = op->crtime.tv_nsec = 0;
255da6c28aaSamw 	op->create_disposition = FILE_OPEN;
2562c1b14e5Sjose borrego 	op->create_options = FILE_NON_DIRECTORY_FILE;
2572c1b14e5Sjose borrego 	if (op->omode & SMB_DA_WRITE_THROUGH)
2582c1b14e5Sjose borrego 		op->create_options |= FILE_WRITE_THROUGH;
259da6c28aaSamw 
260da6c28aaSamw 	if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
2612c2961f8Sjose borrego 		if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
2622c2961f8Sjose borrego 			op->op_oplock_level = SMB_OPLOCK_BATCH;
2632c2961f8Sjose borrego 		else
2642c2961f8Sjose borrego 			op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
265da6c28aaSamw 	} else {
2662c2961f8Sjose borrego 		op->op_oplock_level = SMB_OPLOCK_NONE;
267da6c28aaSamw 	}
268cb174861Sjoyce mcintosh 	op->op_oplock_levelII = B_FALSE;
269da6c28aaSamw 
2705fd03bc0SGordon Ross 	if (smb_open_dsize_check && op->dsize > UINT_MAX) {
2715fd03bc0SGordon Ross 		smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
2725fd03bc0SGordon Ross 		return (SDRC_ERROR);
2735fd03bc0SGordon Ross 	}
2745fd03bc0SGordon Ross 
275a90cf9f2SGordon Ross 	status = smb_common_open(sr);
276a90cf9f2SGordon Ross 	if (status != NT_STATUS_SUCCESS) {
277a90cf9f2SGordon Ross 		smbsr_status(sr, status, 0, 0);
278faa1795aSjb150015 		return (SDRC_ERROR);
279a90cf9f2SGordon Ross 	}
280da6c28aaSamw 
2815fd03bc0SGordon Ross 	/*
2825fd03bc0SGordon Ross 	 * NB: after the above smb_common_open() success,
2835fd03bc0SGordon Ross 	 * we have a handle allocated (sr->fid_ofile).
2845fd03bc0SGordon Ross 	 * If we don't return success, we must close it.
2855fd03bc0SGordon Ross 	 */
2865fd03bc0SGordon Ross 	of = sr->fid_ofile;
2875fd03bc0SGordon Ross 
2882c2961f8Sjose borrego 	if (op->op_oplock_level == SMB_OPLOCK_NONE) {
289da6c28aaSamw 		sr->smb_flg &=
290da6c28aaSamw 		    ~(SMB_FLAGS_OPLOCK | SMB_FLAGS_OPLOCK_NOTIFY_ANY);
291da6c28aaSamw 	}
292da6c28aaSamw 
293da6c28aaSamw 	file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
2945fd03bc0SGordon Ross 	bzero(&attr, sizeof (attr));
2955fd03bc0SGordon Ross 	attr.sa_mask = SMB_AT_MTIME;
2965fd03bc0SGordon Ross 	rc = smb_node_getattr(sr, of->f_node, of->f_cr, of, &attr);
2975fd03bc0SGordon Ross 	if (rc != 0) {
2985fd03bc0SGordon Ross 		smbsr_errno(sr, rc);
2995fd03bc0SGordon Ross 		goto errout;
300037cac00Sjoyce mcintosh 	}
301da6c28aaSamw 
3027b59d02dSjb150015 	rc = smbsr_encode_result(sr, 7, 0, "bwwllww",
303da6c28aaSamw 	    7,
304da6c28aaSamw 	    sr->smb_fid,
305da6c28aaSamw 	    file_attr,
306e3f2c991SKeyur Desai 	    smb_time_gmt_to_local(sr, attr.sa_vattr.va_mtime.tv_sec),
307da6c28aaSamw 	    (uint32_t)op->dsize,
3082c2961f8Sjose borrego 	    op->omode,
309da6c28aaSamw 	    (uint16_t)0);	/* bcc */
310da6c28aaSamw 
3115fd03bc0SGordon Ross 	if (rc == 0)
3125fd03bc0SGordon Ross 		return (SDRC_SUCCESS);
3135fd03bc0SGordon Ross 
3145fd03bc0SGordon Ross errout:
3155fd03bc0SGordon Ross 	smb_ofile_close(of, 0);
3165fd03bc0SGordon Ross 	return (SDRC_ERROR);
317da6c28aaSamw }
318da6c28aaSamw 
319c5f48fa5SGordon Ross int smb_openx_enable_extended_response = 1;
320c5f48fa5SGordon Ross 
3212c1b14e5Sjose borrego /*
3222c1b14e5Sjose borrego  * smb_pre_open_andx
3232c1b14e5Sjose borrego  * For compatibility with windows servers, the search attributes
3242c1b14e5Sjose borrego  * specified in the request are ignored.
3252c1b14e5Sjose borrego  */
3267b59d02dSjb150015 smb_sdrc_t
327faa1795aSjb150015 smb_pre_open_andx(smb_request_t *sr)
328da6c28aaSamw {
329da6c28aaSamw 	struct open_param *op = &sr->arg.open;
330c5f48fa5SGordon Ross 	uint16_t openx_flags;
331a90cf9f2SGordon Ross 	uint32_t alloc_size;
3328c10a865Sas200622 	uint32_t creation_time;
3332c1b14e5Sjose borrego 	uint16_t file_attr, sattr;
334da6c28aaSamw 	int rc;
335da6c28aaSamw 
336da6c28aaSamw 	bzero(op, sizeof (sr->arg.open));
337faa1795aSjb150015 
338da6c28aaSamw 	rc = smbsr_decode_vwv(sr, "b.wwwwwlwll4.", &sr->andx_com,
339c5f48fa5SGordon Ross 	    &sr->andx_off, &openx_flags, &op->omode, &sattr,
340a90cf9f2SGordon Ross 	    &file_attr, &creation_time, &op->ofun, &alloc_size, &op->timeo);
341da6c28aaSamw 
342faa1795aSjb150015 	if (rc == 0) {
343eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		rc = smbsr_decode_data(sr, "%u", sr, &op->fqi.fq_path.pn_path);
344faa1795aSjb150015 
345faa1795aSjb150015 		op->dattr = file_attr;
346a90cf9f2SGordon Ross 		op->dsize = alloc_size;
347faa1795aSjb150015 
348c5f48fa5SGordon Ross 		/*
349c5f48fa5SGordon Ross 		 * The openx_flags use some "extended" flags that
350c5f48fa5SGordon Ross 		 * happen to match some of the NtCreateX flags.
351c5f48fa5SGordon Ross 		 */
352c5f48fa5SGordon Ross 		if (openx_flags & NT_CREATE_FLAG_REQUEST_OPLOCK)
3532c2961f8Sjose borrego 			op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
354c5f48fa5SGordon Ross 		else if (openx_flags & NT_CREATE_FLAG_REQUEST_OPBATCH)
3552c2961f8Sjose borrego 			op->op_oplock_level = SMB_OPLOCK_BATCH;
3562c2961f8Sjose borrego 		else
3572c2961f8Sjose borrego 			op->op_oplock_level = SMB_OPLOCK_NONE;
358c5f48fa5SGordon Ross 		if (openx_flags & NT_CREATE_FLAG_EXTENDED_RESPONSE)
359c5f48fa5SGordon Ross 			op->nt_flags |= NT_CREATE_FLAG_EXTENDED_RESPONSE;
360faa1795aSjb150015 
3618c10a865Sas200622 		if ((creation_time != 0) && (creation_time != UINT_MAX))
362e3f2c991SKeyur Desai 			op->crtime.tv_sec =
363e3f2c991SKeyur Desai 			    smb_time_local_to_gmt(sr, creation_time);
3648c10a865Sas200622 		op->crtime.tv_nsec = 0;
365faa1795aSjb150015 
3662c2961f8Sjose borrego 		op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
367faa1795aSjb150015 	}
368faa1795aSjb150015 
369*93bc28dbSGordon Ross 	DTRACE_SMB_START(op__OpenX, smb_request_t *, sr); /* arg.open */
370faa1795aSjb150015 
371faa1795aSjb150015 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
372faa1795aSjb150015 }
373faa1795aSjb150015 
374faa1795aSjb150015 void
375faa1795aSjb150015 smb_post_open_andx(smb_request_t *sr)
376faa1795aSjb150015 {
377*93bc28dbSGordon Ross 	DTRACE_SMB_DONE(op__OpenX, smb_request_t *, sr);
378faa1795aSjb150015 }
379faa1795aSjb150015 
380faa1795aSjb150015 smb_sdrc_t
381faa1795aSjb150015 smb_com_open_andx(smb_request_t *sr)
382faa1795aSjb150015 {
383faa1795aSjb150015 	struct open_param	*op = &sr->arg.open;
384c5f48fa5SGordon Ross 	smb_attr_t		*ap = &op->fqi.fq_fattr;
3855fd03bc0SGordon Ross 	smb_ofile_t		*of;
386a90cf9f2SGordon Ross 	uint32_t		status;
387c5f48fa5SGordon Ross 	uint32_t		mtime_sec;
388faa1795aSjb150015 	uint16_t		file_attr;
389faa1795aSjb150015 	int rc;
390da6c28aaSamw 
391da6c28aaSamw 	op->desired_access = smb_omode_to_amask(op->omode);
392eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	op->share_access = smb_denymode_to_sharemode(op->omode,
393eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    op->fqi.fq_path.pn_path);
394da6c28aaSamw 
3952c2961f8Sjose borrego 	if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) {
3962c2961f8Sjose borrego 		smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
397faa1795aSjb150015 		return (SDRC_ERROR);
398da6c28aaSamw 	}
399da6c28aaSamw 
4002c1b14e5Sjose borrego 	op->create_options = FILE_NON_DIRECTORY_FILE;
4012c1b14e5Sjose borrego 	if (op->omode & SMB_DA_WRITE_THROUGH)
4022c1b14e5Sjose borrego 		op->create_options |= FILE_WRITE_THROUGH;
403da6c28aaSamw 
404cb174861Sjoyce mcintosh 	op->op_oplock_levelII = B_FALSE;
405cb174861Sjoyce mcintosh 
4062c2961f8Sjose borrego 	if (smb_open_dsize_check && op->dsize > UINT_MAX) {
4072c2961f8Sjose borrego 		smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
408faa1795aSjb150015 		return (SDRC_ERROR);
4097b59d02dSjb150015 	}
410da6c28aaSamw 
411a90cf9f2SGordon Ross 	status = smb_common_open(sr);
412a90cf9f2SGordon Ross 	if (status != NT_STATUS_SUCCESS) {
413a90cf9f2SGordon Ross 		smbsr_status(sr, status, 0, 0);
4145fd03bc0SGordon Ross 		return (SDRC_ERROR);
415a90cf9f2SGordon Ross 	}
4165fd03bc0SGordon Ross 
4175fd03bc0SGordon Ross 	/*
4185fd03bc0SGordon Ross 	 * NB: after the above smb_common_open() success,
4195fd03bc0SGordon Ross 	 * we have a handle allocated (sr->fid_ofile).
4205fd03bc0SGordon Ross 	 * If we don't return success, we must close it.
4215fd03bc0SGordon Ross 	 */
4225fd03bc0SGordon Ross 	of = sr->fid_ofile;
4235fd03bc0SGordon Ross 
4242c2961f8Sjose borrego 	if (op->op_oplock_level != SMB_OPLOCK_NONE)
425c5f48fa5SGordon Ross 		op->action_taken |= SMB_OACT_OPLOCK;
4262c2961f8Sjose borrego 	else
427c5f48fa5SGordon Ross 		op->action_taken &= ~SMB_OACT_OPLOCK;
428da6c28aaSamw 
429da6c28aaSamw 	file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
430c5f48fa5SGordon Ross 	mtime_sec = smb_time_gmt_to_local(sr, ap->sa_vattr.va_mtime.tv_sec);
431037cac00Sjoyce mcintosh 
432f96bd5c8SAlan Wright 	switch (sr->tid_tree->t_res_type & STYPE_MASK) {
433f96bd5c8SAlan Wright 	case STYPE_DISKTREE:
434f96bd5c8SAlan Wright 	case STYPE_PRINTQ:
435f96bd5c8SAlan Wright 		break;
436f96bd5c8SAlan Wright 
437f96bd5c8SAlan Wright 	case STYPE_IPC:
438c5f48fa5SGordon Ross 		mtime_sec = 0;
439f96bd5c8SAlan Wright 		break;
440f96bd5c8SAlan Wright 
441f96bd5c8SAlan Wright 	default:
442f96bd5c8SAlan Wright 		smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
443f96bd5c8SAlan Wright 		    ERRDOS, ERROR_INVALID_FUNCTION);
4445fd03bc0SGordon Ross 		goto errout;
445da6c28aaSamw 	}
446da6c28aaSamw 
447c5f48fa5SGordon Ross 	if ((op->nt_flags & NT_CREATE_FLAG_EXTENDED_RESPONSE) != 0 &&
448c5f48fa5SGordon Ross 	    smb_openx_enable_extended_response != 0) {
449c5f48fa5SGordon Ross 		uint32_t MaxAccess = 0;
450c5f48fa5SGordon Ross 		if (of->f_node != NULL) {
451c5f48fa5SGordon Ross 			smb_fsop_eaccess(sr, of->f_cr, of->f_node, &MaxAccess);
452c5f48fa5SGordon Ross 		}
453c5f48fa5SGordon Ross 		MaxAccess |= of->f_granted_access;
454c5f48fa5SGordon Ross 
455c5f48fa5SGordon Ross 		rc = smbsr_encode_result(
456c5f48fa5SGordon Ross 		    sr, 19, 0, "bb.wwwllwwwwl2.llw",
457c5f48fa5SGordon Ross 		    19,		/* word count	   (b) */
458c5f48fa5SGordon Ross 		    sr->andx_com,		/* (b.) */
459c5f48fa5SGordon Ross 		    VAR_BCC,	/* andx offset	   (w) */
460c5f48fa5SGordon Ross 		    sr->smb_fid,		/* (w) */
461c5f48fa5SGordon Ross 		    file_attr,			/* (w) */
462c5f48fa5SGordon Ross 		    mtime_sec,			/* (l) */
463c5f48fa5SGordon Ross 		    (uint32_t)op->dsize,	/* (l) */
464c5f48fa5SGordon Ross 		    op->omode,			/* (w) */
465c5f48fa5SGordon Ross 		    op->ftype,			/* (w) */
466c5f48fa5SGordon Ross 		    op->devstate,		/* (w) */
467c5f48fa5SGordon Ross 		    op->action_taken,		/* (w) */
468c5f48fa5SGordon Ross 		    0,		/* legacy fileid   (l) */
469c5f48fa5SGordon Ross 		    /* reserved			  (2.) */
470c5f48fa5SGordon Ross 		    MaxAccess,			/* (l) */
471c5f48fa5SGordon Ross 		    0,		/* guest access	   (l) */
472c5f48fa5SGordon Ross 		    0);		/* byte count	   (w) */
473c5f48fa5SGordon Ross 
474c5f48fa5SGordon Ross 	} else {
475c5f48fa5SGordon Ross 		rc = smbsr_encode_result(
476c5f48fa5SGordon Ross 		    sr, 15, 0, "bb.wwwllwwwwl2.w",
477c5f48fa5SGordon Ross 		    15,		/* word count	   (b) */
478c5f48fa5SGordon Ross 		    sr->andx_com,		/* (b.) */
479c5f48fa5SGordon Ross 		    VAR_BCC,	/* andx offset	   (w) */
480c5f48fa5SGordon Ross 		    sr->smb_fid,		/* (w) */
481c5f48fa5SGordon Ross 		    file_attr,			/* (w) */
482c5f48fa5SGordon Ross 		    mtime_sec,			/* (l) */
483c5f48fa5SGordon Ross 		    (uint32_t)op->dsize,	/* (l) */
484c5f48fa5SGordon Ross 		    op->omode,			/* (w) */
485c5f48fa5SGordon Ross 		    op->ftype,			/* (w) */
486c5f48fa5SGordon Ross 		    op->devstate,		/* (w) */
487c5f48fa5SGordon Ross 		    op->action_taken,		/* (w) */
488c5f48fa5SGordon Ross 		    0,		/* legacy fileid   (l) */
489c5f48fa5SGordon Ross 		    /* reserved			  (2.) */
490c5f48fa5SGordon Ross 		    0);		/* byte count	   (w) */
491c5f48fa5SGordon Ross 	}
492c5f48fa5SGordon Ross 
4935fd03bc0SGordon Ross 	if (rc == 0)
4945fd03bc0SGordon Ross 		return (SDRC_SUCCESS);
4955fd03bc0SGordon Ross 
4965fd03bc0SGordon Ross errout:
4975fd03bc0SGordon Ross 	smb_ofile_close(of, 0);
4985fd03bc0SGordon Ross 	return (SDRC_ERROR);
499da6c28aaSamw }
5002c2961f8Sjose borrego 
5012c2961f8Sjose borrego smb_sdrc_t
5022c2961f8Sjose borrego smb_com_trans2_open2(smb_request_t *sr, smb_xa_t *xa)
5032c2961f8Sjose borrego {
5042c2961f8Sjose borrego 	struct open_param *op = &sr->arg.open;
5052c2961f8Sjose borrego 	uint32_t	creation_time;
5062c2961f8Sjose borrego 	uint32_t	alloc_size;
5073bd40d98SGordon Ross 	uint32_t	ea_list_size;
5082c2961f8Sjose borrego 	uint16_t	flags;
5092c2961f8Sjose borrego 	uint16_t	file_attr;
510a90cf9f2SGordon Ross 	uint32_t	status;
5112c2961f8Sjose borrego 	int		rc;
5122c2961f8Sjose borrego 
5132c2961f8Sjose borrego 	bzero(op, sizeof (sr->arg.open));
5142c2961f8Sjose borrego 
5152c2961f8Sjose borrego 	rc = smb_mbc_decodef(&xa->req_param_mb, "%wwwwlwl10.u",
516eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    sr, &flags, &op->omode, &op->fqi.fq_sattr, &file_attr,
517eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    &creation_time, &op->ofun, &alloc_size, &op->fqi.fq_path.pn_path);
5182c2961f8Sjose borrego 	if (rc != 0)
5192c2961f8Sjose borrego 		return (SDRC_ERROR);
5202c2961f8Sjose borrego 
5213bd40d98SGordon Ross 	/*
5223bd40d98SGordon Ross 	 * The data part of this transaction may contain an EA list.
5233bd40d98SGordon Ross 	 * See: SMB_FEA_LIST ExtendedAttributeList
5243bd40d98SGordon Ross 	 *
5253bd40d98SGordon Ross 	 * If we find a non-empty EA list payload, return the special
5263bd40d98SGordon Ross 	 * error that tells the caller this FS does not suport EAs.
5273bd40d98SGordon Ross 	 *
5283bd40d98SGordon Ross 	 * Note: the first word is the size of the whole data segment,
5293bd40d98SGordon Ross 	 * INCLUDING the size of that length word.  That means if
5303bd40d98SGordon Ross 	 * the length word specifies a size less than four, it's
5313bd40d98SGordon Ross 	 * invalid (and probably a client trying something fishy).
5323bd40d98SGordon Ross 	 */
5333bd40d98SGordon Ross 	rc = smb_mbc_decodef(&xa->req_data_mb, "l", &ea_list_size);
5343bd40d98SGordon Ross 	if (rc == 0 && ea_list_size > 4) {
5353bd40d98SGordon Ross 		smbsr_status(sr, NT_STATUS_EAS_NOT_SUPPORTED, 0, 0);
5363bd40d98SGordon Ross 		return (SDRC_ERROR);
5373bd40d98SGordon Ross 	}
5383bd40d98SGordon Ross 
5392c2961f8Sjose borrego 	if ((creation_time != 0) && (creation_time != UINT_MAX))
540e3f2c991SKeyur Desai 		op->crtime.tv_sec = smb_time_local_to_gmt(sr, creation_time);
5412c2961f8Sjose borrego 	op->crtime.tv_nsec = 0;
5422c2961f8Sjose borrego 
5432c2961f8Sjose borrego 	op->dattr = file_attr;
5442c2961f8Sjose borrego 	op->dsize = alloc_size;
5452c2961f8Sjose borrego 	op->create_options = FILE_NON_DIRECTORY_FILE;
5462c2961f8Sjose borrego 
5472c2961f8Sjose borrego 	op->desired_access = smb_omode_to_amask(op->omode);
548eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	op->share_access = smb_denymode_to_sharemode(op->omode,
549eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    op->fqi.fq_path.pn_path);
5502c2961f8Sjose borrego 
5512c2961f8Sjose borrego 	op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
5522c2961f8Sjose borrego 	if (op->create_disposition > FILE_MAXIMUM_DISPOSITION)
5532c2961f8Sjose borrego 		op->create_disposition = FILE_CREATE;
5542c2961f8Sjose borrego 
5552c2961f8Sjose borrego 	if (op->omode & SMB_DA_WRITE_THROUGH)
5562c2961f8Sjose borrego 		op->create_options |= FILE_WRITE_THROUGH;
5572c2961f8Sjose borrego 
5582c2961f8Sjose borrego 	if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
5592c2961f8Sjose borrego 		if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
5602c2961f8Sjose borrego 			op->op_oplock_level = SMB_OPLOCK_BATCH;
5612c2961f8Sjose borrego 		else
5622c2961f8Sjose borrego 			op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
5632c2961f8Sjose borrego 	} else {
5642c2961f8Sjose borrego 		op->op_oplock_level = SMB_OPLOCK_NONE;
5652c2961f8Sjose borrego 	}
566cb174861Sjoyce mcintosh 	op->op_oplock_levelII = B_FALSE;
5672c2961f8Sjose borrego 
568a90cf9f2SGordon Ross 	status = smb_common_open(sr);
569a90cf9f2SGordon Ross 	if (status != NT_STATUS_SUCCESS) {
570a90cf9f2SGordon Ross 		smbsr_status(sr, status, 0, 0);
5712c2961f8Sjose borrego 		return (SDRC_ERROR);
572a90cf9f2SGordon Ross 	}
5732c2961f8Sjose borrego 
5742c2961f8Sjose borrego 	if (op->op_oplock_level != SMB_OPLOCK_NONE)
575c5f48fa5SGordon Ross 		op->action_taken |= SMB_OACT_OPLOCK;
5762c2961f8Sjose borrego 	else
577c5f48fa5SGordon Ross 		op->action_taken &= ~SMB_OACT_OPLOCK;
5782c2961f8Sjose borrego 
5792c2961f8Sjose borrego 	file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
5802c2961f8Sjose borrego 
581f96bd5c8SAlan Wright 	if (STYPE_ISIPC(sr->tid_tree->t_res_type))
5822c2961f8Sjose borrego 		op->dsize = 0;
5832c2961f8Sjose borrego 
5842c2961f8Sjose borrego 	(void) smb_mbc_encodef(&xa->rep_param_mb, "wwllwwwwlwl",
5852c2961f8Sjose borrego 	    sr->smb_fid,
5862c2961f8Sjose borrego 	    file_attr,
5872c2961f8Sjose borrego 	    (uint32_t)0,	/* creation time */
5882c2961f8Sjose borrego 	    (uint32_t)op->dsize,
5892c2961f8Sjose borrego 	    op->omode,
5902c2961f8Sjose borrego 	    op->ftype,
5912c2961f8Sjose borrego 	    op->devstate,
5922c2961f8Sjose borrego 	    op->action_taken,
5932c2961f8Sjose borrego 	    op->fileid,
5942c2961f8Sjose borrego 	    (uint16_t)0,	/* EA error offset */
5952c2961f8Sjose borrego 	    (uint32_t)0);	/* EA list length */
5962c2961f8Sjose borrego 
5972c2961f8Sjose borrego 	return (SDRC_SUCCESS);
5982c2961f8Sjose borrego }
599