1da6c28aaSamw /* 2da6c28aaSamw * CDDL HEADER START 3da6c28aaSamw * 4da6c28aaSamw * The contents of this file are subject to the terms of the 5da6c28aaSamw * Common Development and Distribution License (the "License"). 6da6c28aaSamw * You may not use this file except in compliance with the License. 7da6c28aaSamw * 8da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da6c28aaSamw * or http://www.opensolaris.org/os/licensing. 10da6c28aaSamw * See the License for the specific language governing permissions 11da6c28aaSamw * and limitations under the License. 12da6c28aaSamw * 13da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each 14da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the 16da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying 17da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner] 18da6c28aaSamw * 19da6c28aaSamw * CDDL HEADER END 20da6c28aaSamw */ 21da6c28aaSamw /* 222c2961f8Sjose borrego * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23da6c28aaSamw * Use is subject to license terms. 24da6c28aaSamw */ 25da6c28aaSamw 26da6c28aaSamw /* 27da6c28aaSamw * This command is used to create or open a file or directory. 28da6c28aaSamw */ 29da6c28aaSamw 30da6c28aaSamw 31da6c28aaSamw #include <smbsrv/smb_incl.h> 32da6c28aaSamw #include <smbsrv/smb_fsops.h> 33da6c28aaSamw #include <smbsrv/smb_vops.h> 34da6c28aaSamw 35da6c28aaSamw /* 36da6c28aaSamw * smb_com_nt_create_andx 37da6c28aaSamw * 38da6c28aaSamw * This command is used to create or open a file or directory. 39da6c28aaSamw * 40da6c28aaSamw * Client Request Description 41da6c28aaSamw * ================================= ================================== 42da6c28aaSamw * 43da6c28aaSamw * UCHAR WordCount; Count of parameter words = 24 44da6c28aaSamw * UCHAR AndXCommand; Secondary command; 0xFF = None 45da6c28aaSamw * UCHAR AndXReserved; Reserved (must be 0) 46da6c28aaSamw * USHORT AndXOffset; Offset to next command WordCount 47da6c28aaSamw * UCHAR Reserved; Reserved (must be 0) 48da6c28aaSamw * USHORT NameLength; Length of Name[] in bytes 49da6c28aaSamw * ULONG Flags; Create bit set: 50da6c28aaSamw * 0x02 - Request an oplock 51da6c28aaSamw * 0x04 - Request a batch oplock 52da6c28aaSamw * 0x08 - Target of open must be 53da6c28aaSamw * directory 54da6c28aaSamw * ULONG RootDirectoryFid; If non-zero, open is relative to 55da6c28aaSamw * this directory 56da6c28aaSamw * ACCESS_MASK DesiredAccess; access desired 57da6c28aaSamw * LARGE_INTEGER AllocationSize; Initial allocation size 58da6c28aaSamw * ULONG ExtFileAttributes; File attributes 59da6c28aaSamw * ULONG ShareAccess; Type of share access 60da6c28aaSamw * ULONG CreateDisposition; Action to take if file exists or 61da6c28aaSamw * not 62da6c28aaSamw * ULONG CreateOptions; Options to use if creating a file 63da6c28aaSamw * ULONG ImpersonationLevel; Security QOS information 64da6c28aaSamw * UCHAR SecurityFlags; Security tracking mode flags: 65da6c28aaSamw * 0x1 - SECURITY_CONTEXT_TRACKING 66da6c28aaSamw * 0x2 - SECURITY_EFFECTIVE_ONLY 67da6c28aaSamw * USHORT ByteCount; Length of byte parameters 68da6c28aaSamw * STRING Name[]; File to open or create 69da6c28aaSamw * 70da6c28aaSamw * The DesiredAccess parameter is specified in section 3.7 on Access Mask 71da6c28aaSamw * Encoding. 72da6c28aaSamw * 73da6c28aaSamw * If no value is specified, it still allows an application to query 74da6c28aaSamw * attributes without actually accessing the file. 75da6c28aaSamw * 76da6c28aaSamw * The ExtFIleAttributes parameter specifies the file attributes and flags 77da6c28aaSamw * for the file. The parameter's value is the sum of allowed attributes and 78da6c28aaSamw * flags defined in section 3.11 on Extended File Attribute Encoding 79da6c28aaSamw * 80da6c28aaSamw * The ShareAccess field Specifies how this file can be shared. This 81da6c28aaSamw * parameter must be some combination of the following values: 82da6c28aaSamw * 83da6c28aaSamw * Name Value Meaning 84da6c28aaSamw * 0 Prevents the file from being shared. 85da6c28aaSamw * FILE_SHARE_READ 0x00000001 Other open operations can be performed on 86da6c28aaSamw * the file for read access. 87da6c28aaSamw * FILE_SHARE_WRITE 0x00000002 Other open operations can be performed on 88da6c28aaSamw * the file for write access. 89da6c28aaSamw * FILE_SHARE_DELETE 0x00000004 Other open operations can be performed on 90da6c28aaSamw * the file for delete access. 91da6c28aaSamw * 92da6c28aaSamw * The CreateDisposition parameter can contain one of the following values: 93da6c28aaSamw * 94da6c28aaSamw * CREATE_NEW Creates a new file. The function fails if the 95da6c28aaSamw * specified file already exists. 96da6c28aaSamw * CREATE_ALWAYS Creates a new file. The function overwrites the file 97da6c28aaSamw * if it exists. 98da6c28aaSamw * OPEN_EXISTING Opens the file. The function fails if the file does 99da6c28aaSamw * not exist. 100da6c28aaSamw * OPEN_ALWAYS Opens the file, if it exists. If the file does not 101da6c28aaSamw * exist, act like CREATE_NEW. 102da6c28aaSamw * TRUNCATE_EXISTING Opens the file. Once opened, the file is truncated so 103da6c28aaSamw * that its size is zero bytes. The calling process must 104da6c28aaSamw * open the file with at least GENERIC_WRITE access. The 105da6c28aaSamw * function fails if the file does not exist. 106da6c28aaSamw * 107da6c28aaSamw * The ImpersonationLevel parameter can contain one or more of the 108da6c28aaSamw * following values: 109da6c28aaSamw * 110da6c28aaSamw * SECURITY_ANONYMOUS Specifies to impersonate the client at the 111da6c28aaSamw * Anonymous impersonation level. 112da6c28aaSamw * SECURITY_IDENTIFICATION Specifies to impersonate the client at the 113da6c28aaSamw * Identification impersonation level. 114da6c28aaSamw * SECURITY_IMPERSONATION Specifies to impersonate the client at the 115da6c28aaSamw * Impersonation impersonation level. 116da6c28aaSamw * SECURITY_DELEGATION Specifies to impersonate the client at the 117da6c28aaSamw * Delegation impersonation level. 118da6c28aaSamw * 119da6c28aaSamw * The SecurityFlags parameter can have either of the following two flags 120da6c28aaSamw * set: 121da6c28aaSamw * 122da6c28aaSamw * SECURITY_CONTEXT_TRACKING Specifies that the security tracking mode is 123da6c28aaSamw * dynamic. If this flag is not specified, 124da6c28aaSamw * Security Tracking Mode is static. 125da6c28aaSamw * SECURITY_EFFECTIVE_ONLY Specifies that only the enabled aspects of 126da6c28aaSamw * the client's security context are available 127da6c28aaSamw * to the server. If you do not specify this 128da6c28aaSamw * flag, all aspects of the client's security 129da6c28aaSamw * context are available. This flag allows the 130da6c28aaSamw * client to limit the groups and privileges 131da6c28aaSamw * that a server can use while impersonating the 132da6c28aaSamw * client. 133da6c28aaSamw * 134da6c28aaSamw * The response is as follows: 135da6c28aaSamw * 136da6c28aaSamw * Server Response Description 137da6c28aaSamw * ================================= ================================== 138da6c28aaSamw * 139da6c28aaSamw * UCHAR WordCount; Count of parameter words = 26 140da6c28aaSamw * UCHAR AndXCommand; Secondary 0xFF = None 141da6c28aaSamw * command; 142da6c28aaSamw * UCHAR AndXReserved; MBZ 143da6c28aaSamw * USHORT AndXOffset; Offset to next command WordCount 144da6c28aaSamw * UCHAR OplockLevel; The oplock level granted 145da6c28aaSamw * 0 - No oplock granted 146da6c28aaSamw * 1 - Exclusive oplock granted 147da6c28aaSamw * 2 - Batch oplock granted 148da6c28aaSamw * 3 - Level II oplock granted 149da6c28aaSamw * USHORT Fid; The file ID 150da6c28aaSamw * ULONG CreateAction; The action taken 151da6c28aaSamw * TIME CreationTime; The time the file was created 152da6c28aaSamw * TIME LastAccessTime; The time the file was accessed 153da6c28aaSamw * TIME LastWriteTime; The time the file was last written 154da6c28aaSamw * TIME ChangeTime; The time the file was last changed 155da6c28aaSamw * ULONG ExtFileAttributes; The file attributes 156da6c28aaSamw * LARGE_INTEGER AllocationSize; The number of bytes allocated 157da6c28aaSamw * LARGE_INTEGER EndOfFile; The end of file offset 158da6c28aaSamw * USHORT FileType; 159da6c28aaSamw * USHORT DeviceState; state of IPC device (e.g. pipe) 160da6c28aaSamw * BOOLEAN Directory; TRUE if this is a directory 161da6c28aaSamw * USHORT ByteCount; = 0 162da6c28aaSamw * 163da6c28aaSamw * The following SMBs may follow SMB_COM_NT_CREATE_ANDX: 164da6c28aaSamw * 165da6c28aaSamw * SMB_COM_READ SMB_COM_READ_ANDX 166da6c28aaSamw * SMB_COM_IOCTL 167da6c28aaSamw */ 1687b59d02dSjb150015 smb_sdrc_t 169faa1795aSjb150015 smb_pre_nt_create_andx(smb_request_t *sr) 170da6c28aaSamw { 171da6c28aaSamw struct open_param *op = &sr->arg.open; 172faa1795aSjb150015 uint8_t SecurityFlags; 173da6c28aaSamw uint32_t ImpersonationLevel; 174faa1795aSjb150015 uint16_t NameLength; 175da6c28aaSamw int rc; 176da6c28aaSamw 177faa1795aSjb150015 bzero(op, sizeof (sr->arg.open)); 178da6c28aaSamw 179da6c28aaSamw rc = smbsr_decode_vwv(sr, "5.wlllqlllllb", 180da6c28aaSamw &NameLength, 1812c2961f8Sjose borrego &op->nt_flags, 182faa1795aSjb150015 &op->rootdirfid, 183da6c28aaSamw &op->desired_access, 184da6c28aaSamw &op->dsize, 185faa1795aSjb150015 &op->dattr, 186da6c28aaSamw &op->share_access, 187da6c28aaSamw &op->create_disposition, 188da6c28aaSamw &op->create_options, 189da6c28aaSamw &ImpersonationLevel, 190da6c28aaSamw &SecurityFlags); 191da6c28aaSamw 192faa1795aSjb150015 if (rc == 0) { 193faa1795aSjb150015 if (NameLength == 0) { 194*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States op->fqi.fq_path.pn_path = "\\"; 195faa1795aSjb150015 } else if (NameLength >= MAXPATHLEN) { 196faa1795aSjb150015 smbsr_error(sr, NT_STATUS_OBJECT_PATH_NOT_FOUND, 197faa1795aSjb150015 ERRDOS, ERROR_PATH_NOT_FOUND); 198faa1795aSjb150015 rc = -1; 199faa1795aSjb150015 } else { 200faa1795aSjb150015 rc = smbsr_decode_data(sr, "%#u", sr, NameLength, 201*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States &op->fqi.fq_path.pn_path); 202da6c28aaSamw } 203da6c28aaSamw } 204da6c28aaSamw 2052c2961f8Sjose borrego op->op_oplock_level = SMB_OPLOCK_NONE; 2062c2961f8Sjose borrego if (op->nt_flags & NT_CREATE_FLAG_REQUEST_OPLOCK) { 2072c2961f8Sjose borrego if (op->nt_flags & NT_CREATE_FLAG_REQUEST_OPBATCH) 2082c2961f8Sjose borrego op->op_oplock_level = SMB_OPLOCK_BATCH; 2092c2961f8Sjose borrego else 2102c2961f8Sjose borrego op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE; 211da6c28aaSamw } 212da6c28aaSamw 213faa1795aSjb150015 DTRACE_SMB_2(op__NtCreateX__start, smb_request_t *, sr, 214faa1795aSjb150015 struct open_param *, op); 215faa1795aSjb150015 216faa1795aSjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 217faa1795aSjb150015 } 218faa1795aSjb150015 219faa1795aSjb150015 void 220faa1795aSjb150015 smb_post_nt_create_andx(smb_request_t *sr) 221faa1795aSjb150015 { 222faa1795aSjb150015 DTRACE_SMB_1(op__NtCreateX__done, smb_request_t *, sr); 223faa1795aSjb150015 } 224faa1795aSjb150015 225faa1795aSjb150015 smb_sdrc_t 226faa1795aSjb150015 smb_com_nt_create_andx(struct smb_request *sr) 227faa1795aSjb150015 { 228faa1795aSjb150015 struct open_param *op = &sr->arg.open; 229faa1795aSjb150015 unsigned char OplockLevel; 230faa1795aSjb150015 unsigned char DirFlag; 231faa1795aSjb150015 smb_attr_t new_attr; 232faa1795aSjb150015 smb_node_t *node; 233faa1795aSjb150015 int rc; 234faa1795aSjb150015 235faa1795aSjb150015 if ((op->create_options & FILE_DELETE_ON_CLOSE) && 236faa1795aSjb150015 !(op->desired_access & DELETE)) { 2372c2961f8Sjose borrego smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 2382c2961f8Sjose borrego ERRDOS, ERRbadaccess); 2392c2961f8Sjose borrego return (SDRC_ERROR); 2402c2961f8Sjose borrego } 2412c2961f8Sjose borrego 2422c2961f8Sjose borrego if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) { 2432c2961f8Sjose borrego smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 2442c2961f8Sjose borrego ERRDOS, ERRbadaccess); 245faa1795aSjb150015 return (SDRC_ERROR); 246faa1795aSjb150015 } 247faa1795aSjb150015 248faa1795aSjb150015 if (op->dattr & FILE_FLAG_WRITE_THROUGH) 249da6c28aaSamw op->create_options |= FILE_WRITE_THROUGH; 250da6c28aaSamw 251faa1795aSjb150015 if (op->dattr & FILE_FLAG_DELETE_ON_CLOSE) 252da6c28aaSamw op->create_options |= FILE_DELETE_ON_CLOSE; 253da6c28aaSamw 254b89a8333Snatalie li - Sun Microsystems - Irvine United States if (op->dattr & FILE_FLAG_BACKUP_SEMANTICS) 255b89a8333Snatalie li - Sun Microsystems - Irvine United States op->create_options |= FILE_OPEN_FOR_BACKUP_INTENT; 256b89a8333Snatalie li - Sun Microsystems - Irvine United States 257b89a8333Snatalie li - Sun Microsystems - Irvine United States if (op->create_options & FILE_OPEN_FOR_BACKUP_INTENT) 258b89a8333Snatalie li - Sun Microsystems - Irvine United States sr->user_cr = smb_user_getprivcred(sr->uid_user); 259b89a8333Snatalie li - Sun Microsystems - Irvine United States 260faa1795aSjb150015 if (op->rootdirfid == 0) { 261*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States op->fqi.fq_dnode = sr->tid_tree->t_snode; 262da6c28aaSamw } else { 263faa1795aSjb150015 sr->smb_fid = (ushort_t)op->rootdirfid; 2642c2961f8Sjose borrego smbsr_lookup_file(sr); 265da6c28aaSamw if (sr->fid_ofile == NULL) { 266dc20a302Sas200622 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, 267da6c28aaSamw ERRDOS, ERRbadfid); 268faa1795aSjb150015 return (SDRC_ERROR); 269da6c28aaSamw } 270da6c28aaSamw 271*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States op->fqi.fq_dnode = sr->fid_ofile->f_node; 272da6c28aaSamw smbsr_disconnect_file(sr); 273da6c28aaSamw } 274da6c28aaSamw 2757b59d02dSjb150015 if (smb_common_open(sr) != NT_STATUS_SUCCESS) 276faa1795aSjb150015 return (SDRC_ERROR); 277da6c28aaSamw 278da6c28aaSamw if (STYPE_ISDSK(sr->tid_tree->t_res_type)) { 2792c2961f8Sjose borrego switch (op->op_oplock_level) { 2802c2961f8Sjose borrego case SMB_OPLOCK_EXCLUSIVE: 281da6c28aaSamw OplockLevel = 1; 282da6c28aaSamw break; 2832c2961f8Sjose borrego case SMB_OPLOCK_BATCH: 284da6c28aaSamw OplockLevel = 2; 285da6c28aaSamw break; 2862c2961f8Sjose borrego case SMB_OPLOCK_LEVEL_II: 287da6c28aaSamw OplockLevel = 3; 288da6c28aaSamw break; 2892c2961f8Sjose borrego case SMB_OPLOCK_NONE: 290da6c28aaSamw default: 291da6c28aaSamw OplockLevel = 0; 292da6c28aaSamw break; 293da6c28aaSamw } 294da6c28aaSamw 295da6c28aaSamw if (op->create_options & FILE_DELETE_ON_CLOSE) 2968b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_ofile_set_delete_on_close(sr->fid_ofile); 297da6c28aaSamw 298da6c28aaSamw /* 299da6c28aaSamw * Set up the directory flag and ensure that 300da6c28aaSamw * we don't return a stale file size. 301da6c28aaSamw */ 302da6c28aaSamw node = sr->fid_ofile->f_node; 303da6c28aaSamw if (node->attr.sa_vattr.va_type == VDIR) { 304da6c28aaSamw DirFlag = 1; 305da6c28aaSamw new_attr.sa_vattr.va_size = 0; 306da6c28aaSamw } else { 307da6c28aaSamw DirFlag = 0; 308da6c28aaSamw new_attr.sa_mask = SMB_AT_SIZE; 309da6c28aaSamw (void) smb_fsop_getattr(sr, kcred, node, &new_attr); 310da6c28aaSamw node->attr.sa_vattr.va_size = new_attr.sa_vattr.va_size; 311da6c28aaSamw } 312da6c28aaSamw 3137b59d02dSjb150015 rc = smbsr_encode_result(sr, 34, 0, "bb.wbwlTTTTlqqwwbw", 314da6c28aaSamw 34, 315da6c28aaSamw sr->andx_com, 316da6c28aaSamw 0x67, 317da6c28aaSamw OplockLevel, 318da6c28aaSamw sr->smb_fid, 319da6c28aaSamw op->action_taken, 320da6c28aaSamw &node->attr.sa_crtime, 321da6c28aaSamw &node->attr.sa_vattr.va_atime, 322da6c28aaSamw &node->attr.sa_vattr.va_mtime, 323da6c28aaSamw &node->attr.sa_vattr.va_ctime, 324da6c28aaSamw op->dattr & FILE_ATTRIBUTE_MASK, 325da6c28aaSamw new_attr.sa_vattr.va_size, 326da6c28aaSamw new_attr.sa_vattr.va_size, 327da6c28aaSamw op->ftype, 328da6c28aaSamw op->devstate, 329da6c28aaSamw DirFlag, 330da6c28aaSamw 0); 331da6c28aaSamw } else { 332da6c28aaSamw /* Named PIPE */ 333da6c28aaSamw OplockLevel = 0; 3347b59d02dSjb150015 rc = smbsr_encode_result(sr, 34, 0, "bb.wbwlqqqqlqqwwbw", 335da6c28aaSamw 34, 336da6c28aaSamw sr->andx_com, 337da6c28aaSamw 0x67, 338da6c28aaSamw OplockLevel, 339da6c28aaSamw sr->smb_fid, 340da6c28aaSamw op->action_taken, 341da6c28aaSamw 0LL, 342da6c28aaSamw 0LL, 343da6c28aaSamw 0LL, 344da6c28aaSamw 0LL, 3453db3f65cSamw FILE_ATTRIBUTE_NORMAL, 346da6c28aaSamw 0x1000LL, 347da6c28aaSamw 0LL, 348da6c28aaSamw op->ftype, 349da6c28aaSamw op->devstate, 350da6c28aaSamw 0, 351da6c28aaSamw 0); 352da6c28aaSamw } 353da6c28aaSamw 354faa1795aSjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 355da6c28aaSamw } 356