Print this page
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-1643 dtrace provider for smbsrv
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-4538 SMB1 create file should support extended_response format (2)
NEX-6116 Failures in smbtorture raw.open
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Include this commit if upstreaming/backporting any of:
NEX-4540 SMB server declines EA support incorrectly
NEX-4239 smbtorture create failures re. allocation size
(illumos) 6398 SMB should support path names longer than 1024
NEX-4538 SMB1 create file should support extended_response format
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
SMB-11 SMB2 message parse & dispatch
SMB-12 SMB2 Negotiate Protocol
SMB-13 SMB2 Session Setup
SMB-14 SMB2 Logoff
SMB-15 SMB2 Tree Connect
SMB-16 SMB2 Tree Disconnect
SMB-17 SMB2 Create
SMB-18 SMB2 Close
SMB-19 SMB2 Flush
SMB-20 SMB2 Read
SMB-21 SMB2 Write
SMB-22 SMB2 Lock/Unlock
SMB-23 SMB2 Ioctl
SMB-24 SMB2 Cancel
SMB-25 SMB2 Echo
SMB-26 SMB2 Query Dir
SMB-27 SMB2 Change Notify
SMB-28 SMB2 Query Info
SMB-29 SMB2 Set Info
SMB-30 SMB2 Oplocks
SMB-53 SMB2 Create Context options
(SMB2 code review cleanup 1, 2, 3)
SMB-50 User-mode SMB server
Includes work by these authors:
Thomas Keiser <thomas.keiser@nexenta.com>
Albert Lee <trisk@nexenta.com>
SMB-63 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
re #11974 CIFS Share - Tree connect fails from Windows 7 Clients
re #14152 Race between ipmi_submit_driver_request() and kcs_loop() (sync with illumos fix 3902)
SMB-46 File handle leaks exposed by mtime fixes (rm 7815)
re #7815 SMB server delivers old modification time...
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c
+++ new/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 - * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
23 + * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
24 24 */
25 25
26 26 /*
27 27 * This command is used to create or open a file or directory, when EAs
28 28 * or an SD must be applied to the file. The functionality is similar
29 29 * to SmbNtCreateAndx with the option to supply extended attributes or
30 30 * a security descriptor.
31 31 *
32 32 * Note: we don't decode the extended attributes because we don't
33 33 * support them at this time.
34 34 */
35 35
36 36 #include <smbsrv/smb_kproto.h>
37 37 #include <smbsrv/smb_fsops.h>
38 38
39 +extern int smb_nt_create_enable_extended_response;
40 +
39 41 /*
40 42 * smb_nt_transact_create
41 43 *
42 44 * This command is used to create or open a file or directory, when EAs
43 45 * or an SD must be applied to the file. The request parameter block
44 46 * encoding, data block encoding and output parameter block encoding are
45 47 * described in CIFS section 4.2.2.
46 48 *
47 49 * The format of the command is SmbNtTransact but it is basically the same
48 50 * as SmbNtCreateAndx with the option to supply extended attributes or a
49 51 * security descriptor. For information not defined in CIFS section 4.2.2
50 52 * see section 4.2.1 (NT_CREATE_ANDX).
51 53 */
52 54 smb_sdrc_t
53 55 smb_pre_nt_transact_create(smb_request_t *sr, smb_xa_t *xa)
54 56 {
55 57 struct open_param *op = &sr->arg.open;
56 58 uint8_t SecurityFlags;
57 59 uint32_t EaLength;
58 60 uint32_t ImpersonationLevel;
59 61 uint32_t NameLength;
60 62 uint32_t sd_len;
61 63 uint32_t status;
62 64 smb_sd_t sd;
63 65 int rc;
64 66
65 67 bzero(op, sizeof (sr->arg.open));
66 68
67 69 rc = smb_mbc_decodef(&xa->req_param_mb, "%lllqllllllllb",
68 70 sr,
69 71 &op->nt_flags,
70 72 &op->rootdirfid,
71 73 &op->desired_access,
72 74 &op->dsize,
73 75 &op->dattr,
74 76 &op->share_access,
75 77 &op->create_disposition,
|
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
76 78 &op->create_options,
77 79 &sd_len,
78 80 &EaLength,
79 81 &NameLength,
80 82 &ImpersonationLevel,
81 83 &SecurityFlags);
82 84
83 85 if (rc == 0) {
84 86 if (NameLength == 0) {
85 87 op->fqi.fq_path.pn_path = "\\";
86 - } else if (NameLength >= MAXPATHLEN) {
87 - smbsr_error(sr, NT_STATUS_OBJECT_PATH_NOT_FOUND,
88 - ERRDOS, ERROR_PATH_NOT_FOUND);
88 + } else if (NameLength >= SMB_MAXPATHLEN) {
89 + smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
90 + ERRDOS, ERROR_INVALID_NAME);
89 91 rc = -1;
90 92 } else {
91 93 rc = smb_mbc_decodef(&xa->req_param_mb, "%#u",
92 94 sr, NameLength, &op->fqi.fq_path.pn_path);
93 95 }
94 96 }
95 97
96 98 op->op_oplock_level = SMB_OPLOCK_NONE;
97 99 if (op->nt_flags & NT_CREATE_FLAG_REQUEST_OPLOCK) {
98 100 if (op->nt_flags & NT_CREATE_FLAG_REQUEST_OPBATCH)
99 101 op->op_oplock_level = SMB_OPLOCK_BATCH;
100 102 else
101 103 op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
102 104 }
103 105
104 106 if (sd_len) {
105 107 status = smb_decode_sd(&xa->req_data_mb, &sd);
|
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
106 108 if (status != NT_STATUS_SUCCESS) {
107 109 smbsr_error(sr, status, 0, 0);
108 110 return (SDRC_ERROR);
109 111 }
110 112 op->sd = kmem_alloc(sizeof (smb_sd_t), KM_SLEEP);
111 113 *op->sd = sd;
112 114 } else {
113 115 op->sd = NULL;
114 116 }
115 117
116 - DTRACE_SMB_2(op__NtTransactCreate__start, smb_request_t *, sr,
117 - struct open_param *, op);
118 + DTRACE_SMB_START(op__NtTransactCreate, smb_request_t *, sr);
118 119
119 120 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
120 121 }
121 122
122 123 void
123 124 smb_post_nt_transact_create(smb_request_t *sr, smb_xa_t *xa)
124 125 {
125 126 smb_sd_t *sd = sr->arg.open.sd;
127 + _NOTE(ARGUNUSED(xa))
126 128
127 - DTRACE_SMB_2(op__NtTransactCreate__done, smb_request_t *, sr,
128 - smb_xa_t *, xa);
129 + DTRACE_SMB_DONE(op__NtTransactCreate, smb_request_t *, sr);
129 130
130 131 if (sd) {
131 132 smb_sd_term(sd);
132 133 kmem_free(sd, sizeof (smb_sd_t));
133 134 }
134 135
135 - if (sr->arg.open.dir != NULL)
136 + if (sr->arg.open.dir != NULL) {
136 137 smb_ofile_release(sr->arg.open.dir);
138 + sr->arg.open.dir = NULL;
139 + }
137 140 }
138 141
142 +/*
143 + * A lot like smb_com_nt_create_andx
144 + */
139 145 smb_sdrc_t
140 146 smb_nt_transact_create(smb_request_t *sr, smb_xa_t *xa)
141 147 {
142 - struct open_param *op = &sr->arg.open;
143 - uint8_t DirFlag;
144 - smb_attr_t attr;
148 + struct open_param *op = &sr->arg.open;
149 + smb_attr_t *ap = &op->fqi.fq_fattr;
145 150 smb_ofile_t *of;
146 - uint32_t status;
147 151 int rc;
152 + uint8_t DirFlag;
153 + uint32_t status;
148 154
155 + if (op->create_options & ~SMB_NTCREATE_VALID_OPTIONS) {
156 + smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
157 + ERRDOS, ERROR_INVALID_PARAMETER);
158 + return (SDRC_ERROR);
159 + }
160 +
161 + if (op->create_options & FILE_OPEN_BY_FILE_ID) {
162 + smbsr_error(sr, NT_STATUS_NOT_SUPPORTED,
163 + ERRDOS, ERROR_NOT_SUPPORTED);
164 + return (SDRC_ERROR);
165 + }
166 +
149 167 if ((op->create_options & FILE_DELETE_ON_CLOSE) &&
150 168 !(op->desired_access & DELETE)) {
151 169 smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
152 170 ERRDOS, ERRbadaccess);
153 171 return (SDRC_ERROR);
154 172 }
155 173
156 174 if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) {
157 175 smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
158 176 ERRDOS, ERRbadaccess);
159 177 return (SDRC_ERROR);
160 178 }
161 179
162 180 if (op->dattr & FILE_FLAG_WRITE_THROUGH)
163 181 op->create_options |= FILE_WRITE_THROUGH;
164 182
165 183 if (op->dattr & FILE_FLAG_DELETE_ON_CLOSE)
166 184 op->create_options |= FILE_DELETE_ON_CLOSE;
167 185
168 186 if (op->dattr & FILE_FLAG_BACKUP_SEMANTICS)
169 187 op->create_options |= FILE_OPEN_FOR_BACKUP_INTENT;
170 188
171 189 if (op->create_options & FILE_OPEN_FOR_BACKUP_INTENT)
172 190 sr->user_cr = smb_user_getprivcred(sr->uid_user);
173 191
174 192 if (op->rootdirfid == 0) {
175 193 op->fqi.fq_dnode = sr->tid_tree->t_snode;
|
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
176 194 } else {
177 195 op->dir = smb_ofile_lookup_by_fid(sr, (uint16_t)op->rootdirfid);
178 196 if (op->dir == NULL) {
179 197 smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
180 198 ERRDOS, ERRbadfid);
181 199 return (SDRC_ERROR);
182 200 }
183 201 op->fqi.fq_dnode = op->dir->f_node;
184 202 }
185 203
186 - op->op_oplock_levelII = B_TRUE;
187 -
188 204 status = smb_common_open(sr);
189 205 if (status != NT_STATUS_SUCCESS) {
190 206 smbsr_status(sr, status, 0, 0);
191 207 return (SDRC_ERROR);
192 208 }
209 + if (op->op_oplock_level != SMB_OPLOCK_NONE) {
210 + /* Oplock req. in op->op_oplock_level etc. */
211 + smb1_oplock_acquire(sr, B_TRUE);
212 + }
193 213
194 214 /*
195 215 * NB: after the above smb_common_open() success,
196 216 * we have a handle allocated (sr->fid_ofile).
197 217 * If we don't return success, we must close it.
198 218 */
199 219 of = sr->fid_ofile;
200 220
201 221 switch (sr->tid_tree->t_res_type & STYPE_MASK) {
202 222 case STYPE_DISKTREE:
203 223 case STYPE_PRINTQ:
204 224 if (op->create_options & FILE_DELETE_ON_CLOSE)
205 - smb_ofile_set_delete_on_close(of);
206 -
225 + smb_ofile_set_delete_on_close(sr, of);
207 226 DirFlag = smb_node_is_dir(of->f_node) ? 1 : 0;
208 - bzero(&attr, sizeof (attr));
209 - attr.sa_mask = SMB_AT_ALL;
210 - rc = smb_node_getattr(sr, of->f_node, of->f_cr, of, &attr);
211 - if (rc != 0) {
212 - smbsr_errno(sr, rc);
213 - goto errout;
214 - }
215 -
216 - rc = smb_mbc_encodef(&xa->rep_param_mb, "b.wllTTTTlqqwwb",
217 - op->op_oplock_level,
218 - sr->smb_fid,
219 - op->action_taken,
220 - 0, /* EaErrorOffset */
221 - &attr.sa_crtime,
222 - &attr.sa_vattr.va_atime,
223 - &attr.sa_vattr.va_mtime,
224 - &attr.sa_vattr.va_ctime,
225 - op->dattr & FILE_ATTRIBUTE_MASK,
226 - attr.sa_allocsz,
227 - attr.sa_vattr.va_size,
228 - op->ftype,
229 - op->devstate,
230 - DirFlag);
231 227 break;
232 228
233 229 case STYPE_IPC:
234 - bzero(&attr, sizeof (smb_attr_t));
235 - rc = smb_mbc_encodef(&xa->rep_param_mb, "b.wllTTTTlqqwwb",
236 - 0,
237 - sr->smb_fid,
238 - op->action_taken,
239 - 0, /* EaErrorOffset */
240 - &attr.sa_crtime,
241 - &attr.sa_vattr.va_atime,
242 - &attr.sa_vattr.va_mtime,
243 - &attr.sa_vattr.va_ctime,
244 - op->dattr,
245 - 0x1000LL,
246 - 0LL,
247 - op->ftype,
248 - op->devstate,
249 - 0);
230 + DirFlag = 0;
250 231 break;
251 232
252 233 default:
253 234 smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
254 235 ERRDOS, ERROR_INVALID_FUNCTION);
255 236 goto errout;
256 237 }
257 - return (SDRC_SUCCESS);
258 238
239 + if ((op->nt_flags & NT_CREATE_FLAG_EXTENDED_RESPONSE) != 0 &&
240 + smb_nt_create_enable_extended_response != 0) {
241 + uint32_t MaxAccess = 0;
242 + if (of->f_node != NULL) {
243 + smb_fsop_eaccess(sr, of->f_cr, of->f_node, &MaxAccess);
244 + }
245 + MaxAccess |= of->f_granted_access;
246 +
247 + rc = smb_mbc_encodef(
248 + &xa->rep_param_mb, "bbwllTTTTlqqwwb16.qll",
249 + op->op_oplock_level, /* (b) */
250 + 1, /* ResponseType (b) */
251 + sr->smb_fid, /* (w) */
252 + op->action_taken, /* (l) */
253 + 0, /* EaErrorOffset (l) */
254 + &ap->sa_crtime, /* (T) */
255 + &ap->sa_vattr.va_atime, /* (T) */
256 + &ap->sa_vattr.va_mtime, /* (T) */
257 + &ap->sa_vattr.va_ctime, /* (T) */
258 + op->dattr & FILE_ATTRIBUTE_MASK, /* (l) */
259 + ap->sa_allocsz, /* (q) */
260 + ap->sa_vattr.va_size, /* (q) */
261 + op->ftype, /* (w) */
262 + op->devstate, /* (w) */
263 + DirFlag, /* (b) */
264 + /* volume guid (16.) */
265 + op->fileid, /* (q) */
266 + MaxAccess, /* (l) */
267 + 0); /* guest access (l) */
268 + } else {
269 + rc = smb_mbc_encodef(
270 + &xa->rep_param_mb, "bbwllTTTTlqqwwb",
271 + op->op_oplock_level, /* (b) */
272 + 0, /* ResponseType (b) */
273 + sr->smb_fid, /* (w) */
274 + op->action_taken, /* (l) */
275 + 0, /* EaErrorOffset (l) */
276 + &ap->sa_crtime, /* (T) */
277 + &ap->sa_vattr.va_atime, /* (T) */
278 + &ap->sa_vattr.va_mtime, /* (T) */
279 + &ap->sa_vattr.va_ctime, /* (T) */
280 + op->dattr & FILE_ATTRIBUTE_MASK, /* (l) */
281 + ap->sa_allocsz, /* (q) */
282 + ap->sa_vattr.va_size, /* (q) */
283 + op->ftype, /* (w) */
284 + op->devstate, /* (w) */
285 + DirFlag); /* (b) */
286 + }
287 +
288 + if (rc == 0)
289 + return (SDRC_SUCCESS);
290 +
259 291 errout:
260 292 smb_ofile_close(of, 0);
261 293 return (SDRC_ERROR);
262 294 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX