15331Samw /* 25331Samw * CDDL HEADER START 35331Samw * 45331Samw * The contents of this file are subject to the terms of the 55331Samw * Common Development and Distribution License (the "License"). 65331Samw * You may not use this file except in compliance with the License. 75331Samw * 85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95331Samw * or http://www.opensolaris.org/os/licensing. 105331Samw * See the License for the specific language governing permissions 115331Samw * and limitations under the License. 125331Samw * 135331Samw * When distributing Covered Code, include this CDDL HEADER in each 145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155331Samw * If applicable, add the following below this CDDL HEADER, with the 165331Samw * fields enclosed by brackets "[]" replaced with your own identifying 175331Samw * information: Portions Copyright [yyyy] [name of copyright owner] 185331Samw * 195331Samw * CDDL HEADER END 205331Samw */ 215331Samw /* 225772Sas200622 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 235331Samw * Use is subject to license terms. 245331Samw */ 255331Samw 26*7348SJose.Borrego@Sun.COM #pragma ident "@(#)smb_delete.c 1.10 08/08/07 SMI" 275331Samw 285331Samw #include <smbsrv/smb_incl.h> 295331Samw #include <smbsrv/smb_fsops.h> 305331Samw #include <smbsrv/smbinfo.h> 315772Sas200622 #include <sys/nbmlock.h> 325331Samw 336139Sjb150015 static uint32_t smb_delete_check(smb_request_t *, smb_node_t *); 34*7348SJose.Borrego@Sun.COM static boolean_t smb_delete_check_path(smb_request_t *, boolean_t *); 355331Samw 365331Samw /* 375331Samw * smb_com_delete 385331Samw * 395331Samw * The delete file message is sent to delete a data file. The appropriate 405331Samw * Tid and additional pathname are passed. Read only files may not be 415331Samw * deleted, the read-only attribute must be reset prior to file deletion. 425331Samw * 435331Samw * NT supports a hidden permission known as File Delete Child (FDC). If 445331Samw * the user has FullControl access to a directory, the user is permitted 455331Samw * to delete any object in the directory regardless of the permissions 465331Samw * on the object. 475331Samw * 485331Samw * Client Request Description 495331Samw * ================================== ================================= 505331Samw * UCHAR WordCount; Count of parameter words = 1 515331Samw * USHORT SearchAttributes; 525331Samw * USHORT ByteCount; Count of data bytes; min = 2 535331Samw * UCHAR BufferFormat; 0x04 545331Samw * STRING FileName[]; File name 555331Samw * 565331Samw * Multiple files may be deleted in response to a single request as 575331Samw * SMB_COM_DELETE supports wildcards 585331Samw * 595331Samw * SearchAttributes indicates the attributes that the target file(s) must 605331Samw * have. If the attribute is zero then only normal files are deleted. If 615331Samw * the system file or hidden attributes are specified then the delete is 625331Samw * inclusive -both the specified type(s) of files and normal files are 635331Samw * deleted. Attributes are described in the "Attribute Encoding" section 645331Samw * of this document. 655331Samw * 665331Samw * If bit0 of the Flags2 field of the SMB header is set, a pattern is 675331Samw * passed in, and the file has a long name, then the passed pattern much 685331Samw * match the long file name for the delete to succeed. If bit0 is clear, a 695331Samw * pattern is passed in, and the file has a long name, then the passed 705331Samw * pattern must match the file's short name for the deletion to succeed. 715331Samw * 725331Samw * Server Response Description 735331Samw * ================================== ================================= 745331Samw * UCHAR WordCount; Count of parameter words = 0 755331Samw * USHORT ByteCount; Count of data bytes = 0 765331Samw * 775331Samw * 4.2.10.1 Errors 785331Samw * 795331Samw * ERRDOS/ERRbadpath 805331Samw * ERRDOS/ERRbadfile 815331Samw * ERRDOS/ERRnoaccess 825331Samw * ERRDOS/ERRbadshare # returned by NT for files that are already open 835331Samw * ERRHRD/ERRnowrite 845331Samw * ERRSRV/ERRaccess 855331Samw * ERRSRV/ERRinvdevice 865331Samw * ERRSRV/ERRinvid 875331Samw * ERRSRV/ERRbaduid 885331Samw */ 896030Sjb150015 smb_sdrc_t 906139Sjb150015 smb_pre_delete(smb_request_t *sr) 915331Samw { 926139Sjb150015 struct smb_fqi *fqi = &sr->arg.dirop.fqi; 936139Sjb150015 int rc; 946139Sjb150015 956139Sjb150015 if ((rc = smbsr_decode_vwv(sr, "w", &fqi->srch_attr)) == 0) 966139Sjb150015 rc = smbsr_decode_data(sr, "%S", sr, &fqi->path); 976139Sjb150015 986139Sjb150015 DTRACE_SMB_2(op__Delete__start, smb_request_t *, sr, 996139Sjb150015 struct smb_fqi *, fqi); 1006139Sjb150015 1016139Sjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 1026139Sjb150015 } 1036139Sjb150015 1046139Sjb150015 void 1056139Sjb150015 smb_post_delete(smb_request_t *sr) 1066139Sjb150015 { 1076139Sjb150015 DTRACE_SMB_1(op__Delete__done, smb_request_t *, sr); 1086139Sjb150015 } 1096139Sjb150015 110*7348SJose.Borrego@Sun.COM /* 111*7348SJose.Borrego@Sun.COM * smb_com_delete 112*7348SJose.Borrego@Sun.COM * 113*7348SJose.Borrego@Sun.COM * readonly 114*7348SJose.Borrego@Sun.COM * If a readonly entry is matched the search aborts with status 115*7348SJose.Borrego@Sun.COM * NT_STATUS_CANNOT_DELETE. Entries found prior to the readonly 116*7348SJose.Borrego@Sun.COM * entry will have been deleted. 117*7348SJose.Borrego@Sun.COM * 118*7348SJose.Borrego@Sun.COM * directories: 119*7348SJose.Borrego@Sun.COM * smb_com_delete does not delete directories: 120*7348SJose.Borrego@Sun.COM * A non-wildcard delete that finds a directory should result in 121*7348SJose.Borrego@Sun.COM * NT_STATUS_FILE_IS_A_DIRECTORY. 122*7348SJose.Borrego@Sun.COM * A wildcard delete that finds a directory will either: 123*7348SJose.Borrego@Sun.COM * - abort with status NT_STATUS_FILE_IS_A_DIRECTORY, if 124*7348SJose.Borrego@Sun.COM * FILE_ATTRIBUTE_DIRECTORY is specified in the search attributes, or 125*7348SJose.Borrego@Sun.COM * - skip that entry, if FILE_ATTRIBUTE_DIRECTORY is NOT specified 126*7348SJose.Borrego@Sun.COM * in the search attributes 127*7348SJose.Borrego@Sun.COM * Entries found prior to the directory entry will have been deleted. 128*7348SJose.Borrego@Sun.COM * 129*7348SJose.Borrego@Sun.COM * search attribute not matched 130*7348SJose.Borrego@Sun.COM * If an entry is found but it is either hidden or system and those 131*7348SJose.Borrego@Sun.COM * attributes are not specified in the search attributes: 132*7348SJose.Borrego@Sun.COM * - if deleting a single file, status NT_STATUS_NO_SUCH_FILE 133*7348SJose.Borrego@Sun.COM * - if wildcard delete, skip the entry and continue 134*7348SJose.Borrego@Sun.COM * 135*7348SJose.Borrego@Sun.COM * path not found 136*7348SJose.Borrego@Sun.COM * If smb_rdir_open cannot find the specified path, the error code 137*7348SJose.Borrego@Sun.COM * is set to NT_STATUS_OBJECT_PATH_NOT_FOUND. If there are wildcards 138*7348SJose.Borrego@Sun.COM * in the last_component, NT_STATUS_OBJECT_NAME_NOT_FOUND should be set 139*7348SJose.Borrego@Sun.COM * instead. 140*7348SJose.Borrego@Sun.COM * 141*7348SJose.Borrego@Sun.COM * smb_delete_check_path() - checks dot, bad path syntax, wildcards in path 142*7348SJose.Borrego@Sun.COM */ 143*7348SJose.Borrego@Sun.COM 1446139Sjb150015 smb_sdrc_t 1456139Sjb150015 smb_com_delete(smb_request_t *sr) 1466139Sjb150015 { 1476139Sjb150015 struct smb_fqi *fqi = &sr->arg.dirop.fqi; 148*7348SJose.Borrego@Sun.COM int rc; 149*7348SJose.Borrego@Sun.COM int deleted = 0; 1507052Samw struct smb_node *node = NULL; 1515331Samw smb_odir_context_t *pc; 152*7348SJose.Borrego@Sun.COM unsigned short sattr; 153*7348SJose.Borrego@Sun.COM boolean_t wildcards; 1545331Samw 155*7348SJose.Borrego@Sun.COM if (smb_delete_check_path(sr, &wildcards) != B_TRUE) 1566139Sjb150015 return (SDRC_ERROR); 1575772Sas200622 158*7348SJose.Borrego@Sun.COM /* 159*7348SJose.Borrego@Sun.COM * specify all search attributes so that delete-specific 160*7348SJose.Borrego@Sun.COM * search attribute handling can be performed 161*7348SJose.Borrego@Sun.COM */ 162*7348SJose.Borrego@Sun.COM sattr = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_HIDDEN | 163*7348SJose.Borrego@Sun.COM FILE_ATTRIBUTE_SYSTEM; 164*7348SJose.Borrego@Sun.COM 165*7348SJose.Borrego@Sun.COM if (smb_rdir_open(sr, fqi->path, sattr) != 0) { 166*7348SJose.Borrego@Sun.COM /* 167*7348SJose.Borrego@Sun.COM * If there are wildcards in the last_component, 168*7348SJose.Borrego@Sun.COM * NT_STATUS_OBJECT_NAME_NOT_FOUND 169*7348SJose.Borrego@Sun.COM * should be used in place of NT_STATUS_OBJECT_PATH_NOT_FOUND 170*7348SJose.Borrego@Sun.COM */ 171*7348SJose.Borrego@Sun.COM if ((wildcards == B_TRUE) && 172*7348SJose.Borrego@Sun.COM (sr->smb_error.status == NT_STATUS_OBJECT_PATH_NOT_FOUND)) { 173*7348SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND, 174*7348SJose.Borrego@Sun.COM ERRDOS, ERROR_FILE_NOT_FOUND); 175*7348SJose.Borrego@Sun.COM } 176*7348SJose.Borrego@Sun.COM 177*7348SJose.Borrego@Sun.COM return (SDRC_ERROR); 178*7348SJose.Borrego@Sun.COM } 179*7348SJose.Borrego@Sun.COM 1805331Samw pc = kmem_zalloc(sizeof (*pc), KM_SLEEP); 1815331Samw 1825331Samw /* 1835331Samw * This while loop is meant to deal with wildcards. 1845331Samw * It is not expected that wildcards will exist for 1855331Samw * streams. For the streams case, it is expected 1865331Samw * that the below loop will be executed only once. 1875331Samw */ 1885331Samw 1895331Samw while ((rc = smb_rdir_next(sr, &node, pc)) == 0) { 190*7348SJose.Borrego@Sun.COM /* check directory */ 1917052Samw if (pc->dc_dattr & FILE_ATTRIBUTE_DIRECTORY) { 192*7348SJose.Borrego@Sun.COM smb_node_release(node); 193*7348SJose.Borrego@Sun.COM if (wildcards == B_FALSE) { 194*7348SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_FILE_IS_A_DIRECTORY, 195*7348SJose.Borrego@Sun.COM ERRDOS, ERROR_ACCESS_DENIED); 196*7348SJose.Borrego@Sun.COM goto delete_error; 197*7348SJose.Borrego@Sun.COM } else { 198*7348SJose.Borrego@Sun.COM if (SMB_SEARCH_DIRECTORY(fqi->srch_attr) != 0) 199*7348SJose.Borrego@Sun.COM break; 200*7348SJose.Borrego@Sun.COM else 201*7348SJose.Borrego@Sun.COM continue; 202*7348SJose.Borrego@Sun.COM } 203*7348SJose.Borrego@Sun.COM } 204*7348SJose.Borrego@Sun.COM 205*7348SJose.Borrego@Sun.COM /* check readonly */ 206*7348SJose.Borrego@Sun.COM if (SMB_PATHFILE_IS_READONLY(sr, node)) { 207*7348SJose.Borrego@Sun.COM smb_node_release(node); 208*7348SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_CANNOT_DELETE, 2096139Sjb150015 ERRDOS, ERROR_ACCESS_DENIED); 2105772Sas200622 goto delete_error; 2115772Sas200622 } 2125772Sas200622 213*7348SJose.Borrego@Sun.COM /* check search attributes */ 214*7348SJose.Borrego@Sun.COM if (((pc->dc_dattr & FILE_ATTRIBUTE_HIDDEN) && 215*7348SJose.Borrego@Sun.COM !(SMB_SEARCH_HIDDEN(fqi->srch_attr))) || 216*7348SJose.Borrego@Sun.COM ((pc->dc_dattr & FILE_ATTRIBUTE_SYSTEM) && 217*7348SJose.Borrego@Sun.COM !(SMB_SEARCH_SYSTEM(fqi->srch_attr)))) { 2185331Samw smb_node_release(node); 219*7348SJose.Borrego@Sun.COM if (wildcards == B_FALSE) { 220*7348SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_NO_SUCH_FILE, 221*7348SJose.Borrego@Sun.COM ERRDOS, ERROR_FILE_NOT_FOUND); 222*7348SJose.Borrego@Sun.COM goto delete_error; 223*7348SJose.Borrego@Sun.COM } else { 224*7348SJose.Borrego@Sun.COM continue; 225*7348SJose.Borrego@Sun.COM } 2265331Samw } 2275331Samw 2285772Sas200622 /* 2295772Sas200622 * NT does not always close a file immediately, which 2305772Sas200622 * can cause the share and access checking to fail 2315772Sas200622 * (the node refcnt is greater than one), and the file 2325772Sas200622 * doesn't get deleted. Breaking the oplock before 2335772Sas200622 * share and access checking gives the client a chance 2345772Sas200622 * to close the file. 2355772Sas200622 */ 2365772Sas200622 2376600Sas200622 smb_oplock_break(node); 2385772Sas200622 2395772Sas200622 smb_node_start_crit(node, RW_READER); 2405772Sas200622 2416139Sjb150015 if (smb_delete_check(sr, node) != NT_STATUS_SUCCESS) { 2425772Sas200622 smb_node_end_crit(node); 2435772Sas200622 smb_node_release(node); 2445772Sas200622 goto delete_error; 2455772Sas200622 } 2465331Samw 2477052Samw /* 2487052Samw * Use node->od_name so as to skip mangle checks and 2497052Samw * stream processing (which have already been done in 2507052Samw * smb_rdir_next()). 2517052Samw * Use node->dir_snode to obtain the correct parent node 2527052Samw * (especially for streams). 2537052Samw */ 2547052Samw rc = smb_fsop_remove(sr, sr->user_cr, node->dir_snode, 2557052Samw node->od_name, 1); 2565331Samw 2575772Sas200622 smb_node_end_crit(node); 2585772Sas200622 smb_node_release(node); 2595772Sas200622 node = NULL; 2605772Sas200622 2615331Samw if (rc != 0) { 2626139Sjb150015 if (rc != ENOENT) { 2636139Sjb150015 smbsr_errno(sr, rc); 2646139Sjb150015 goto delete_error; 2656139Sjb150015 } 2665331Samw } else { 2675331Samw deleted++; 2685331Samw } 2695331Samw } 2705331Samw 2715331Samw if ((rc != 0) && (rc != ENOENT)) { 2726139Sjb150015 smbsr_errno(sr, rc); 2736139Sjb150015 goto delete_error; 2745331Samw } 2755331Samw 2765331Samw if (deleted == 0) { 277*7348SJose.Borrego@Sun.COM if (wildcards == B_FALSE) 2786139Sjb150015 smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND, 2796139Sjb150015 ERRDOS, ERROR_FILE_NOT_FOUND); 2806139Sjb150015 else 2816139Sjb150015 smbsr_error(sr, NT_STATUS_NO_SUCH_FILE, 2826139Sjb150015 ERRDOS, ERROR_FILE_NOT_FOUND); 2835331Samw goto delete_error; 2845331Samw } 2855331Samw 2865331Samw smb_rdir_close(sr); 2875331Samw kmem_free(pc, sizeof (*pc)); 2886030Sjb150015 2896030Sjb150015 rc = smbsr_encode_empty_result(sr); 2906139Sjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 2915331Samw 2925331Samw delete_error: 2935331Samw smb_rdir_close(sr); 2945331Samw kmem_free(pc, sizeof (*pc)); 2956139Sjb150015 return (SDRC_ERROR); 2965331Samw } 2975331Samw 2986139Sjb150015 /* 299*7348SJose.Borrego@Sun.COM * smb_delete_check_path 300*7348SJose.Borrego@Sun.COM * 301*7348SJose.Borrego@Sun.COM * Perform initial validation on the pathname and last_component. 302*7348SJose.Borrego@Sun.COM * 303*7348SJose.Borrego@Sun.COM * dot: 304*7348SJose.Borrego@Sun.COM * A filename of '.' should result in NT_STATUS_OBJECT_NAME_INVALID 305*7348SJose.Borrego@Sun.COM * Any wildcard filename that resolves to '.' should result in 306*7348SJose.Borrego@Sun.COM * NT_STATUS_OBJECT_NAME_INVALID if the search attributes include 307*7348SJose.Borrego@Sun.COM * FILE_ATTRIBUTE_DIRECTORY, otherwise handled as directory (see above). 308*7348SJose.Borrego@Sun.COM * 309*7348SJose.Borrego@Sun.COM * bad path syntax: 310*7348SJose.Borrego@Sun.COM * On unix .. at the root of a file system links to the root. Thus 311*7348SJose.Borrego@Sun.COM * an attempt to lookup "/../../.." will be the same as looking up "/" 312*7348SJose.Borrego@Sun.COM * CIFs clients expect the above to result in 313*7348SJose.Borrego@Sun.COM * NT_STATUS_OBJECT_PATH_SYNTAX_BAD. It is currently not possible 314*7348SJose.Borrego@Sun.COM * (and questionable if it's desirable) to deal with all cases 315*7348SJose.Borrego@Sun.COM * but paths beginning with \\.. are handled. See bad_paths[]. 316*7348SJose.Borrego@Sun.COM * Cases like "\\dir\\..\\.." will still result in "\\" which is 317*7348SJose.Borrego@Sun.COM * contrary to windows behavior. 318*7348SJose.Borrego@Sun.COM * 319*7348SJose.Borrego@Sun.COM * wildcards in path: 320*7348SJose.Borrego@Sun.COM * Wildcards in the path (excluding the last_component) should result 321*7348SJose.Borrego@Sun.COM * in NT_STATUS_OBJECT_NAME_INVALID. 322*7348SJose.Borrego@Sun.COM * 323*7348SJose.Borrego@Sun.COM * Returns: 324*7348SJose.Borrego@Sun.COM * B_TRUE: path is valid. Sets *wildcard to TRUE if wildcard delete 325*7348SJose.Borrego@Sun.COM * i.e. if wildcards in last component 326*7348SJose.Borrego@Sun.COM * B_FALSE: path is invalid. Sets error information in sr. 327*7348SJose.Borrego@Sun.COM */ 328*7348SJose.Borrego@Sun.COM static boolean_t 329*7348SJose.Borrego@Sun.COM smb_delete_check_path(smb_request_t *sr, boolean_t *wildcard) 330*7348SJose.Borrego@Sun.COM { 331*7348SJose.Borrego@Sun.COM struct smb_fqi *fqi = &sr->arg.dirop.fqi; 332*7348SJose.Borrego@Sun.COM char *p, *last_component; 333*7348SJose.Borrego@Sun.COM int i, wildcards; 334*7348SJose.Borrego@Sun.COM 335*7348SJose.Borrego@Sun.COM struct { 336*7348SJose.Borrego@Sun.COM char *name; 337*7348SJose.Borrego@Sun.COM int len; 338*7348SJose.Borrego@Sun.COM } *bad, bad_paths[] = { 339*7348SJose.Borrego@Sun.COM {"\\..\0", 4}, 340*7348SJose.Borrego@Sun.COM {"\\..\\", 4}, 341*7348SJose.Borrego@Sun.COM {"..\0", 3}, 342*7348SJose.Borrego@Sun.COM {"..\\", 3} 343*7348SJose.Borrego@Sun.COM }; 344*7348SJose.Borrego@Sun.COM 345*7348SJose.Borrego@Sun.COM wildcards = smb_convert_unicode_wildcards(fqi->path); 346*7348SJose.Borrego@Sun.COM 347*7348SJose.Borrego@Sun.COM /* find last component, strip trailing '\\' */ 348*7348SJose.Borrego@Sun.COM p = fqi->path + strlen(fqi->path) - 1; 349*7348SJose.Borrego@Sun.COM while (*p == '\\') { 350*7348SJose.Borrego@Sun.COM *p = '\0'; 351*7348SJose.Borrego@Sun.COM --p; 352*7348SJose.Borrego@Sun.COM } 353*7348SJose.Borrego@Sun.COM if ((p = strrchr(fqi->path, '\\')) == NULL) { 354*7348SJose.Borrego@Sun.COM last_component = fqi->path; 355*7348SJose.Borrego@Sun.COM } else { 356*7348SJose.Borrego@Sun.COM last_component = ++p; 357*7348SJose.Borrego@Sun.COM 358*7348SJose.Borrego@Sun.COM /* 359*7348SJose.Borrego@Sun.COM * Any wildcards in path (excluding last_component) should 360*7348SJose.Borrego@Sun.COM * result in NT_STATUS_OBJECT_NAME_INVALID 361*7348SJose.Borrego@Sun.COM */ 362*7348SJose.Borrego@Sun.COM if (smb_convert_unicode_wildcards(last_component) 363*7348SJose.Borrego@Sun.COM != wildcards) { 364*7348SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID, 365*7348SJose.Borrego@Sun.COM ERRDOS, ERROR_INVALID_NAME); 366*7348SJose.Borrego@Sun.COM return (B_FALSE); 367*7348SJose.Borrego@Sun.COM } 368*7348SJose.Borrego@Sun.COM } 369*7348SJose.Borrego@Sun.COM 370*7348SJose.Borrego@Sun.COM /* 371*7348SJose.Borrego@Sun.COM * path above the mount point => NT_STATUS_OBJECT_PATH_SYNTAX_BAD 372*7348SJose.Borrego@Sun.COM * This test doesn't cover all cases: e.g. \dir\..\.. 373*7348SJose.Borrego@Sun.COM */ 374*7348SJose.Borrego@Sun.COM for (i = 0; i < sizeof (bad_paths) / sizeof (bad_paths[0]); ++i) { 375*7348SJose.Borrego@Sun.COM bad = &bad_paths[i]; 376*7348SJose.Borrego@Sun.COM if (strncmp(fqi->path, bad->name, bad->len) == 0) { 377*7348SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_OBJECT_PATH_SYNTAX_BAD, 378*7348SJose.Borrego@Sun.COM ERRDOS, ERROR_BAD_PATHNAME); 379*7348SJose.Borrego@Sun.COM return (B_FALSE); 380*7348SJose.Borrego@Sun.COM } 381*7348SJose.Borrego@Sun.COM } 382*7348SJose.Borrego@Sun.COM 383*7348SJose.Borrego@Sun.COM /* 384*7348SJose.Borrego@Sun.COM * Any file pattern that resolves to '.' is considered invalid. 385*7348SJose.Borrego@Sun.COM * In the wildcard case, only an error if FILE_ATTRIBUTE_DIRECTORY 386*7348SJose.Borrego@Sun.COM * is specified in search attributes, otherwise skipped (below) 387*7348SJose.Borrego@Sun.COM */ 388*7348SJose.Borrego@Sun.COM if ((strcmp(last_component, ".") == 0) || 389*7348SJose.Borrego@Sun.COM (SMB_SEARCH_DIRECTORY(fqi->srch_attr) && 390*7348SJose.Borrego@Sun.COM (smb_match(last_component, ".")))) { 391*7348SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID, 392*7348SJose.Borrego@Sun.COM ERRDOS, ERROR_INVALID_NAME); 393*7348SJose.Borrego@Sun.COM return (B_FALSE); 394*7348SJose.Borrego@Sun.COM } 395*7348SJose.Borrego@Sun.COM 396*7348SJose.Borrego@Sun.COM *wildcard = (wildcards != 0); 397*7348SJose.Borrego@Sun.COM return (B_TRUE); 398*7348SJose.Borrego@Sun.COM } 399*7348SJose.Borrego@Sun.COM 400*7348SJose.Borrego@Sun.COM /* 4016139Sjb150015 * For consistency with Windows 2000, the range check should be done 4026139Sjb150015 * after checking for sharing violations. Attempting to delete a 4036139Sjb150015 * locked file will result in sharing violation, which is the same 4046139Sjb150015 * thing that will happen if you try to delete a non-locked open file. 4056139Sjb150015 * 4066139Sjb150015 * Note that windows 2000 rejects lock requests on open files that 4076139Sjb150015 * have been opened with metadata open modes. The error is 4086139Sjb150015 * STATUS_ACCESS_DENIED. 4096139Sjb150015 */ 4106139Sjb150015 static uint32_t 4116139Sjb150015 smb_delete_check(smb_request_t *sr, smb_node_t *node) 4125331Samw { 4136139Sjb150015 uint32_t status; 4145331Samw 4156139Sjb150015 status = smb_node_delete_check(node); 4166139Sjb150015 4176139Sjb150015 if (status == NT_STATUS_SHARING_VIOLATION) { 4186139Sjb150015 smbsr_error(sr, NT_STATUS_SHARING_VIOLATION, 4196139Sjb150015 ERRDOS, ERROR_SHARING_VIOLATION); 4206139Sjb150015 return (status); 4215331Samw } 4225331Samw 423*7348SJose.Borrego@Sun.COM status = smb_range_check(sr, node, 0, UINT64_MAX, B_TRUE); 4245772Sas200622 4256139Sjb150015 if (status != NT_STATUS_SUCCESS) { 4266139Sjb150015 smbsr_error(sr, NT_STATUS_ACCESS_DENIED, 4276139Sjb150015 ERRDOS, ERROR_ACCESS_DENIED); 4285331Samw } 4295331Samw 4306139Sjb150015 return (status); 4315331Samw } 432