Print this page
NEX-15069 smtorture smb2.create.blob is failed
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15069 smtorture smb2.create.blob is failed
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@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-4540 SMB server declines EA support incorrectly
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
NEX-2442 regression with smbtorture test raw.sfileinfo.rename
NEX-946 smb_set_by_fid should return zero on success
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)
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/fs/smbsrv/smb_set_fileinfo.c
+++ new/usr/src/uts/common/fs/smbsrv/smb_set_fileinfo.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 2014 Nexenta Systems, Inc. All rights reserved.
23 + * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
24 24 */
25 25
26 26 /*
27 27 * Trans2 Set File/Path Information Levels:
28 28 *
29 29 * SMB_INFO_STANDARD
30 30 * SMB_INFO_SET_EAS
31 31 * SMB_SET_FILE_BASIC_INFO
32 32 * SMB_SET_FILE_DISPOSITION_INFO
33 33 * SMB_SET_FILE_END_OF_FILE_INFO
34 34 * SMB_SET_FILE_ALLOCATION_INFO
35 35 *
36 36 * Handled Passthrough levels:
37 37 * SMB_FILE_BASIC_INFORMATION
38 38 * SMB_FILE_RENAME_INFORMATION
39 39 * SMB_FILE_LINK_INFORMATION
40 40 * SMB_FILE_DISPOSITION_INFORMATION
41 41 * SMB_FILE_END_OF_FILE_INFORMATION
42 42 * SMB_FILE_ALLOCATION_INFORMATION
43 43 *
44 44 * Internal levels representing non trans2 requests
45 45 * SMB_SET_INFORMATION
46 46 * SMB_SET_INFORMATION2
47 47 */
48 48
49 49 /*
50 50 * Setting timestamps:
51 51 * The behaviour when the time field is set to -1 is not documented
52 52 * but is generally treated like 0, meaning that that server file
53 53 * system assigned value need not be changed.
54 54 *
55 55 * Setting attributes - FILE_ATTRIBUTE_NORMAL:
56 56 * SMB_SET_INFORMATION -
57 57 * - if the specified attributes have ONLY FILE_ATTRIBUTE_NORMAL set
58 58 * do NOT change the file's attributes.
59 59 * SMB_SET_BASIC_INFO -
60 60 * - if the specified attributes have ONLY FILE_ATTRIBUTE_NORMAL set
61 61 * clear (0) the file's attributes.
62 62 * - if the specified attributes are 0 do NOT change the file's
63 63 * attributes.
64 64 */
65 65
66 66 #include <smbsrv/smb_kproto.h>
67 67 #include <smbsrv/smb_fsops.h>
68 68
69 69 static int smb_set_by_fid(smb_request_t *, smb_xa_t *, uint16_t);
70 70 static int smb_set_by_path(smb_request_t *, smb_xa_t *, uint16_t);
71 71
72 72 /*
73 73 * These functions all return and NT status code.
74 74 */
75 75 static uint32_t smb_set_fileinfo(smb_request_t *, smb_setinfo_t *, int);
76 76 static uint32_t smb_set_information(smb_request_t *, smb_setinfo_t *);
77 77 static uint32_t smb_set_information2(smb_request_t *, smb_setinfo_t *);
78 78 static uint32_t smb_set_standard_info(smb_request_t *, smb_setinfo_t *);
79 79 static uint32_t smb_set_rename_info(smb_request_t *sr, smb_setinfo_t *);
80 80
81 81 /*
82 82 * smb_com_trans2_set_file_information
83 83 */
84 84 smb_sdrc_t
85 85 smb_com_trans2_set_file_information(smb_request_t *sr, smb_xa_t *xa)
86 86 {
87 87 uint16_t infolev;
88 88
89 89 if (smb_mbc_decodef(&xa->req_param_mb, "ww",
90 90 &sr->smb_fid, &infolev) != 0)
91 91 return (SDRC_ERROR);
92 92
93 93 if (smb_set_by_fid(sr, xa, infolev) != 0)
94 94 return (SDRC_ERROR);
95 95
96 96 return (SDRC_SUCCESS);
97 97 }
98 98
99 99 /*
100 100 * smb_com_trans2_set_path_information
101 101 */
102 102 smb_sdrc_t
103 103 smb_com_trans2_set_path_information(smb_request_t *sr, smb_xa_t *xa)
104 104 {
105 105 uint16_t infolev;
106 106 smb_fqi_t *fqi = &sr->arg.dirop.fqi;
107 107
108 108 if (STYPE_ISIPC(sr->tid_tree->t_res_type)) {
109 109 smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
110 110 ERRDOS, ERROR_INVALID_FUNCTION);
111 111 return (SDRC_ERROR);
112 112 }
113 113
114 114 if (smb_mbc_decodef(&xa->req_param_mb, "%w4.u",
115 115 sr, &infolev, &fqi->fq_path.pn_path) != 0)
116 116 return (SDRC_ERROR);
117 117
118 118 if (smb_set_by_path(sr, xa, infolev) != 0)
119 119 return (SDRC_ERROR);
|
↓ open down ↓ |
86 lines elided |
↑ open up ↑ |
120 120
121 121 return (SDRC_SUCCESS);
122 122 }
123 123
124 124 /*
125 125 * smb_com_set_information (aka setattr)
126 126 */
127 127 smb_sdrc_t
128 128 smb_pre_set_information(smb_request_t *sr)
129 129 {
130 - DTRACE_SMB_1(op__SetInformation__start, smb_request_t *, sr);
130 + DTRACE_SMB_START(op__SetInformation, smb_request_t *, sr);
131 131 return (SDRC_SUCCESS);
132 132 }
133 133
134 134 void
135 135 smb_post_set_information(smb_request_t *sr)
136 136 {
137 - DTRACE_SMB_1(op__SetInformation__done, smb_request_t *, sr);
137 + DTRACE_SMB_DONE(op__SetInformation, smb_request_t *, sr);
138 138 }
139 139
140 140 smb_sdrc_t
141 141 smb_com_set_information(smb_request_t *sr)
142 142 {
143 143 uint16_t infolev = SMB_SET_INFORMATION;
144 144 smb_fqi_t *fqi = &sr->arg.dirop.fqi;
145 145
146 146 if (STYPE_ISIPC(sr->tid_tree->t_res_type)) {
147 147 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
148 148 ERRDOS, ERROR_ACCESS_DENIED);
149 149 return (SDRC_ERROR);
150 150 }
151 151
152 152 if (smbsr_decode_data(sr, "%S", sr, &fqi->fq_path.pn_path) != 0)
153 153 return (SDRC_ERROR);
154 154
155 155 if (smb_set_by_path(sr, NULL, infolev) != 0)
156 156 return (SDRC_ERROR);
157 157
158 158 if (smbsr_encode_empty_result(sr) != 0)
159 159 return (SDRC_ERROR);
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
160 160
161 161 return (SDRC_SUCCESS);
162 162 }
163 163
164 164 /*
165 165 * smb_com_set_information2 (aka setattre)
166 166 */
167 167 smb_sdrc_t
168 168 smb_pre_set_information2(smb_request_t *sr)
169 169 {
170 - DTRACE_SMB_1(op__SetInformation2__start, smb_request_t *, sr);
170 + DTRACE_SMB_START(op__SetInformation2, smb_request_t *, sr);
171 171 return (SDRC_SUCCESS);
172 172 }
173 173
174 174 void
175 175 smb_post_set_information2(smb_request_t *sr)
176 176 {
177 - DTRACE_SMB_1(op__SetInformation2__done, smb_request_t *, sr);
177 + DTRACE_SMB_DONE(op__SetInformation2, smb_request_t *, sr);
178 178 }
179 179
180 180 smb_sdrc_t
181 181 smb_com_set_information2(smb_request_t *sr)
182 182 {
183 183 uint16_t infolev = SMB_SET_INFORMATION2;
184 184
185 185 if (smbsr_decode_vwv(sr, "w", &sr->smb_fid) != 0)
186 186 return (SDRC_ERROR);
187 187
188 188 if (smb_set_by_fid(sr, NULL, infolev) != 0)
189 189 return (SDRC_ERROR);
190 190
191 191 if (smbsr_encode_empty_result(sr) != 0)
192 192 return (SDRC_ERROR);
193 193
194 194 return (SDRC_SUCCESS);
195 195 }
196 196
197 197 /*
198 198 * smb_set_by_fid
199 199 *
200 200 * Common code for setting file information by open file id.
201 201 * Use the id to identify the node object and invoke smb_set_fileinfo
202 202 * for that node.
203 203 *
204 204 * Setting attributes on a named pipe by id is handled by simply
205 205 * returning success.
206 206 */
207 207 static int
208 208 smb_set_by_fid(smb_request_t *sr, smb_xa_t *xa, uint16_t infolev)
209 209 {
210 210 smb_setinfo_t sinfo;
211 211 uint32_t status;
212 212 int rc = 0;
213 213
214 214 if (SMB_TREE_IS_READONLY(sr)) {
215 215 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
216 216 ERRDOS, ERROR_ACCESS_DENIED);
217 217 return (-1);
218 218 }
219 219
220 220 if (STYPE_ISIPC(sr->tid_tree->t_res_type))
221 221 return (0);
222 222
223 223 smbsr_lookup_file(sr);
224 224 if (sr->fid_ofile == NULL) {
225 225 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
226 226 return (-1);
227 227 }
228 228
229 229 if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
230 230 smbsr_release_file(sr);
231 231 return (0);
232 232 }
233 233
234 234 sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
235 235
236 236 bzero(&sinfo, sizeof (sinfo));
237 237 sinfo.si_node = sr->fid_ofile->f_node;
238 238 if (xa != NULL)
239 239 sinfo.si_data = xa->req_data_mb;
240 240 status = smb_set_fileinfo(sr, &sinfo, infolev);
241 241 if (status != 0) {
242 242 smbsr_error(sr, status, 0, 0);
243 243 rc = -1;
244 244 }
245 245
246 246 smbsr_release_file(sr);
247 247 return (rc);
248 248 }
249 249
250 250 /*
251 251 * smb_set_by_path
252 252 *
253 253 * Common code for setting file information by file name.
254 254 * Use the file name to identify the node object and invoke
255 255 * smb_set_fileinfo for that node.
256 256 *
257 257 * Path should be set in sr->arg.dirop.fqi.fq_path prior to
258 258 * calling smb_set_by_path.
259 259 *
260 260 * Setting attributes on a named pipe by name is an error and
261 261 * is handled in the calling functions so that they can return
262 262 * the appropriate error status code (which differs by caller).
263 263 */
264 264 static int
265 265 smb_set_by_path(smb_request_t *sr, smb_xa_t *xa, uint16_t infolev)
266 266 {
267 267 int rc;
268 268 uint32_t status;
269 269 smb_setinfo_t sinfo;
270 270 smb_node_t *node, *dnode;
271 271 char *name;
272 272 smb_pathname_t *pn;
273 273
274 274 if (SMB_TREE_IS_READONLY(sr)) {
275 275 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
276 276 ERRDOS, ERROR_ACCESS_DENIED);
277 277 return (-1);
278 278 }
279 279
280 280 pn = &sr->arg.dirop.fqi.fq_path;
281 281 smb_pathname_init(sr, pn, pn->pn_path);
282 282 if (!smb_pathname_validate(sr, pn))
283 283 return (-1);
284 284
285 285 name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
|
↓ open down ↓ |
98 lines elided |
↑ open up ↑ |
286 286 rc = smb_pathname_reduce(sr, sr->user_cr, pn->pn_path,
287 287 sr->tid_tree->t_snode, sr->tid_tree->t_snode, &dnode, name);
288 288 if (rc == 0) {
289 289 rc = smb_fsop_lookup_name(sr, sr->user_cr, SMB_FOLLOW_LINKS,
290 290 sr->tid_tree->t_snode, dnode, name, &node);
291 291 smb_node_release(dnode);
292 292 }
293 293 kmem_free(name, MAXNAMELEN);
294 294
295 295 if (rc != 0) {
296 - if (rc == ENOENT) {
297 - smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
298 - ERRDOS, ERROR_FILE_NOT_FOUND);
299 - } else {
300 - smbsr_errno(sr, rc);
301 - }
296 + smbsr_errno(sr, rc);
302 297 return (-1);
303 298 }
304 299
305 300 bzero(&sinfo, sizeof (sinfo));
306 301 sinfo.si_node = node;
307 302 if (xa != NULL)
308 303 sinfo.si_data = xa->req_data_mb;
309 304 status = smb_set_fileinfo(sr, &sinfo, infolev);
310 305 if (status != 0) {
311 306 smbsr_error(sr, status, 0, 0);
312 307 rc = -1;
313 308 }
314 309
315 310 smb_node_release(node);
316 311 return (rc);
317 312 }
318 313
319 314 /*
320 315 * smb_set_fileinfo
321 316 *
322 317 * For compatibility with windows servers, SMB_FILE_LINK_INFORMATION
323 318 * is handled by returning NT_STATUS_NOT_SUPPORTED.
324 319 */
325 320 static uint32_t
326 321 smb_set_fileinfo(smb_request_t *sr, smb_setinfo_t *sinfo, int infolev)
327 322 {
328 323 uint32_t status;
329 324
330 325 switch (infolev) {
331 326 case SMB_SET_INFORMATION:
332 327 status = smb_set_information(sr, sinfo);
333 328 break;
|
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
334 329
335 330 case SMB_SET_INFORMATION2:
336 331 status = smb_set_information2(sr, sinfo);
337 332 break;
338 333
339 334 case SMB_INFO_STANDARD:
340 335 status = smb_set_standard_info(sr, sinfo);
341 336 break;
342 337
343 338 case SMB_INFO_SET_EAS:
344 - /* EAs not supported */
345 - status = 0;
339 + status = NT_STATUS_EAS_NOT_SUPPORTED;
346 340 break;
347 341
348 342 case SMB_SET_FILE_BASIC_INFO:
349 343 case SMB_FILE_BASIC_INFORMATION:
350 344 status = smb_set_basic_info(sr, sinfo);
351 345 break;
352 346
353 347 case SMB_SET_FILE_DISPOSITION_INFO:
354 348 case SMB_FILE_DISPOSITION_INFORMATION:
355 349 status = smb_set_disposition_info(sr, sinfo);
356 350 break;
357 351
358 352 case SMB_SET_FILE_END_OF_FILE_INFO:
359 353 case SMB_FILE_END_OF_FILE_INFORMATION:
360 354 status = smb_set_eof_info(sr, sinfo);
361 355 break;
362 356
363 357 case SMB_SET_FILE_ALLOCATION_INFO:
364 358 case SMB_FILE_ALLOCATION_INFORMATION:
365 359 status = smb_set_alloc_info(sr, sinfo);
366 360 break;
367 361
368 362 case SMB_FILE_RENAME_INFORMATION:
369 363 status = smb_set_rename_info(sr, sinfo);
370 364 break;
371 365
372 366 case SMB_FILE_LINK_INFORMATION:
373 367 status = NT_STATUS_NOT_SUPPORTED;
374 368 break;
375 369
376 370 default:
377 371 status = NT_STATUS_INVALID_INFO_CLASS;
378 372 break;
379 373 }
380 374
381 375 return (status);
382 376 }
383 377
384 378 /*
385 379 * smb_set_information
386 380 *
387 381 * It is not valid to set FILE_ATTRIBUTE_DIRECTORY if the
388 382 * target is not a directory.
389 383 *
390 384 * For compatibility with Windows Servers, if the specified
391 385 * attributes have ONLY FILE_ATTRIBUTE_NORMAL set do NOT change
392 386 * the file's attributes.
393 387 */
394 388 static uint32_t
395 389 smb_set_information(smb_request_t *sr, smb_setinfo_t *sinfo)
396 390 {
397 391 smb_attr_t attr;
398 392 smb_node_t *node = sinfo->si_node;
399 393 uint32_t status = 0;
400 394 uint32_t mtime;
401 395 uint16_t attributes;
402 396 int rc;
403 397
404 398 if (smbsr_decode_vwv(sr, "wl10.", &attributes, &mtime) != 0)
405 399 return (NT_STATUS_INFO_LENGTH_MISMATCH);
406 400
407 401 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) &&
408 402 (!smb_node_is_dir(node))) {
409 403 return (NT_STATUS_INVALID_PARAMETER);
410 404 }
411 405
412 406 bzero(&attr, sizeof (smb_attr_t));
413 407 if (attributes != FILE_ATTRIBUTE_NORMAL) {
414 408 attr.sa_dosattr = attributes;
415 409 attr.sa_mask |= SMB_AT_DOSATTR;
416 410 }
417 411
418 412 if (mtime != 0 && mtime != UINT_MAX) {
419 413 attr.sa_vattr.va_mtime.tv_sec =
420 414 smb_time_local_to_gmt(sr, mtime);
421 415 attr.sa_mask |= SMB_AT_MTIME;
422 416 }
423 417
424 418 rc = smb_node_setattr(sr, node, sr->user_cr, NULL, &attr);
425 419 if (rc != 0)
426 420 status = smb_errno2status(rc);
427 421
428 422 return (status);
429 423 }
430 424
431 425 /*
432 426 * smb_set_information2
433 427 */
434 428 static uint32_t
435 429 smb_set_information2(smb_request_t *sr, smb_setinfo_t *sinfo)
436 430 {
437 431 smb_attr_t attr;
438 432 uint32_t crtime, atime, mtime;
439 433 uint32_t status = 0;
440 434 int rc;
441 435
442 436 if (smbsr_decode_vwv(sr, "yyy", &crtime, &atime, &mtime) != 0)
443 437 return (NT_STATUS_INFO_LENGTH_MISMATCH);
444 438
445 439 bzero(&attr, sizeof (smb_attr_t));
446 440 if (mtime != 0 && mtime != UINT_MAX) {
447 441 attr.sa_vattr.va_mtime.tv_sec =
448 442 smb_time_local_to_gmt(sr, mtime);
449 443 attr.sa_mask |= SMB_AT_MTIME;
450 444 }
451 445
452 446 if (crtime != 0 && crtime != UINT_MAX) {
453 447 attr.sa_crtime.tv_sec = smb_time_local_to_gmt(sr, crtime);
454 448 attr.sa_mask |= SMB_AT_CRTIME;
455 449 }
456 450
457 451 if (atime != 0 && atime != UINT_MAX) {
458 452 attr.sa_vattr.va_atime.tv_sec =
459 453 smb_time_local_to_gmt(sr, atime);
460 454 attr.sa_mask |= SMB_AT_ATIME;
461 455 }
462 456
463 457 rc = smb_node_setattr(sr, sinfo->si_node, sr->user_cr,
464 458 sr->fid_ofile, &attr);
465 459 if (rc != 0)
466 460 status = smb_errno2status(rc);
467 461
468 462 return (status);
469 463 }
470 464
471 465 /*
472 466 * smb_set_standard_info
473 467 *
474 468 * Sets standard file/path information.
475 469 */
476 470 static uint32_t
477 471 smb_set_standard_info(smb_request_t *sr, smb_setinfo_t *sinfo)
478 472 {
479 473 smb_attr_t attr;
480 474 smb_node_t *node = sinfo->si_node;
481 475 uint32_t crtime, atime, mtime;
482 476 uint32_t status = 0;
483 477 int rc;
484 478
485 479 if (smb_mbc_decodef(&sinfo->si_data, "yyy",
486 480 &crtime, &atime, &mtime) != 0)
487 481 return (NT_STATUS_INFO_LENGTH_MISMATCH);
488 482
489 483 bzero(&attr, sizeof (smb_attr_t));
490 484 if (mtime != 0 && mtime != (uint32_t)-1) {
491 485 attr.sa_vattr.va_mtime.tv_sec =
492 486 smb_time_local_to_gmt(sr, mtime);
493 487 attr.sa_mask |= SMB_AT_MTIME;
494 488 }
495 489
496 490 if (crtime != 0 && crtime != (uint32_t)-1) {
497 491 attr.sa_crtime.tv_sec = smb_time_local_to_gmt(sr, crtime);
498 492 attr.sa_mask |= SMB_AT_CRTIME;
499 493 }
500 494
501 495 if (atime != 0 && atime != (uint32_t)-1) {
502 496 attr.sa_vattr.va_atime.tv_sec =
503 497 smb_time_local_to_gmt(sr, atime);
504 498 attr.sa_mask |= SMB_AT_ATIME;
505 499 }
506 500
507 501 rc = smb_node_setattr(sr, node, sr->user_cr, sr->fid_ofile, &attr);
508 502 if (rc != 0)
509 503 status = smb_errno2status(rc);
510 504
511 505 return (status);
512 506 }
513 507
514 508 /*
515 509 * smb_set_rename_info
516 510 *
517 511 * This call only allows a rename in the same directory, and the
518 512 * directory name is not part of the new name provided.
519 513 *
520 514 * Explicitly specified parameter validation rules:
521 515 * - If rootdir is not NULL respond with NT_STATUS_INVALID_PARAMETER.
522 516 * - If the filename contains a separator character respond with
523 517 * NT_STATUS_INVALID_PARAMETER.
524 518 *
525 519 * Oplock break:
526 520 * Some Windows servers break BATCH oplocks prior to the rename.
527 521 * W2K3 does not. We behave as W2K3; we do not send an oplock break.
528 522 */
529 523 static uint32_t
530 524 smb_set_rename_info(smb_request_t *sr, smb_setinfo_t *sinfo)
531 525 {
532 526 smb_fqi_t *src_fqi = &sr->arg.dirop.fqi;
533 527 smb_fqi_t *dst_fqi = &sr->arg.dirop.dst_fqi;
534 528 char *fname;
535 529 char *path;
536 530 uint8_t flags;
537 531 uint32_t rootdir, namelen;
538 532 uint32_t status = 0;
539 533 int rc;
540 534
541 535 rc = smb_mbc_decodef(&sinfo->si_data, "b...ll",
542 536 &flags, &rootdir, &namelen);
543 537 if (rc == 0) {
544 538 rc = smb_mbc_decodef(&sinfo->si_data, "%#U",
545 539 sr, namelen, &fname);
546 540 }
547 541 if (rc != 0)
548 542 return (NT_STATUS_INFO_LENGTH_MISMATCH);
549 543
550 544 if ((rootdir != 0) || (namelen == 0) || (namelen >= MAXNAMELEN)) {
551 545 return (NT_STATUS_INVALID_PARAMETER);
552 546 }
553 547
554 548 if (strchr(fname, '\\') != NULL) {
555 549 return (NT_STATUS_NOT_SUPPORTED);
556 550 }
557 551
558 552 /*
559 553 * Construct the full dst. path relative to the share root.
560 554 * Allocated path is free'd in smb_request_free.
561 555 */
562 556 path = smb_srm_zalloc(sr, SMB_MAXPATHLEN);
563 557 if (src_fqi->fq_path.pn_pname) {
564 558 /* Got here via: smb_set_by_path */
565 559 (void) snprintf(path, SMB_MAXPATHLEN, "%s\\%s",
566 560 src_fqi->fq_path.pn_pname, fname);
567 561 } else {
568 562 /* Got here via: smb_set_by_fid */
569 563 rc = smb_node_getshrpath(sinfo->si_node->n_dnode,
570 564 sr->tid_tree, path, SMB_MAXPATHLEN);
571 565 if (rc != 0) {
572 566 status = smb_errno2status(rc);
573 567 return (status);
574 568 }
575 569 (void) strlcat(path, "\\", SMB_MAXPATHLEN);
576 570 (void) strlcat(path, fname, SMB_MAXPATHLEN);
577 571 }
578 572
579 573 /*
580 574 * The common rename code can slightly optimize a
581 575 * rename in the same directory when we set the
582 576 * dst_fqi->fq_dnode, dst_fqi->fq_last_comp
583 577 */
584 578 dst_fqi->fq_dnode = sinfo->si_node->n_dnode;
585 579 (void) strlcpy(dst_fqi->fq_last_comp, fname, MAXNAMELEN);
586 580
587 581 status = smb_setinfo_rename(sr, sinfo->si_node, path, flags);
588 582 return (status);
589 583 }
|
↓ open down ↓ |
234 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX