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 /* 22cb174861Sjoyce mcintosh * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23*5fd03bc0SGordon Ross * Copyright 2013 Nexenta Systems, Inc. All rights reserved. 24da6c28aaSamw */ 25da6c28aaSamw 26da6c28aaSamw /* 27da6c28aaSamw * This command is used to create or open a file or directory, when EAs 28da6c28aaSamw * or an SD must be applied to the file. The functionality is similar 29da6c28aaSamw * to SmbNtCreateAndx with the option to supply extended attributes or 30da6c28aaSamw * a security descriptor. 31da6c28aaSamw * 32da6c28aaSamw * Note: we don't decode the extended attributes because we don't 33da6c28aaSamw * support them at this time. 34da6c28aaSamw */ 35da6c28aaSamw 3655bf511dSas200622 #include <smbsrv/smb_kproto.h> 37da6c28aaSamw #include <smbsrv/smb_fsops.h> 38da6c28aaSamw 39da6c28aaSamw /* 40da6c28aaSamw * smb_nt_transact_create 41da6c28aaSamw * 42da6c28aaSamw * This command is used to create or open a file or directory, when EAs 43da6c28aaSamw * or an SD must be applied to the file. The request parameter block 44da6c28aaSamw * encoding, data block encoding and output parameter block encoding are 45da6c28aaSamw * described in CIFS section 4.2.2. 46da6c28aaSamw * 47da6c28aaSamw * The format of the command is SmbNtTransact but it is basically the same 48da6c28aaSamw * as SmbNtCreateAndx with the option to supply extended attributes or a 49da6c28aaSamw * security descriptor. For information not defined in CIFS section 4.2.2 50da6c28aaSamw * see section 4.2.1 (NT_CREATE_ANDX). 51da6c28aaSamw */ 527b59d02dSjb150015 smb_sdrc_t 53faa1795aSjb150015 smb_pre_nt_transact_create(smb_request_t *sr, smb_xa_t *xa) 54da6c28aaSamw { 55da6c28aaSamw struct open_param *op = &sr->arg.open; 56da6c28aaSamw uint8_t SecurityFlags; 57da6c28aaSamw uint32_t EaLength; 58da6c28aaSamw uint32_t ImpersonationLevel; 59da6c28aaSamw uint32_t NameLength; 60faa1795aSjb150015 uint32_t sd_len; 61faa1795aSjb150015 uint32_t status; 6255bf511dSas200622 smb_sd_t sd; 63da6c28aaSamw int rc; 64da6c28aaSamw 65faa1795aSjb150015 bzero(op, sizeof (sr->arg.open)); 66faa1795aSjb150015 673db3f65cSamw rc = smb_mbc_decodef(&xa->req_param_mb, "%lllqllllllllb", 68da6c28aaSamw sr, 692c2961f8Sjose borrego &op->nt_flags, 70faa1795aSjb150015 &op->rootdirfid, 71da6c28aaSamw &op->desired_access, 72da6c28aaSamw &op->dsize, 73faa1795aSjb150015 &op->dattr, 74da6c28aaSamw &op->share_access, 75da6c28aaSamw &op->create_disposition, 76da6c28aaSamw &op->create_options, 77da6c28aaSamw &sd_len, 78da6c28aaSamw &EaLength, 79da6c28aaSamw &NameLength, 80da6c28aaSamw &ImpersonationLevel, 81da6c28aaSamw &SecurityFlags); 82da6c28aaSamw 83faa1795aSjb150015 if (rc == 0) { 84da6c28aaSamw if (NameLength == 0) { 85eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States op->fqi.fq_path.pn_path = "\\"; 86faa1795aSjb150015 } else if (NameLength >= MAXPATHLEN) { 87faa1795aSjb150015 smbsr_error(sr, NT_STATUS_OBJECT_PATH_NOT_FOUND, 88faa1795aSjb150015 ERRDOS, ERROR_PATH_NOT_FOUND); 89faa1795aSjb150015 rc = -1; 90da6c28aaSamw } else { 913db3f65cSamw rc = smb_mbc_decodef(&xa->req_param_mb, "%#u", 92eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States sr, NameLength, &op->fqi.fq_path.pn_path); 93faa1795aSjb150015 } 94da6c28aaSamw } 95da6c28aaSamw 962c2961f8Sjose borrego op->op_oplock_level = SMB_OPLOCK_NONE; 972c2961f8Sjose borrego if (op->nt_flags & NT_CREATE_FLAG_REQUEST_OPLOCK) { 982c2961f8Sjose borrego if (op->nt_flags & NT_CREATE_FLAG_REQUEST_OPBATCH) 992c2961f8Sjose borrego op->op_oplock_level = SMB_OPLOCK_BATCH; 100faa1795aSjb150015 else 1012c2961f8Sjose borrego op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE; 102da6c28aaSamw } 103da6c28aaSamw 10455bf511dSas200622 if (sd_len) { 10555bf511dSas200622 status = smb_decode_sd(xa, &sd); 10655bf511dSas200622 if (status != NT_STATUS_SUCCESS) { 107dc20a302Sas200622 smbsr_error(sr, status, 0, 0); 108faa1795aSjb150015 return (SDRC_ERROR); 109da6c28aaSamw } 110e5468186Sas200622 op->sd = kmem_alloc(sizeof (smb_sd_t), KM_SLEEP); 111e5468186Sas200622 *op->sd = sd; 112da6c28aaSamw } else { 11355bf511dSas200622 op->sd = NULL; 114da6c28aaSamw } 115da6c28aaSamw 116faa1795aSjb150015 DTRACE_SMB_2(op__NtTransactCreate__start, smb_request_t *, sr, 117faa1795aSjb150015 struct open_param *, op); 118da6c28aaSamw 119faa1795aSjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 120da6c28aaSamw } 121da6c28aaSamw 122faa1795aSjb150015 void 123faa1795aSjb150015 smb_post_nt_transact_create(smb_request_t *sr, smb_xa_t *xa) 124faa1795aSjb150015 { 125e5468186Sas200622 smb_sd_t *sd = sr->arg.open.sd; 126e5468186Sas200622 127faa1795aSjb150015 DTRACE_SMB_2(op__NtTransactCreate__done, smb_request_t *, sr, 128faa1795aSjb150015 smb_xa_t *, xa); 129e5468186Sas200622 130e5468186Sas200622 if (sd) { 131e5468186Sas200622 smb_sd_term(sd); 132e5468186Sas200622 kmem_free(sd, sizeof (smb_sd_t)); 133e5468186Sas200622 } 134bbf6f00cSJordan Brown 135bbf6f00cSJordan Brown if (sr->arg.open.dir != NULL) 136bbf6f00cSJordan Brown smb_ofile_release(sr->arg.open.dir); 137faa1795aSjb150015 } 138faa1795aSjb150015 139faa1795aSjb150015 smb_sdrc_t 140faa1795aSjb150015 smb_nt_transact_create(smb_request_t *sr, smb_xa_t *xa) 141faa1795aSjb150015 { 142faa1795aSjb150015 struct open_param *op = &sr->arg.open; 143faa1795aSjb150015 uint8_t DirFlag; 144037cac00Sjoyce mcintosh smb_attr_t attr; 145*5fd03bc0SGordon Ross smb_ofile_t *of; 146*5fd03bc0SGordon Ross int rc; 147faa1795aSjb150015 148faa1795aSjb150015 if ((op->create_options & FILE_DELETE_ON_CLOSE) && 149faa1795aSjb150015 !(op->desired_access & DELETE)) { 1502c2961f8Sjose borrego smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 1512c2961f8Sjose borrego ERRDOS, ERRbadaccess); 1522c2961f8Sjose borrego return (SDRC_ERROR); 1532c2961f8Sjose borrego } 1542c2961f8Sjose borrego 1552c2961f8Sjose borrego if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) { 1562c2961f8Sjose borrego smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 1572c2961f8Sjose borrego ERRDOS, ERRbadaccess); 158faa1795aSjb150015 return (SDRC_ERROR); 159faa1795aSjb150015 } 160faa1795aSjb150015 161faa1795aSjb150015 if (op->dattr & FILE_FLAG_WRITE_THROUGH) 162da6c28aaSamw op->create_options |= FILE_WRITE_THROUGH; 163da6c28aaSamw 164faa1795aSjb150015 if (op->dattr & FILE_FLAG_DELETE_ON_CLOSE) 165da6c28aaSamw op->create_options |= FILE_DELETE_ON_CLOSE; 166da6c28aaSamw 167b89a8333Snatalie li - Sun Microsystems - Irvine United States if (op->dattr & FILE_FLAG_BACKUP_SEMANTICS) 168b89a8333Snatalie li - Sun Microsystems - Irvine United States op->create_options |= FILE_OPEN_FOR_BACKUP_INTENT; 169b89a8333Snatalie li - Sun Microsystems - Irvine United States 170b89a8333Snatalie li - Sun Microsystems - Irvine United States if (op->create_options & FILE_OPEN_FOR_BACKUP_INTENT) 171b89a8333Snatalie li - Sun Microsystems - Irvine United States sr->user_cr = smb_user_getprivcred(sr->uid_user); 172b89a8333Snatalie li - Sun Microsystems - Irvine United States 173faa1795aSjb150015 if (op->rootdirfid == 0) { 174eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States op->fqi.fq_dnode = sr->tid_tree->t_snode; 175da6c28aaSamw } else { 176bbf6f00cSJordan Brown op->dir = smb_ofile_lookup_by_fid(sr->tid_tree, 177bbf6f00cSJordan Brown (uint16_t)op->rootdirfid); 178bbf6f00cSJordan Brown if (op->dir == NULL) { 179faa1795aSjb150015 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, 180faa1795aSjb150015 ERRDOS, ERRbadfid); 181faa1795aSjb150015 return (SDRC_ERROR); 182faa1795aSjb150015 } 183bbf6f00cSJordan Brown op->fqi.fq_dnode = op->dir->f_node; 184da6c28aaSamw } 185da6c28aaSamw 186cb174861Sjoyce mcintosh op->op_oplock_levelII = B_TRUE; 187cb174861Sjoyce mcintosh 188*5fd03bc0SGordon Ross if (smb_common_open(sr) != NT_STATUS_SUCCESS) 189faa1795aSjb150015 return (SDRC_ERROR); 190da6c28aaSamw 191*5fd03bc0SGordon Ross /* 192*5fd03bc0SGordon Ross * NB: after the above smb_common_open() success, 193*5fd03bc0SGordon Ross * we have a handle allocated (sr->fid_ofile). 194*5fd03bc0SGordon Ross * If we don't return success, we must close it. 195*5fd03bc0SGordon Ross */ 196*5fd03bc0SGordon Ross of = sr->fid_ofile; 197*5fd03bc0SGordon Ross 198f96bd5c8SAlan Wright switch (sr->tid_tree->t_res_type & STYPE_MASK) { 199f96bd5c8SAlan Wright case STYPE_DISKTREE: 200f96bd5c8SAlan Wright case STYPE_PRINTQ: 201da6c28aaSamw if (op->create_options & FILE_DELETE_ON_CLOSE) 202*5fd03bc0SGordon Ross smb_ofile_set_delete_on_close(of); 203da6c28aaSamw 204*5fd03bc0SGordon Ross DirFlag = smb_node_is_dir(of->f_node) ? 1 : 0; 205*5fd03bc0SGordon Ross bzero(&attr, sizeof (attr)); 206*5fd03bc0SGordon Ross attr.sa_mask = SMB_AT_ALL; 207*5fd03bc0SGordon Ross rc = smb_node_getattr(sr, of->f_node, of->f_cr, of, &attr); 208*5fd03bc0SGordon Ross if (rc != 0) { 209*5fd03bc0SGordon Ross smbsr_errno(sr, rc); 210*5fd03bc0SGordon Ross goto errout; 211da6c28aaSamw } 212da6c28aaSamw 2133db3f65cSamw (void) smb_mbc_encodef(&xa->rep_param_mb, "b.wllTTTTlqqwwb", 214cb174861Sjoyce mcintosh op->op_oplock_level, 215da6c28aaSamw sr->smb_fid, 216da6c28aaSamw op->action_taken, 217da6c28aaSamw 0, /* EaErrorOffset */ 218037cac00Sjoyce mcintosh &attr.sa_crtime, 219037cac00Sjoyce mcintosh &attr.sa_vattr.va_atime, 220037cac00Sjoyce mcintosh &attr.sa_vattr.va_mtime, 221037cac00Sjoyce mcintosh &attr.sa_vattr.va_ctime, 222da6c28aaSamw op->dattr & FILE_ATTRIBUTE_MASK, 223e3f2c991SKeyur Desai attr.sa_allocsz, 224037cac00Sjoyce mcintosh attr.sa_vattr.va_size, 225da6c28aaSamw op->ftype, 226da6c28aaSamw op->devstate, 227da6c28aaSamw DirFlag); 228f96bd5c8SAlan Wright break; 229f96bd5c8SAlan Wright 230f96bd5c8SAlan Wright case STYPE_IPC: 231037cac00Sjoyce mcintosh bzero(&attr, sizeof (smb_attr_t)); 2323db3f65cSamw (void) smb_mbc_encodef(&xa->rep_param_mb, "b.wllTTTTlqqwwb", 233da6c28aaSamw 0, 234da6c28aaSamw sr->smb_fid, 235da6c28aaSamw op->action_taken, 236da6c28aaSamw 0, /* EaErrorOffset */ 237037cac00Sjoyce mcintosh &attr.sa_crtime, 238037cac00Sjoyce mcintosh &attr.sa_vattr.va_atime, 239037cac00Sjoyce mcintosh &attr.sa_vattr.va_mtime, 240037cac00Sjoyce mcintosh &attr.sa_vattr.va_ctime, 241da6c28aaSamw op->dattr, 242da6c28aaSamw 0x1000LL, 243da6c28aaSamw 0LL, 244da6c28aaSamw op->ftype, 245da6c28aaSamw op->devstate, 246da6c28aaSamw 0); 247f96bd5c8SAlan Wright break; 248f96bd5c8SAlan Wright 249f96bd5c8SAlan Wright default: 250f96bd5c8SAlan Wright smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST, 251f96bd5c8SAlan Wright ERRDOS, ERROR_INVALID_FUNCTION); 252*5fd03bc0SGordon Ross goto errout; 253da6c28aaSamw } 254*5fd03bc0SGordon Ross if (rc == 0) 255faa1795aSjb150015 return (SDRC_SUCCESS); 256*5fd03bc0SGordon Ross 257*5fd03bc0SGordon Ross errout: 258*5fd03bc0SGordon Ross smb_ofile_close(of, 0); 259*5fd03bc0SGordon Ross return (SDRC_ERROR); 260da6c28aaSamw } 261