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.
2393bc28dbSGordon 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>
29da6c28aaSamw
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
2187b59d02dSjb smb_sdrc_t
smb_pre_open(smb_request_t * sr)219faa1795aSjb smb_pre_open(smb_request_t *sr)
220da6c28aaSamw {
221da6c28aaSamw struct open_param *op = &sr->arg.open;
2227b59d02dSjb int rc;
223da6c28aaSamw
224da6c28aaSamw bzero(op, sizeof (sr->arg.open));
2257b59d02dSjb
226eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States rc = smbsr_decode_vwv(sr, "ww", &op->omode, &op->fqi.fq_sattr);
227faa1795aSjb if (rc == 0)
228eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States rc = smbsr_decode_data(sr, "%S", sr, &op->fqi.fq_path.pn_path);
229faa1795aSjb
23093bc28dbSGordon Ross DTRACE_SMB_START(op__Open, smb_request_t *, sr); /* arg.open */
231faa1795aSjb
232faa1795aSjb return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
233faa1795aSjb }
234faa1795aSjb
235faa1795aSjb void
smb_post_open(smb_request_t * sr)236faa1795aSjb smb_post_open(smb_request_t *sr)
237faa1795aSjb {
23893bc28dbSGordon Ross DTRACE_SMB_DONE(op__Open, smb_request_t *, sr);
239faa1795aSjb }
240faa1795aSjb
241faa1795aSjb smb_sdrc_t
smb_com_open(smb_request_t * sr)242faa1795aSjb smb_com_open(smb_request_t *sr)
243faa1795aSjb {
244faa1795aSjb struct open_param *op = &sr->arg.open;
2455fd03bc0SGordon Ross smb_ofile_t *of;
246*94047d49SGordon Ross uint32_t mtime_sec;
247a90cf9f2SGordon Ross uint32_t status;
248faa1795aSjb uint16_t file_attr;
249faa1795aSjb 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);
2548c10a865Sas 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;
2652c2961f8Sjose borrego } else {
2662c2961f8Sjose borrego op->op_oplock_level = SMB_OPLOCK_NONE;
267da6c28aaSamw }
268da6c28aaSamw
2695fd03bc0SGordon Ross if (smb_open_dsize_check && op->dsize > UINT_MAX) {
2705fd03bc0SGordon Ross smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
2715fd03bc0SGordon Ross return (SDRC_ERROR);
2725fd03bc0SGordon Ross }
2735fd03bc0SGordon Ross
274*94047d49SGordon Ross /*
275*94047d49SGordon Ross * The real open call. Note: this gets attributes into
276*94047d49SGordon Ross * op->fqi.fq_fattr (SMB_AT_ALL). We need those below.
277*94047d49SGordon Ross */
278a90cf9f2SGordon Ross status = smb_common_open(sr);
279a90cf9f2SGordon Ross if (status != NT_STATUS_SUCCESS) {
280a90cf9f2SGordon Ross smbsr_status(sr, status, 0, 0);
281faa1795aSjb return (SDRC_ERROR);
282a90cf9f2SGordon Ross }
283*94047d49SGordon Ross if (op->op_oplock_level != SMB_OPLOCK_NONE) {
284*94047d49SGordon Ross /* Oplock req. in op->op_oplock_level etc. */
285*94047d49SGordon Ross smb1_oplock_acquire(sr, B_FALSE);
286*94047d49SGordon Ross }
287da6c28aaSamw
2885fd03bc0SGordon Ross /*
2895fd03bc0SGordon Ross * NB: after the above smb_common_open() success,
2905fd03bc0SGordon Ross * we have a handle allocated (sr->fid_ofile).
2915fd03bc0SGordon Ross * If we don't return success, we must close it.
2925fd03bc0SGordon Ross */
2935fd03bc0SGordon Ross of = sr->fid_ofile;
2945fd03bc0SGordon Ross
2952c2961f8Sjose borrego if (op->op_oplock_level == SMB_OPLOCK_NONE) {
296da6c28aaSamw sr->smb_flg &=
297da6c28aaSamw ~(SMB_FLAGS_OPLOCK | SMB_FLAGS_OPLOCK_NOTIFY_ANY);
298da6c28aaSamw }
299da6c28aaSamw
3005fd03bc0SGordon Ross file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
301*94047d49SGordon Ross mtime_sec = smb_time_gmt_to_local(sr,
302*94047d49SGordon Ross op->fqi.fq_fattr.sa_vattr.va_mtime.tv_sec);
303da6c28aaSamw
3047b59d02dSjb rc = smbsr_encode_result(sr, 7, 0, "bwwllww",
305da6c28aaSamw 7,
306da6c28aaSamw sr->smb_fid,
307da6c28aaSamw file_attr,
308*94047d49SGordon Ross mtime_sec,
309da6c28aaSamw (uint32_t)op->dsize,
3102c2961f8Sjose borrego op->omode,
311da6c28aaSamw (uint16_t)0); /* bcc */
312da6c28aaSamw
3135fd03bc0SGordon Ross if (rc == 0)
3145fd03bc0SGordon Ross return (SDRC_SUCCESS);
3155fd03bc0SGordon Ross
3165fd03bc0SGordon Ross smb_ofile_close(of, 0);
3175fd03bc0SGordon Ross return (SDRC_ERROR);
318da6c28aaSamw }
319da6c28aaSamw
320c5f48fa5SGordon Ross int smb_openx_enable_extended_response = 1;
321c5f48fa5SGordon Ross
3222c1b14e5Sjose borrego /*
3232c1b14e5Sjose borrego * smb_pre_open_andx
3242c1b14e5Sjose borrego * For compatibility with windows servers, the search attributes
3252c1b14e5Sjose borrego * specified in the request are ignored.
3262c1b14e5Sjose borrego */
3277b59d02dSjb smb_sdrc_t
smb_pre_open_andx(smb_request_t * sr)328faa1795aSjb smb_pre_open_andx(smb_request_t *sr)
329da6c28aaSamw {
330faa1795aSjb struct open_param *op = &sr->arg.open;
331c5f48fa5SGordon Ross uint16_t openx_flags;
332a90cf9f2SGordon Ross uint32_t alloc_size;
3338c10a865Sas uint32_t creation_time;
3342c1b14e5Sjose borrego uint16_t file_attr, sattr;
335da6c28aaSamw int rc;
336da6c28aaSamw
337da6c28aaSamw bzero(op, sizeof (sr->arg.open));
338faa1795aSjb
339da6c28aaSamw rc = smbsr_decode_vwv(sr, "b.wwwwwlwll4.", &sr->andx_com,
340c5f48fa5SGordon Ross &sr->andx_off, &openx_flags, &op->omode, &sattr,
341a90cf9f2SGordon Ross &file_attr, &creation_time, &op->ofun, &alloc_size, &op->timeo);
342da6c28aaSamw
343faa1795aSjb if (rc == 0) {
344eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States rc = smbsr_decode_data(sr, "%u", sr, &op->fqi.fq_path.pn_path);
345faa1795aSjb
346faa1795aSjb op->dattr = file_attr;
347a90cf9f2SGordon Ross op->dsize = alloc_size;
348faa1795aSjb
349c5f48fa5SGordon Ross /*
350c5f48fa5SGordon Ross * The openx_flags use some "extended" flags that
351c5f48fa5SGordon Ross * happen to match some of the NtCreateX flags.
352c5f48fa5SGordon Ross */
353*94047d49SGordon Ross if (openx_flags & NT_CREATE_FLAG_REQUEST_OPBATCH)
3542c2961f8Sjose borrego op->op_oplock_level = SMB_OPLOCK_BATCH;
355*94047d49SGordon Ross else if (openx_flags & NT_CREATE_FLAG_REQUEST_OPLOCK)
356*94047d49SGordon Ross op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
3572c2961f8Sjose borrego else
3582c2961f8Sjose borrego op->op_oplock_level = SMB_OPLOCK_NONE;
359c5f48fa5SGordon Ross if (openx_flags & NT_CREATE_FLAG_EXTENDED_RESPONSE)
360c5f48fa5SGordon Ross op->nt_flags |= NT_CREATE_FLAG_EXTENDED_RESPONSE;
361faa1795aSjb
3628c10a865Sas if ((creation_time != 0) && (creation_time != UINT_MAX))
363e3f2c991SKeyur Desai op->crtime.tv_sec =
364e3f2c991SKeyur Desai smb_time_local_to_gmt(sr, creation_time);
3658c10a865Sas op->crtime.tv_nsec = 0;
366faa1795aSjb
3672c2961f8Sjose borrego op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
368faa1795aSjb }
369faa1795aSjb
37093bc28dbSGordon Ross DTRACE_SMB_START(op__OpenX, smb_request_t *, sr); /* arg.open */
371faa1795aSjb
372faa1795aSjb return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
373faa1795aSjb }
374faa1795aSjb
375faa1795aSjb void
smb_post_open_andx(smb_request_t * sr)376faa1795aSjb smb_post_open_andx(smb_request_t *sr)
377faa1795aSjb {
37893bc28dbSGordon Ross DTRACE_SMB_DONE(op__OpenX, smb_request_t *, sr);
379faa1795aSjb }
380faa1795aSjb
381faa1795aSjb smb_sdrc_t
smb_com_open_andx(smb_request_t * sr)382faa1795aSjb smb_com_open_andx(smb_request_t *sr)
383faa1795aSjb {
384faa1795aSjb struct open_param *op = &sr->arg.open;
385c5f48fa5SGordon Ross smb_attr_t *ap = &op->fqi.fq_fattr;
3865fd03bc0SGordon Ross smb_ofile_t *of;
387a90cf9f2SGordon Ross uint32_t status;
388c5f48fa5SGordon Ross uint32_t mtime_sec;
389faa1795aSjb uint16_t file_attr;
390faa1795aSjb int rc;
391da6c28aaSamw
392da6c28aaSamw op->desired_access = smb_omode_to_amask(op->omode);
393eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States op->share_access = smb_denymode_to_sharemode(op->omode,
394eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States op->fqi.fq_path.pn_path);
395da6c28aaSamw
3962c2961f8Sjose borrego if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) {
3972c2961f8Sjose borrego smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
398faa1795aSjb return (SDRC_ERROR);
399da6c28aaSamw }
400da6c28aaSamw
4012c1b14e5Sjose borrego op->create_options = FILE_NON_DIRECTORY_FILE;
4022c1b14e5Sjose borrego if (op->omode & SMB_DA_WRITE_THROUGH)
4032c1b14e5Sjose borrego op->create_options |= FILE_WRITE_THROUGH;
404da6c28aaSamw
4052c2961f8Sjose borrego if (smb_open_dsize_check && op->dsize > UINT_MAX) {
4062c2961f8Sjose borrego smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
407faa1795aSjb return (SDRC_ERROR);
4087b59d02dSjb }
409da6c28aaSamw
410a90cf9f2SGordon Ross status = smb_common_open(sr);
411a90cf9f2SGordon Ross if (status != NT_STATUS_SUCCESS) {
412a90cf9f2SGordon Ross smbsr_status(sr, status, 0, 0);
4135fd03bc0SGordon Ross return (SDRC_ERROR);
414a90cf9f2SGordon Ross }
415*94047d49SGordon Ross if (op->op_oplock_level != SMB_OPLOCK_NONE) {
416*94047d49SGordon Ross /* Oplock req. in op->op_oplock_level etc. */
417*94047d49SGordon Ross smb1_oplock_acquire(sr, B_FALSE);
418*94047d49SGordon Ross }
4195fd03bc0SGordon Ross
4205fd03bc0SGordon Ross /*
4215fd03bc0SGordon Ross * NB: after the above smb_common_open() success,
4225fd03bc0SGordon Ross * we have a handle allocated (sr->fid_ofile).
4235fd03bc0SGordon Ross * If we don't return success, we must close it.
4245fd03bc0SGordon Ross */
4255fd03bc0SGordon Ross of = sr->fid_ofile;
4265fd03bc0SGordon Ross
4272c2961f8Sjose borrego if (op->op_oplock_level != SMB_OPLOCK_NONE)
428c5f48fa5SGordon Ross op->action_taken |= SMB_OACT_OPLOCK;
4292c2961f8Sjose borrego else
430c5f48fa5SGordon Ross op->action_taken &= ~SMB_OACT_OPLOCK;
431da6c28aaSamw
432da6c28aaSamw file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
433c5f48fa5SGordon Ross mtime_sec = smb_time_gmt_to_local(sr, ap->sa_vattr.va_mtime.tv_sec);
434037cac00Sjoyce mcintosh
435f96bd5c8SAlan Wright switch (sr->tid_tree->t_res_type & STYPE_MASK) {
436f96bd5c8SAlan Wright case STYPE_DISKTREE:
437f96bd5c8SAlan Wright case STYPE_PRINTQ:
438f96bd5c8SAlan Wright break;
439f96bd5c8SAlan Wright
440f96bd5c8SAlan Wright case STYPE_IPC:
441c5f48fa5SGordon Ross mtime_sec = 0;
442f96bd5c8SAlan Wright break;
443f96bd5c8SAlan Wright
444f96bd5c8SAlan Wright default:
445f96bd5c8SAlan Wright smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
446f96bd5c8SAlan Wright ERRDOS, ERROR_INVALID_FUNCTION);
4475fd03bc0SGordon Ross goto errout;
448da6c28aaSamw }
449da6c28aaSamw
450c5f48fa5SGordon Ross if ((op->nt_flags & NT_CREATE_FLAG_EXTENDED_RESPONSE) != 0 &&
451c5f48fa5SGordon Ross smb_openx_enable_extended_response != 0) {
452c5f48fa5SGordon Ross uint32_t MaxAccess = 0;
453c5f48fa5SGordon Ross if (of->f_node != NULL) {
454c5f48fa5SGordon Ross smb_fsop_eaccess(sr, of->f_cr, of->f_node, &MaxAccess);
455c5f48fa5SGordon Ross }
456c5f48fa5SGordon Ross MaxAccess |= of->f_granted_access;
457c5f48fa5SGordon Ross
458c5f48fa5SGordon Ross rc = smbsr_encode_result(
459c5f48fa5SGordon Ross sr, 19, 0, "bb.wwwllwwwwl2.llw",
460c5f48fa5SGordon Ross 19, /* word count (b) */
461c5f48fa5SGordon Ross sr->andx_com, /* (b.) */
462c5f48fa5SGordon Ross VAR_BCC, /* andx offset (w) */
463c5f48fa5SGordon Ross sr->smb_fid, /* (w) */
464c5f48fa5SGordon Ross file_attr, /* (w) */
465c5f48fa5SGordon Ross mtime_sec, /* (l) */
466c5f48fa5SGordon Ross (uint32_t)op->dsize, /* (l) */
467c5f48fa5SGordon Ross op->omode, /* (w) */
468c5f48fa5SGordon Ross op->ftype, /* (w) */
469c5f48fa5SGordon Ross op->devstate, /* (w) */
470c5f48fa5SGordon Ross op->action_taken, /* (w) */
471c5f48fa5SGordon Ross 0, /* legacy fileid (l) */
472c5f48fa5SGordon Ross /* reserved (2.) */
473c5f48fa5SGordon Ross MaxAccess, /* (l) */
474c5f48fa5SGordon Ross 0, /* guest access (l) */
475c5f48fa5SGordon Ross 0); /* byte count (w) */
476c5f48fa5SGordon Ross
477c5f48fa5SGordon Ross } else {
478c5f48fa5SGordon Ross rc = smbsr_encode_result(
479c5f48fa5SGordon Ross sr, 15, 0, "bb.wwwllwwwwl2.w",
480c5f48fa5SGordon Ross 15, /* word count (b) */
481c5f48fa5SGordon Ross sr->andx_com, /* (b.) */
482c5f48fa5SGordon Ross VAR_BCC, /* andx offset (w) */
483c5f48fa5SGordon Ross sr->smb_fid, /* (w) */
484c5f48fa5SGordon Ross file_attr, /* (w) */
485c5f48fa5SGordon Ross mtime_sec, /* (l) */
486c5f48fa5SGordon Ross (uint32_t)op->dsize, /* (l) */
487c5f48fa5SGordon Ross op->omode, /* (w) */
488c5f48fa5SGordon Ross op->ftype, /* (w) */
489c5f48fa5SGordon Ross op->devstate, /* (w) */
490c5f48fa5SGordon Ross op->action_taken, /* (w) */
491c5f48fa5SGordon Ross 0, /* legacy fileid (l) */
492c5f48fa5SGordon Ross /* reserved (2.) */
493c5f48fa5SGordon Ross 0); /* byte count (w) */
494c5f48fa5SGordon Ross }
495c5f48fa5SGordon Ross
4965fd03bc0SGordon Ross if (rc == 0)
4975fd03bc0SGordon Ross return (SDRC_SUCCESS);
4985fd03bc0SGordon Ross
4995fd03bc0SGordon Ross errout:
5005fd03bc0SGordon Ross smb_ofile_close(of, 0);
5015fd03bc0SGordon Ross return (SDRC_ERROR);
502da6c28aaSamw }
5032c2961f8Sjose borrego
5042c2961f8Sjose borrego smb_sdrc_t
smb_com_trans2_open2(smb_request_t * sr,smb_xa_t * xa)5052c2961f8Sjose borrego smb_com_trans2_open2(smb_request_t *sr, smb_xa_t *xa)
5062c2961f8Sjose borrego {
5072c2961f8Sjose borrego struct open_param *op = &sr->arg.open;
5082c2961f8Sjose borrego uint32_t creation_time;
5092c2961f8Sjose borrego uint32_t alloc_size;
5103bd40d98SGordon Ross uint32_t ea_list_size;
5112c2961f8Sjose borrego uint16_t flags;
5122c2961f8Sjose borrego uint16_t file_attr;
513a90cf9f2SGordon Ross uint32_t status;
5142c2961f8Sjose borrego int rc;
5152c2961f8Sjose borrego
5162c2961f8Sjose borrego bzero(op, sizeof (sr->arg.open));
5172c2961f8Sjose borrego
5182c2961f8Sjose borrego rc = smb_mbc_decodef(&xa->req_param_mb, "%wwwwlwl10.u",
519eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States sr, &flags, &op->omode, &op->fqi.fq_sattr, &file_attr,
520eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States &creation_time, &op->ofun, &alloc_size, &op->fqi.fq_path.pn_path);
5212c2961f8Sjose borrego if (rc != 0)
5222c2961f8Sjose borrego return (SDRC_ERROR);
5232c2961f8Sjose borrego
5243bd40d98SGordon Ross /*
5253bd40d98SGordon Ross * The data part of this transaction may contain an EA list.
5263bd40d98SGordon Ross * See: SMB_FEA_LIST ExtendedAttributeList
5273bd40d98SGordon Ross *
5283bd40d98SGordon Ross * If we find a non-empty EA list payload, return the special
5293bd40d98SGordon Ross * error that tells the caller this FS does not suport EAs.
5303bd40d98SGordon Ross *
5313bd40d98SGordon Ross * Note: the first word is the size of the whole data segment,
5323bd40d98SGordon Ross * INCLUDING the size of that length word. That means if
5333bd40d98SGordon Ross * the length word specifies a size less than four, it's
5343bd40d98SGordon Ross * invalid (and probably a client trying something fishy).
5353bd40d98SGordon Ross */
5363bd40d98SGordon Ross rc = smb_mbc_decodef(&xa->req_data_mb, "l", &ea_list_size);
5373bd40d98SGordon Ross if (rc == 0 && ea_list_size > 4) {
5383bd40d98SGordon Ross smbsr_status(sr, NT_STATUS_EAS_NOT_SUPPORTED, 0, 0);
5393bd40d98SGordon Ross return (SDRC_ERROR);
5403bd40d98SGordon Ross }
5413bd40d98SGordon Ross
5422c2961f8Sjose borrego if ((creation_time != 0) && (creation_time != UINT_MAX))
543e3f2c991SKeyur Desai op->crtime.tv_sec = smb_time_local_to_gmt(sr, creation_time);
5442c2961f8Sjose borrego op->crtime.tv_nsec = 0;
5452c2961f8Sjose borrego
5462c2961f8Sjose borrego op->dattr = file_attr;
5472c2961f8Sjose borrego op->dsize = alloc_size;
5482c2961f8Sjose borrego op->create_options = FILE_NON_DIRECTORY_FILE;
5492c2961f8Sjose borrego
5502c2961f8Sjose borrego op->desired_access = smb_omode_to_amask(op->omode);
551eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States op->share_access = smb_denymode_to_sharemode(op->omode,
552eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States op->fqi.fq_path.pn_path);
5532c2961f8Sjose borrego
5542c2961f8Sjose borrego op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
5552c2961f8Sjose borrego if (op->create_disposition > FILE_MAXIMUM_DISPOSITION)
5562c2961f8Sjose borrego op->create_disposition = FILE_CREATE;
5572c2961f8Sjose borrego
5582c2961f8Sjose borrego if (op->omode & SMB_DA_WRITE_THROUGH)
5592c2961f8Sjose borrego op->create_options |= FILE_WRITE_THROUGH;
5602c2961f8Sjose borrego
5612c2961f8Sjose borrego if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
5622c2961f8Sjose borrego if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
5632c2961f8Sjose borrego op->op_oplock_level = SMB_OPLOCK_BATCH;
5642c2961f8Sjose borrego else
5652c2961f8Sjose borrego op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
5662c2961f8Sjose borrego } else {
5672c2961f8Sjose borrego op->op_oplock_level = SMB_OPLOCK_NONE;
5682c2961f8Sjose borrego }
5692c2961f8Sjose borrego
570a90cf9f2SGordon Ross status = smb_common_open(sr);
571a90cf9f2SGordon Ross if (status != NT_STATUS_SUCCESS) {
572a90cf9f2SGordon Ross smbsr_status(sr, status, 0, 0);
5732c2961f8Sjose borrego return (SDRC_ERROR);
574a90cf9f2SGordon Ross }
575*94047d49SGordon Ross if (op->op_oplock_level != SMB_OPLOCK_NONE) {
576*94047d49SGordon Ross /* Oplock req. in op->op_oplock_level etc. */
577*94047d49SGordon Ross smb1_oplock_acquire(sr, B_FALSE);
578*94047d49SGordon Ross }
5792c2961f8Sjose borrego
5802c2961f8Sjose borrego if (op->op_oplock_level != SMB_OPLOCK_NONE)
581c5f48fa5SGordon Ross op->action_taken |= SMB_OACT_OPLOCK;
5822c2961f8Sjose borrego else
583c5f48fa5SGordon Ross op->action_taken &= ~SMB_OACT_OPLOCK;
5842c2961f8Sjose borrego
5852c2961f8Sjose borrego file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
5862c2961f8Sjose borrego
587f96bd5c8SAlan Wright if (STYPE_ISIPC(sr->tid_tree->t_res_type))
5882c2961f8Sjose borrego op->dsize = 0;
5892c2961f8Sjose borrego
5902c2961f8Sjose borrego (void) smb_mbc_encodef(&xa->rep_param_mb, "wwllwwwwlwl",
5912c2961f8Sjose borrego sr->smb_fid,
5922c2961f8Sjose borrego file_attr,
5932c2961f8Sjose borrego (uint32_t)0, /* creation time */
5942c2961f8Sjose borrego (uint32_t)op->dsize,
5952c2961f8Sjose borrego op->omode,
5962c2961f8Sjose borrego op->ftype,
5972c2961f8Sjose borrego op->devstate,
5982c2961f8Sjose borrego op->action_taken,
5992c2961f8Sjose borrego op->fileid,
6002c2961f8Sjose borrego (uint16_t)0, /* EA error offset */
6012c2961f8Sjose borrego (uint32_t)0); /* EA list length */
6022c2961f8Sjose borrego
6032c2961f8Sjose borrego return (SDRC_SUCCESS);
6042c2961f8Sjose borrego }
605