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 265331Samw #pragma ident "%Z%%M% %I% %E% SMI" 275331Samw 285331Samw #include <smbsrv/smb_incl.h> 295331Samw 305331Samw #define SMB_CREATE_NAMEBUF_SZ 16 315331Samw 325331Samw static uint32_t smb_common_create(struct smb_request *sr); 335331Samw 345331Samw /* 355331Samw * Create a new file, or truncate an existing file to zero length, 365331Samw * open the file and return a fid. The file is specified using a 375331Samw * fully qualified name relative to the tree. 385331Samw */ 39*6030Sjb150015 smb_sdrc_t 405331Samw smb_com_create(struct smb_request *sr) 415331Samw { 425331Samw struct open_param *op = &sr->arg.open; 435331Samw 445331Samw bzero(op, sizeof (sr->arg.open)); 455331Samw 46*6030Sjb150015 if (smbsr_decode_vwv(sr, "wl", &op->dattr, &op->utime.tv_sec) != 0) 47*6030Sjb150015 return (SDRC_ERROR_REPLY); 485331Samw 49*6030Sjb150015 if (smbsr_decode_data(sr, "%S", sr, &op->fqi.path) != 0) 50*6030Sjb150015 return (SDRC_ERROR_REPLY); 515331Samw 525331Samw op->create_disposition = FILE_OVERWRITE_IF; 535331Samw 54*6030Sjb150015 if (smb_common_create(sr) != NT_STATUS_SUCCESS) 55*6030Sjb150015 return (SDRC_ERROR_REPLY); 565331Samw 57*6030Sjb150015 if (smbsr_encode_result(sr, 1, 0, "bww", 1, sr->smb_fid, 0)) 58*6030Sjb150015 return (SDRC_ERROR_REPLY); 595331Samw 605331Samw return (SDRC_NORMAL_REPLY); 615331Samw } 625331Samw 635331Samw /* 645331Samw * Create a new file and return a fid. The file is specified using 655331Samw * a fully qualified name relative to the tree. 665331Samw */ 67*6030Sjb150015 smb_sdrc_t 685331Samw smb_com_create_new(struct smb_request *sr) 695331Samw { 705331Samw struct open_param *op = &sr->arg.open; 715331Samw 725331Samw bzero(op, sizeof (sr->arg.open)); 735331Samw 74*6030Sjb150015 if (smbsr_decode_vwv(sr, "wl", &op->dattr, &op->utime.tv_sec) != 0) 75*6030Sjb150015 return (SDRC_ERROR_REPLY); 765331Samw 77*6030Sjb150015 if (smbsr_decode_data(sr, "%S", sr, &op->fqi.path) != 0) 78*6030Sjb150015 return (SDRC_ERROR_REPLY); 795331Samw 805331Samw op->create_disposition = FILE_CREATE; 815331Samw 82*6030Sjb150015 if (smb_common_create(sr) != NT_STATUS_SUCCESS) 83*6030Sjb150015 return (SDRC_ERROR_REPLY); 845331Samw 85*6030Sjb150015 if (smbsr_encode_result(sr, 1, 0, "bww", 1, sr->smb_fid, 0)) 86*6030Sjb150015 return (SDRC_ERROR_REPLY); 875331Samw 885331Samw return (SDRC_NORMAL_REPLY); 895331Samw } 905331Samw 915331Samw 925331Samw /* 935331Samw * Create a unique file in the specified directory relative to the 945331Samw * current tree. No attributes are specified. 955331Samw */ 96*6030Sjb150015 smb_sdrc_t 975331Samw smb_com_create_temporary(struct smb_request *sr) 985331Samw { 995331Samw static uint16_t tmp_id = 10000; 1005331Samw struct open_param *op = &sr->arg.open; 1015331Samw char name[SMB_CREATE_NAMEBUF_SZ]; 1025331Samw char *buf; 1035331Samw uint16_t reserved; 1045331Samw uint16_t bcc; 1055331Samw 1065331Samw bzero(op, sizeof (sr->arg.open)); 1075331Samw 108*6030Sjb150015 if (smbsr_decode_vwv(sr, "wl", &reserved, &op->utime.tv_sec) != 0) 109*6030Sjb150015 return (SDRC_ERROR_REPLY); 1105331Samw 111*6030Sjb150015 if (smbsr_decode_data(sr, "%S", sr, &op->fqi.path) != 0) 112*6030Sjb150015 return (SDRC_ERROR_REPLY); 1135331Samw 1145331Samw ++tmp_id; 1155331Samw bcc = 1; /* null terminator */ 1165331Samw bcc += snprintf(name, SMB_CREATE_NAMEBUF_SZ, "tt%05d.tmp", tmp_id); 1175331Samw 1185331Samw buf = smbsr_malloc(&sr->request_storage, MAXPATHLEN); 1195331Samw (void) snprintf(buf, MAXPATHLEN, "%s\\%s", op->fqi.path, name); 1205331Samw op->fqi.path = buf; 1215331Samw op->create_disposition = FILE_CREATE; 1225331Samw 123*6030Sjb150015 if (smb_common_create(sr) != NT_STATUS_SUCCESS) 124*6030Sjb150015 return (SDRC_ERROR_REPLY); 1255331Samw 126*6030Sjb150015 if (smbsr_encode_result(sr, 1, 0, "bwwbs", 1, sr->smb_fid, bcc, 4, 127*6030Sjb150015 name)) 128*6030Sjb150015 return (SDRC_ERROR_REPLY); 1295331Samw 1305331Samw return (SDRC_NORMAL_REPLY); 1315331Samw } 1325331Samw 1335331Samw /* 1345331Samw * Common create file function. The file is opened in compatibility 1355331Samw * mode with read/write access. 1365331Samw */ 1375331Samw uint32_t 1385331Samw smb_common_create(struct smb_request *sr) 1395331Samw { 1405331Samw struct open_param *op = &sr->arg.open; 1415331Samw uint32_t status; 1425331Samw 1435331Samw op->utime.tv_sec = smb_local_time_to_gmt(op->utime.tv_sec); 1445331Samw op->utime.tv_nsec = 0; 1455331Samw op->omode = SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY; 1465331Samw op->desired_access = smb_omode_to_amask(op->omode); 1475331Samw op->share_access = smb_denymode_to_sharemode(op->omode, op->fqi.path); 1485331Samw 1495331Samw if ((op->desired_access == ((uint32_t)SMB_INVALID_AMASK)) || 1505331Samw (op->share_access == ((uint32_t)SMB_INVALID_SHAREMODE))) { 1515772Sas200622 smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 1525331Samw ERRDOS, ERROR_INVALID_PARAMETER); 153*6030Sjb150015 return (NT_STATUS_INVALID_PARAMETER); 1545331Samw } 1555331Samw 1565331Samw op->dsize = 0; 1575331Samw 1585331Samw if (sr->smb_flg & SMB_FLAGS_OPLOCK) { 1595331Samw if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY) { 1605331Samw op->my_flags = MYF_BATCH_OPLOCK; 1615331Samw } else { 1625331Samw op->my_flags = MYF_EXCLUSIVE_OPLOCK; 1635331Samw } 1645331Samw } 1655331Samw 166*6030Sjb150015 status = smb_common_open(sr); 1675331Samw 1685331Samw if (MYF_OPLOCK_TYPE(op->my_flags) == MYF_OPLOCK_NONE) { 1695331Samw sr->smb_flg &= 1705331Samw ~(SMB_FLAGS_OPLOCK | SMB_FLAGS_OPLOCK_NOTIFY_ANY); 1715331Samw } 1725331Samw 1735331Samw return (status); 1745331Samw } 175