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.
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.
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]
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
27 * This command is used to create or open a file or directory.
31 #include <smbsrv/smb_kproto.h>
32 #include <smbsrv/smb_fsops.h>
33 #include <smbsrv/smb_vops.h>
36 * smb_com_nt_create_andx
38 * This command is used to create or open a file or directory.
40 * Client Request Description
41 * ================================= ==================================
43 * UCHAR WordCount; Count of parameter words = 24
44 * UCHAR AndXCommand; Secondary command; 0xFF = None
45 * UCHAR AndXReserved; Reserved (must be 0)
46 * USHORT AndXOffset; Offset to next command WordCount
47 * UCHAR Reserved; Reserved (must be 0)
48 * USHORT NameLength; Length of Name[] in bytes
49 * ULONG Flags; Create bit set:
50 * 0x02 - Request an oplock
51 * 0x04 - Request a batch oplock
52 * 0x08 - Target of open must be
54 * ULONG RootDirectoryFid; If non-zero, open is relative to
56 * ACCESS_MASK DesiredAccess; access desired
57 * LARGE_INTEGER AllocationSize; Initial allocation size
58 * ULONG ExtFileAttributes; File attributes
59 * ULONG ShareAccess; Type of share access
60 * ULONG CreateDisposition; Action to take if file exists or
62 * ULONG CreateOptions; Options to use if creating a file
63 * ULONG ImpersonationLevel; Security QOS information
64 * UCHAR SecurityFlags; Security tracking mode flags:
65 * 0x1 - SECURITY_CONTEXT_TRACKING
66 * 0x2 - SECURITY_EFFECTIVE_ONLY
67 * USHORT ByteCount; Length of byte parameters
68 * STRING Name[]; File to open or create
70 * The DesiredAccess parameter is specified in section 3.7 on Access Mask
73 * If no value is specified, it still allows an application to query
74 * attributes without actually accessing the file.
76 * The ExtFIleAttributes parameter specifies the file attributes and flags
77 * for the file. The parameter's value is the sum of allowed attributes and
78 * flags defined in section 3.11 on Extended File Attribute Encoding
80 * The ShareAccess field Specifies how this file can be shared. This
81 * parameter must be some combination of the following values:
84 * 0 Prevents the file from being shared.
85 * FILE_SHARE_READ 0x00000001 Other open operations can be performed on
86 * the file for read access.
87 * FILE_SHARE_WRITE 0x00000002 Other open operations can be performed on
88 * the file for write access.
89 * FILE_SHARE_DELETE 0x00000004 Other open operations can be performed on
90 * the file for delete access.
92 * The CreateDisposition parameter can contain one of the following values:
94 * CREATE_NEW Creates a new file. The function fails if the
95 * specified file already exists.
96 * CREATE_ALWAYS Creates a new file. The function overwrites the file
98 * OPEN_EXISTING Opens the file. The function fails if the file does
100 * OPEN_ALWAYS Opens the file, if it exists. If the file does not
101 * exist, act like CREATE_NEW.
102 * TRUNCATE_EXISTING Opens the file. Once opened, the file is truncated so
103 * that its size is zero bytes. The calling process must
104 * open the file with at least GENERIC_WRITE access. The
105 * function fails if the file does not exist.
107 * The ImpersonationLevel parameter can contain one or more of the
110 * SECURITY_ANONYMOUS Specifies to impersonate the client at the
111 * Anonymous impersonation level.
112 * SECURITY_IDENTIFICATION Specifies to impersonate the client at the
113 * Identification impersonation level.
114 * SECURITY_IMPERSONATION Specifies to impersonate the client at the
115 * Impersonation impersonation level.
116 * SECURITY_DELEGATION Specifies to impersonate the client at the
117 * Delegation impersonation level.
119 * The SecurityFlags parameter can have either of the following two flags
122 * SECURITY_CONTEXT_TRACKING Specifies that the security tracking mode is
123 * dynamic. If this flag is not specified,
124 * Security Tracking Mode is static.
125 * SECURITY_EFFECTIVE_ONLY Specifies that only the enabled aspects of
126 * the client's security context are available
127 * to the server. If you do not specify this
128 * flag, all aspects of the client's security
129 * context are available. This flag allows the
130 * client to limit the groups and privileges
131 * that a server can use while impersonating the
134 * The response is as follows:
136 * Server Response Description
137 * ================================= ==================================
139 * UCHAR WordCount; Count of parameter words = 26
140 * UCHAR AndXCommand; Secondary 0xFF = None
142 * UCHAR AndXReserved; MBZ
143 * USHORT AndXOffset; Offset to next command WordCount
144 * UCHAR OplockLevel; The oplock level granted
145 * 0 - No oplock granted
146 * 1 - Exclusive oplock granted
147 * 2 - Batch oplock granted
148 * 3 - Level II oplock granted
149 * USHORT Fid; The file ID
150 * ULONG CreateAction; The action taken
151 * TIME CreationTime; The time the file was created
152 * TIME LastAccessTime; The time the file was accessed
153 * TIME LastWriteTime; The time the file was last written
154 * TIME ChangeTime; The time the file was last changed
155 * ULONG ExtFileAttributes; The file attributes
156 * LARGE_INTEGER AllocationSize; The number of bytes allocated
157 * LARGE_INTEGER EndOfFile; The end of file offset
159 * USHORT DeviceState; state of IPC device (e.g. pipe)
160 * BOOLEAN Directory; TRUE if this is a directory
161 * USHORT ByteCount; = 0
163 * The following SMBs may follow SMB_COM_NT_CREATE_ANDX:
165 * SMB_COM_READ SMB_COM_READ_ANDX
169 smb_pre_nt_create_andx(smb_request_t
*sr
)
171 struct open_param
*op
= &sr
->arg
.open
;
172 uint8_t SecurityFlags
;
173 uint32_t ImpersonationLevel
;
177 bzero(op
, sizeof (sr
->arg
.open
));
179 rc
= smbsr_decode_vwv(sr
, "5.wlllqlllllb",
187 &op
->create_disposition
,
193 if (NameLength
== 0) {
194 op
->fqi
.fq_path
.pn_path
= "\\";
195 } else if (NameLength
>= SMB_MAXPATHLEN
) {
196 smbsr_error(sr
, NT_STATUS_OBJECT_NAME_INVALID
,
197 ERRDOS
, ERROR_PATH_NOT_FOUND
);
200 rc
= smbsr_decode_data(sr
, "%#u", sr
, NameLength
,
201 &op
->fqi
.fq_path
.pn_path
);
205 op
->op_oplock_level
= SMB_OPLOCK_NONE
;
206 if (op
->nt_flags
& NT_CREATE_FLAG_REQUEST_OPLOCK
) {
207 if (op
->nt_flags
& NT_CREATE_FLAG_REQUEST_OPBATCH
)
208 op
->op_oplock_level
= SMB_OPLOCK_BATCH
;
210 op
->op_oplock_level
= SMB_OPLOCK_EXCLUSIVE
;
213 DTRACE_SMB_2(op__NtCreateX__start
, smb_request_t
*, sr
,
214 struct open_param
*, op
);
216 return ((rc
== 0) ? SDRC_SUCCESS
: SDRC_ERROR
);
220 smb_post_nt_create_andx(smb_request_t
*sr
)
222 DTRACE_SMB_1(op__NtCreateX__done
, smb_request_t
*, sr
);
224 if (sr
->arg
.open
.dir
!= NULL
) {
225 smb_ofile_release(sr
->arg
.open
.dir
);
226 sr
->arg
.open
.dir
= NULL
;
231 smb_com_nt_create_andx(struct smb_request
*sr
)
233 struct open_param
*op
= &sr
->arg
.open
;
234 smb_attr_t
*ap
= &op
->fqi
.fq_fattr
;
237 unsigned char DirFlag
;
239 if ((op
->create_options
& FILE_DELETE_ON_CLOSE
) &&
240 !(op
->desired_access
& DELETE
)) {
241 smbsr_error(sr
, NT_STATUS_INVALID_PARAMETER
,
242 ERRDOS
, ERRbadaccess
);
246 if (op
->create_disposition
> FILE_MAXIMUM_DISPOSITION
) {
247 smbsr_error(sr
, NT_STATUS_INVALID_PARAMETER
,
248 ERRDOS
, ERRbadaccess
);
252 if (op
->dattr
& FILE_FLAG_WRITE_THROUGH
)
253 op
->create_options
|= FILE_WRITE_THROUGH
;
255 if (op
->dattr
& FILE_FLAG_DELETE_ON_CLOSE
)
256 op
->create_options
|= FILE_DELETE_ON_CLOSE
;
258 if (op
->dattr
& FILE_FLAG_BACKUP_SEMANTICS
)
259 op
->create_options
|= FILE_OPEN_FOR_BACKUP_INTENT
;
261 if (op
->create_options
& FILE_OPEN_FOR_BACKUP_INTENT
)
262 sr
->user_cr
= smb_user_getprivcred(sr
->uid_user
);
264 if (op
->rootdirfid
== 0) {
265 op
->fqi
.fq_dnode
= sr
->tid_tree
->t_snode
;
267 op
->dir
= smb_ofile_lookup_by_fid(sr
, (uint16_t)op
->rootdirfid
);
268 if (op
->dir
== NULL
) {
269 smbsr_error(sr
, NT_STATUS_INVALID_HANDLE
,
273 op
->fqi
.fq_dnode
= op
->dir
->f_node
;
276 op
->op_oplock_levelII
= B_TRUE
;
278 if (smb_common_open(sr
) != NT_STATUS_SUCCESS
)
282 * NB: after the above smb_common_open() success,
283 * we have a handle allocated (sr->fid_ofile).
284 * If we don't return success, we must close it.
288 switch (sr
->tid_tree
->t_res_type
& STYPE_MASK
) {
291 if (op
->create_options
& FILE_DELETE_ON_CLOSE
)
292 smb_ofile_set_delete_on_close(of
);
294 DirFlag
= smb_node_is_dir(of
->f_node
) ? 1 : 0;
295 rc
= smbsr_encode_result(sr
, 34, 0, "bb.wbwlTTTTlqqwwbw",
303 &ap
->sa_vattr
.va_atime
,
304 &ap
->sa_vattr
.va_mtime
,
305 &ap
->sa_vattr
.va_ctime
,
306 op
->dattr
& FILE_ATTRIBUTE_MASK
,
308 ap
->sa_vattr
.va_size
,
316 rc
= smbsr_encode_result(sr
, 34, 0, "bb.wbwlqqqqlqqwwbw",
327 FILE_ATTRIBUTE_NORMAL
,
337 smbsr_error(sr
, NT_STATUS_INVALID_DEVICE_REQUEST
,
338 ERRDOS
, ERROR_INVALID_FUNCTION
);
342 return (SDRC_SUCCESS
);
345 smb_ofile_close(of
, 0);