Print this page
Build provider 3rd arg from smb_request_t
hacking...
NEX-1643 dtrace provider for smbsrv
Also illumos 1841:
DTrace smb provider was mis-implemented, doesn't exist.
Add back handlers for read/write raw, so that
legacy dtrace consumers can find the probes.
Kill extra arg in smb_negotiate
Fix missing "done" probe with smb_notify
Add example consumer: smb-trace.d
fix soi_pid
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/fs/smbsrv/smb_delete.c
+++ new/usr/src/uts/common/fs/smbsrv/smb_delete.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 *
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 /*
23 23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
25 25 */
26 26
27 27 #include <sys/sunddi.h>
28 28 #include <sys/nbmlock.h>
29 29
30 30 #include <smbsrv/smb_kproto.h>
31 31 #include <smbsrv/smb_fsops.h>
32 32 #include <smbsrv/smbinfo.h>
33 33
34 34 static int smb_delete_check_path(smb_request_t *);
35 35 static int smb_delete_single_file(smb_request_t *, smb_error_t *);
36 36 static int smb_delete_multiple_files(smb_request_t *, smb_error_t *);
37 37 static int smb_delete_find_fname(smb_request_t *, smb_odir_t *, char *, int);
38 38 static int smb_delete_check_dosattr(smb_request_t *, smb_error_t *);
39 39 static int smb_delete_remove_file(smb_request_t *, smb_error_t *);
40 40
41 41 static void smb_delete_error(smb_error_t *, uint32_t, uint16_t, uint16_t);
42 42
43 43 /*
44 44 * smb_com_delete
45 45 *
46 46 * The delete file message is sent to delete a data file. The appropriate
47 47 * Tid and additional pathname are passed. Read only files may not be
48 48 * deleted, the read-only attribute must be reset prior to file deletion.
49 49 *
50 50 * NT supports a hidden permission known as File Delete Child (FDC). If
51 51 * the user has FullControl access to a directory, the user is permitted
52 52 * to delete any object in the directory regardless of the permissions
53 53 * on the object.
54 54 *
55 55 * Client Request Description
56 56 * ================================== =================================
57 57 * UCHAR WordCount; Count of parameter words = 1
58 58 * USHORT SearchAttributes;
59 59 * USHORT ByteCount; Count of data bytes; min = 2
60 60 * UCHAR BufferFormat; 0x04
61 61 * STRING FileName[]; File name
62 62 *
63 63 * Multiple files may be deleted in response to a single request as
64 64 * SMB_COM_DELETE supports wildcards
65 65 *
66 66 * SearchAttributes indicates the attributes that the target file(s) must
67 67 * have. If the attribute is zero then only normal files are deleted. If
68 68 * the system file or hidden attributes are specified then the delete is
69 69 * inclusive -both the specified type(s) of files and normal files are
70 70 * deleted. Attributes are described in the "Attribute Encoding" section
71 71 * of this document.
72 72 *
73 73 * If bit0 of the Flags2 field of the SMB header is set, a pattern is
74 74 * passed in, and the file has a long name, then the passed pattern much
75 75 * match the long file name for the delete to succeed. If bit0 is clear, a
76 76 * pattern is passed in, and the file has a long name, then the passed
77 77 * pattern must match the file's short name for the deletion to succeed.
78 78 *
79 79 * Server Response Description
80 80 * ================================== =================================
81 81 * UCHAR WordCount; Count of parameter words = 0
82 82 * USHORT ByteCount; Count of data bytes = 0
83 83 *
84 84 * 4.2.10.1 Errors
85 85 *
86 86 * ERRDOS/ERRbadpath
87 87 * ERRDOS/ERRbadfile
88 88 * ERRDOS/ERRnoaccess
89 89 * ERRDOS/ERRbadshare # returned by NT for files that are already open
90 90 * ERRHRD/ERRnowrite
91 91 * ERRSRV/ERRaccess
92 92 * ERRSRV/ERRinvdevice
93 93 * ERRSRV/ERRinvid
94 94 * ERRSRV/ERRbaduid
95 95 */
96 96 smb_sdrc_t
↓ open down ↓ |
96 lines elided |
↑ open up ↑ |
97 97 smb_pre_delete(smb_request_t *sr)
98 98 {
99 99 int rc;
100 100 smb_fqi_t *fqi;
101 101
102 102 fqi = &sr->arg.dirop.fqi;
103 103
104 104 if ((rc = smbsr_decode_vwv(sr, "w", &fqi->fq_sattr)) == 0)
105 105 rc = smbsr_decode_data(sr, "%S", sr, &fqi->fq_path.pn_path);
106 106
107 - DTRACE_SMB_2(op__Delete__start, smb_request_t *, sr, smb_fqi_t *, fqi);
107 + DTRACE_SMB_1(op__Delete__start, smb_request_t *, sr); /* arg.dirop */
108 108
109 109 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
110 110 }
111 111
112 112 void
113 113 smb_post_delete(smb_request_t *sr)
114 114 {
115 115 DTRACE_SMB_1(op__Delete__done, smb_request_t *, sr);
116 116 }
117 117
118 118 /*
119 119 * smb_com_delete
120 120 *
121 121 * 1. intialize, pre-process and validate pathname
122 122 *
123 123 * 2. process the path to get directory node & last_comp,
124 124 * store these in fqi
125 125 * - If smb_pathname_reduce cannot find the specified path,
126 126 * the error (ENOTDIR) is translated to NT_STATUS_OBJECT_PATH_NOT_FOUND
127 127 * if the target is a single file (no wildcards). If there are
128 128 * wildcards in the last_comp, NT_STATUS_OBJECT_NAME_NOT_FOUND is
129 129 * used instead.
130 130 * - If the directory node is the mount point and the last component
131 131 * is ".." NT_STATUS_OBJECT_PATH_SYNTAX_BAD is returned.
132 132 *
133 133 * 3. check access permissions
134 134 *
135 135 * 4. invoke the appropriate deletion routine to find and remove
136 136 * the specified file(s).
137 137 * - if target is a single file (no wildcards) - smb_delete_single_file
138 138 * - if the target contains wildcards - smb_delete_multiple_files
139 139 *
140 140 * Returns: SDRC_SUCCESS or SDRC_ERROR
141 141 */
142 142 smb_sdrc_t
143 143 smb_com_delete(smb_request_t *sr)
144 144 {
145 145 int rc;
146 146 smb_error_t err;
147 147 uint32_t status;
148 148 boolean_t wildcards = B_FALSE;
149 149 smb_fqi_t *fqi;
150 150 smb_pathname_t *pn;
151 151
152 152 fqi = &sr->arg.dirop.fqi;
153 153 pn = &fqi->fq_path;
154 154
155 155 smb_pathname_init(sr, pn, pn->pn_path);
156 156 if (!smb_pathname_validate(sr, pn))
157 157 return (SDRC_ERROR);
158 158 if (smb_delete_check_path(sr) != 0)
159 159 return (SDRC_ERROR);
160 160
161 161 wildcards = smb_contains_wildcards(pn->pn_fname);
162 162
163 163 rc = smb_pathname_reduce(sr, sr->user_cr, fqi->fq_path.pn_path,
164 164 sr->tid_tree->t_snode, sr->tid_tree->t_snode,
165 165 &fqi->fq_dnode, fqi->fq_last_comp);
166 166 if (rc == 0) {
167 167 if (!smb_node_is_dir(fqi->fq_dnode)) {
168 168 smb_node_release(fqi->fq_dnode);
169 169 rc = ENOTDIR;
170 170 }
171 171 }
172 172 if (rc != 0) {
173 173 if (rc == ENOTDIR) {
174 174 if (wildcards)
175 175 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
176 176 else
177 177 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
178 178 smbsr_error(sr, status, ERRDOS, ERROR_FILE_NOT_FOUND);
179 179 } else {
180 180 smbsr_errno(sr, rc);
181 181 }
182 182
183 183 return (SDRC_ERROR);
184 184 }
185 185
186 186 if ((fqi->fq_dnode == sr->tid_tree->t_snode) &&
187 187 (strcmp(fqi->fq_last_comp, "..") == 0)) {
188 188 smb_node_release(fqi->fq_dnode);
189 189 smbsr_error(sr, NT_STATUS_OBJECT_PATH_SYNTAX_BAD,
190 190 ERRDOS, ERROR_BAD_PATHNAME);
191 191 return (SDRC_ERROR);
192 192 }
193 193
194 194 rc = smb_fsop_access(sr, sr->user_cr, fqi->fq_dnode,
195 195 FILE_LIST_DIRECTORY);
196 196 if (rc != 0) {
197 197 smb_node_release(fqi->fq_dnode);
198 198 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
199 199 ERRDOS, ERROR_ACCESS_DENIED);
200 200 return (SDRC_ERROR);
201 201 }
202 202
203 203 if (wildcards)
204 204 rc = smb_delete_multiple_files(sr, &err);
205 205 else
206 206 rc = smb_delete_single_file(sr, &err);
207 207
208 208 smb_node_release(fqi->fq_dnode);
209 209
210 210 if (rc != 0)
211 211 smbsr_set_error(sr, &err);
212 212 else
213 213 rc = smbsr_encode_empty_result(sr);
214 214
215 215 return (rc == 0 ? SDRC_SUCCESS : SDRC_ERROR);
216 216 }
217 217
218 218 /*
219 219 * smb_delete_single_file
220 220 *
221 221 * Find the specified file and, if its attributes match the search
222 222 * criteria, delete it.
223 223 *
224 224 * Returns 0 - success (file deleted)
225 225 * -1 - error, err is populated with error details
226 226 */
227 227 static int
228 228 smb_delete_single_file(smb_request_t *sr, smb_error_t *err)
229 229 {
230 230 smb_fqi_t *fqi;
231 231 smb_pathname_t *pn;
232 232
233 233 fqi = &sr->arg.dirop.fqi;
234 234 pn = &fqi->fq_path;
235 235
236 236 /* pn already initialized and validated */
237 237 if (!smb_validate_object_name(sr, pn)) {
238 238 smb_delete_error(err, sr->smb_error.status,
239 239 ERRDOS, ERROR_INVALID_NAME);
240 240 return (-1);
241 241 }
242 242
243 243 if (smb_fsop_lookup_name(sr, sr->user_cr, 0, sr->tid_tree->t_snode,
244 244 fqi->fq_dnode, fqi->fq_last_comp, &fqi->fq_fnode) != 0) {
245 245 smb_delete_error(err, NT_STATUS_OBJECT_NAME_NOT_FOUND,
246 246 ERRDOS, ERROR_FILE_NOT_FOUND);
247 247 return (-1);
248 248 }
249 249
250 250 if (smb_delete_check_dosattr(sr, err) != 0) {
251 251 smb_node_release(fqi->fq_fnode);
252 252 return (-1);
253 253 }
254 254
255 255 if (smb_delete_remove_file(sr, err) != 0) {
256 256 smb_node_release(fqi->fq_fnode);
257 257 return (-1);
258 258 }
259 259
260 260 smb_node_release(fqi->fq_fnode);
261 261 return (0);
262 262 }
263 263
264 264 /*
265 265 * smb_delete_multiple_files
266 266 *
267 267 * For each matching file found by smb_delete_find_fname:
268 268 * 1. lookup file
269 269 * 2. check the file's attributes
270 270 * - The search ends with an error if a readonly file
271 271 * (NT_STATUS_CANNOT_DELETE) is matched.
272 272 * - The search ends (but not an error) if a directory is
273 273 * matched and the request's search did not include
274 274 * directories.
275 275 * - Otherwise, if smb_delete_check_dosattr fails the file
276 276 * is skipped and the search continues (at step 1)
277 277 * 3. delete the file
278 278 *
279 279 * Returns 0 - success
280 280 * -1 - error, err is populated with error details
281 281 */
282 282 static int
283 283 smb_delete_multiple_files(smb_request_t *sr, smb_error_t *err)
284 284 {
285 285 char namebuf[MAXNAMELEN];
286 286 smb_fqi_t *fqi;
287 287 smb_odir_t *od;
288 288 uint32_t status;
289 289 int rc, deleted = 0;
290 290
291 291 fqi = &sr->arg.dirop.fqi;
292 292
293 293 /*
294 294 * Specify all search attributes (SMB_SEARCH_ATTRIBUTES) so that
295 295 * delete-specific checking can be done (smb_delete_check_dosattr).
296 296 */
297 297 status = smb_odir_openpath(sr, fqi->fq_path.pn_path,
298 298 SMB_SEARCH_ATTRIBUTES, 0, &od);
299 299 if (status != 0) {
300 300 err->status = status;
301 301 return (-1);
302 302 }
303 303
304 304 for (;;) {
305 305 rc = smb_delete_find_fname(sr, od, namebuf, MAXNAMELEN);
306 306 if (rc != 0)
307 307 break;
308 308
309 309 rc = smb_fsop_lookup_name(sr, sr->user_cr, SMB_CASE_SENSITIVE,
310 310 sr->tid_tree->t_snode, fqi->fq_dnode,
311 311 namebuf, &fqi->fq_fnode);
312 312 if (rc != 0)
313 313 break;
314 314
315 315 if (smb_delete_check_dosattr(sr, err) != 0) {
316 316 smb_node_release(fqi->fq_fnode);
317 317 if (err->status == NT_STATUS_CANNOT_DELETE) {
318 318 smb_odir_close(od);
319 319 smb_odir_release(od);
320 320 return (-1);
321 321 }
322 322 if ((err->status == NT_STATUS_FILE_IS_A_DIRECTORY) &&
323 323 (SMB_SEARCH_DIRECTORY(fqi->fq_sattr) != 0))
324 324 break;
325 325 continue;
326 326 }
327 327
328 328 if (smb_delete_remove_file(sr, err) == 0) {
329 329 ++deleted;
330 330 smb_node_release(fqi->fq_fnode);
331 331 continue;
332 332 }
333 333 if (err->status == NT_STATUS_OBJECT_NAME_NOT_FOUND) {
334 334 smb_node_release(fqi->fq_fnode);
335 335 continue;
336 336 }
337 337
338 338 smb_odir_close(od);
339 339 smb_odir_release(od);
340 340 smb_node_release(fqi->fq_fnode);
341 341 return (-1);
342 342 }
343 343
344 344 smb_odir_close(od);
345 345 smb_odir_release(od);
346 346
347 347 if ((rc != 0) && (rc != ENOENT)) {
348 348 smbsr_map_errno(rc, err);
349 349 return (-1);
350 350 }
351 351
352 352 if (deleted == 0) {
353 353 smb_delete_error(err, NT_STATUS_NO_SUCH_FILE,
354 354 ERRDOS, ERROR_FILE_NOT_FOUND);
355 355 return (-1);
356 356 }
357 357
358 358 return (0);
359 359 }
360 360
361 361 /*
362 362 * smb_delete_find_fname
363 363 *
364 364 * Find next filename that matches search pattern and return it
365 365 * in namebuf.
366 366 *
367 367 * Returns: 0 - success
368 368 * errno
369 369 */
370 370 static int
371 371 smb_delete_find_fname(smb_request_t *sr, smb_odir_t *od, char *namebuf, int len)
372 372 {
373 373 int rc;
374 374 smb_odirent_t *odirent;
375 375 boolean_t eos;
376 376
377 377 odirent = kmem_alloc(sizeof (smb_odirent_t), KM_SLEEP);
378 378
379 379 rc = smb_odir_read(sr, od, odirent, &eos);
380 380 if (rc == 0) {
381 381 (void) strlcpy(namebuf, odirent->od_name, len);
382 382 }
383 383 kmem_free(odirent, sizeof (smb_odirent_t));
384 384 return (rc);
385 385 }
386 386
387 387 /*
388 388 * smb_delete_check_dosattr
389 389 *
390 390 * Check file's dos atributes to ensure that
391 391 * 1. the file is not a directory - NT_STATUS_FILE_IS_A_DIRECTORY
392 392 * 2. the file is not readonly - NT_STATUS_CANNOT_DELETE
393 393 * 3. the file's dos attributes comply with the specified search attributes
394 394 * If the file is either hidden or system and those attributes
395 395 * are not specified in the search attributes - NT_STATUS_NO_SUCH_FILE
396 396 *
397 397 * Returns: 0 - file's attributes pass all checks
398 398 * -1 - err populated with error details
399 399 */
400 400 static int
401 401 smb_delete_check_dosattr(smb_request_t *sr, smb_error_t *err)
402 402 {
403 403 smb_fqi_t *fqi;
404 404 smb_node_t *node;
405 405 smb_attr_t attr;
406 406 uint16_t sattr;
407 407
408 408 fqi = &sr->arg.dirop.fqi;
409 409 sattr = fqi->fq_sattr;
410 410 node = fqi->fq_fnode;
411 411
412 412 bzero(&attr, sizeof (attr));
413 413 attr.sa_mask = SMB_AT_DOSATTR;
414 414 if (smb_node_getattr(sr, node, zone_kcred(), NULL, &attr) != 0) {
415 415 smb_delete_error(err, NT_STATUS_INTERNAL_ERROR,
416 416 ERRDOS, ERROR_INTERNAL_ERROR);
417 417 return (-1);
418 418 }
419 419
420 420 if (attr.sa_dosattr & FILE_ATTRIBUTE_DIRECTORY) {
421 421 smb_delete_error(err, NT_STATUS_FILE_IS_A_DIRECTORY,
422 422 ERRDOS, ERROR_ACCESS_DENIED);
423 423 return (-1);
424 424 }
425 425
426 426 if (SMB_PATHFILE_IS_READONLY(sr, node)) {
427 427 smb_delete_error(err, NT_STATUS_CANNOT_DELETE,
428 428 ERRDOS, ERROR_ACCESS_DENIED);
429 429 return (-1);
430 430 }
431 431
432 432 if ((attr.sa_dosattr & FILE_ATTRIBUTE_HIDDEN) &&
433 433 !(SMB_SEARCH_HIDDEN(sattr))) {
434 434 smb_delete_error(err, NT_STATUS_NO_SUCH_FILE,
435 435 ERRDOS, ERROR_FILE_NOT_FOUND);
436 436 return (-1);
437 437 }
438 438
439 439 if ((attr.sa_dosattr & FILE_ATTRIBUTE_SYSTEM) &&
440 440 !(SMB_SEARCH_SYSTEM(sattr))) {
441 441 smb_delete_error(err, NT_STATUS_NO_SUCH_FILE,
442 442 ERRDOS, ERROR_FILE_NOT_FOUND);
443 443 return (-1);
444 444 }
445 445
446 446 return (0);
447 447 }
448 448
449 449 /*
450 450 * smb_delete_remove_file
451 451 *
452 452 * For consistency with Windows 2000, the range check should be done
453 453 * after checking for sharing violations. Attempting to delete a
454 454 * locked file will result in sharing violation, which is the same
455 455 * thing that will happen if you try to delete a non-locked open file.
456 456 *
457 457 * Note that windows 2000 rejects lock requests on open files that
458 458 * have been opened with metadata open modes. The error is
459 459 * STATUS_ACCESS_DENIED.
460 460 *
461 461 * NT does not always close a file immediately, which can cause the
462 462 * share and access checking to fail (the node refcnt is greater
463 463 * than one), and the file doesn't get deleted. Breaking the oplock
464 464 * before share and lock checking gives the client a chance to
465 465 * close the file.
466 466 *
467 467 * Returns: 0 - success
468 468 * -1 - error, err populated with error details
469 469 */
470 470 static int
471 471 smb_delete_remove_file(smb_request_t *sr, smb_error_t *err)
472 472 {
473 473 int rc, count;
474 474 uint32_t status;
475 475 smb_fqi_t *fqi;
476 476 smb_node_t *node;
477 477 uint32_t flags = 0;
478 478
479 479 fqi = &sr->arg.dirop.fqi;
480 480 node = fqi->fq_fnode;
481 481
482 482 /*
483 483 * Break BATCH oplock before ofile checks. If a client
484 484 * has a file open, this will force a flush or close,
485 485 * which may affect the outcome of any share checking.
486 486 */
487 487 (void) smb_oplock_break(sr, node,
488 488 SMB_OPLOCK_BREAK_TO_LEVEL_II | SMB_OPLOCK_BREAK_BATCH);
489 489
490 490 /*
491 491 * Wait (a little) for the oplock break to be
492 492 * responded to by clients closing handles.
493 493 * Hold node->n_lock as reader to keep new
494 494 * ofiles from showing up after we check.
495 495 */
496 496 smb_node_rdlock(node);
497 497 for (count = 0; count <= 12; count++) {
498 498 status = smb_node_delete_check(node);
499 499 if (status != NT_STATUS_SHARING_VIOLATION)
500 500 break;
501 501 smb_node_unlock(node);
502 502 delay(MSEC_TO_TICK(100));
503 503 smb_node_rdlock(node);
504 504 }
505 505 if (status != NT_STATUS_SUCCESS) {
506 506 smb_delete_error(err, NT_STATUS_SHARING_VIOLATION,
507 507 ERRDOS, ERROR_SHARING_VIOLATION);
508 508 smb_node_unlock(node);
509 509 return (-1);
510 510 }
511 511
512 512 /*
513 513 * Note, the combination of these two:
514 514 * smb_node_rdlock(node);
515 515 * nbl_start_crit(node->vp, RW_READER);
516 516 * is equivalent to this call:
517 517 * smb_node_start_crit(node, RW_READER)
518 518 *
519 519 * Cleanup after this point should use:
520 520 * smb_node_end_crit(node)
521 521 */
522 522 nbl_start_crit(node->vp, RW_READER);
523 523
524 524 /*
525 525 * This checks nbl_share_conflict, nbl_lock_conflict
526 526 */
527 527 status = smb_nbl_conflict(node, 0, UINT64_MAX, NBL_REMOVE);
528 528 if (status == NT_STATUS_SHARING_VIOLATION) {
529 529 smb_node_end_crit(node);
530 530 smb_delete_error(err, NT_STATUS_SHARING_VIOLATION,
531 531 ERRDOS, ERROR_SHARING_VIOLATION);
532 532 return (-1);
533 533 }
534 534 if (status != NT_STATUS_SUCCESS) {
535 535 smb_node_end_crit(node);
536 536 smb_delete_error(err, NT_STATUS_ACCESS_DENIED,
537 537 ERRDOS, ERROR_ACCESS_DENIED);
538 538 return (-1);
539 539 }
540 540
541 541 if (SMB_TREE_SUPPORTS_CATIA(sr))
542 542 flags |= SMB_CATIA;
543 543
544 544 rc = smb_fsop_remove(sr, sr->user_cr, node->n_dnode,
545 545 node->od_name, flags);
546 546 if (rc != 0) {
547 547 if (rc == ENOENT)
548 548 smb_delete_error(err, NT_STATUS_OBJECT_NAME_NOT_FOUND,
549 549 ERRDOS, ERROR_FILE_NOT_FOUND);
550 550 else
551 551 smbsr_map_errno(rc, err);
552 552
553 553 smb_node_end_crit(node);
554 554 return (-1);
555 555 }
556 556
557 557 smb_node_end_crit(node);
558 558 return (0);
559 559 }
560 560
561 561
562 562 /*
563 563 * smb_delete_check_path
564 564 *
565 565 * smb_pathname_validate() should already have been used to
566 566 * perform initial validation on the pathname. Additional
567 567 * request specific validation of the filename is performed
568 568 * here.
569 569 *
570 570 * - pn->pn_fname is NULL should result in NT_STATUS_FILE_IS_A_DIRECTORY
571 571 *
572 572 * - Any wildcard filename that resolves to '.' should result in
573 573 * NT_STATUS_OBJECT_NAME_INVALID if the search attributes include
574 574 * FILE_ATTRIBUTE_DIRECTORY
575 575 *
576 576 * Returns:
577 577 * 0: path is valid.
578 578 * -1: path is invalid. Sets error information in sr.
579 579 */
580 580 static int
581 581 smb_delete_check_path(smb_request_t *sr)
582 582 {
583 583 smb_fqi_t *fqi = &sr->arg.dirop.fqi;
584 584 smb_pathname_t *pn = &fqi->fq_path;
585 585
586 586 if (pn->pn_fname == NULL) {
587 587 smbsr_error(sr, NT_STATUS_FILE_IS_A_DIRECTORY,
588 588 ERRDOS, ERROR_ACCESS_DENIED);
589 589 return (-1);
590 590 }
591 591
592 592 /* fname component is, or resolves to, '.' (dot) */
593 593 if ((strcmp(pn->pn_fname, ".") == 0) ||
594 594 (SMB_SEARCH_DIRECTORY(fqi->fq_sattr) &&
595 595 (smb_match(pn->pn_fname, ".", B_FALSE)))) {
596 596 smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
597 597 ERRDOS, ERROR_INVALID_NAME);
598 598 return (-1);
599 599 }
600 600
601 601 return (0);
602 602 }
603 603
604 604 /*
605 605 * smb_delete_error
606 606 */
607 607 static void
608 608 smb_delete_error(smb_error_t *err,
609 609 uint32_t status, uint16_t errcls, uint16_t errcode)
610 610 {
611 611 err->status = status;
612 612 err->errcls = errcls;
613 613 err->errcode = errcode;
614 614 }
↓ open down ↓ |
497 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX