xref: /onnv-gate/usr/src/uts/common/fs/smbsrv/smb_create.c (revision 6139:5c743b207bf9)
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 
32*6139Sjb150015 static uint32_t smb_common_create(smb_request_t *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  */
396030Sjb150015 smb_sdrc_t
40*6139Sjb150015 smb_pre_create(smb_request_t *sr)
415331Samw {
425331Samw 	struct open_param *op = &sr->arg.open;
43*6139Sjb150015 	int rc;
445331Samw 
455331Samw 	bzero(op, sizeof (sr->arg.open));
465331Samw 
47*6139Sjb150015 	rc = smbsr_decode_vwv(sr, "wl", &op->dattr, &op->utime.tv_sec);
48*6139Sjb150015 	if (rc == 0)
49*6139Sjb150015 		rc = smbsr_decode_data(sr, "%S", sr, &op->fqi.path);
505331Samw 
515331Samw 	op->create_disposition = FILE_OVERWRITE_IF;
525331Samw 
53*6139Sjb150015 	DTRACE_SMB_2(op__Create__start, smb_request_t *, sr,
54*6139Sjb150015 	    struct open_param *, op);
55*6139Sjb150015 
56*6139Sjb150015 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
57*6139Sjb150015 }
58*6139Sjb150015 
59*6139Sjb150015 void
60*6139Sjb150015 smb_post_create(smb_request_t *sr)
61*6139Sjb150015 {
62*6139Sjb150015 	DTRACE_SMB_1(op__Create__done, smb_request_t *, sr);
63*6139Sjb150015 }
64*6139Sjb150015 
65*6139Sjb150015 smb_sdrc_t
66*6139Sjb150015 smb_com_create(smb_request_t *sr)
67*6139Sjb150015 {
686030Sjb150015 	if (smb_common_create(sr) != NT_STATUS_SUCCESS)
69*6139Sjb150015 		return (SDRC_ERROR);
705331Samw 
716030Sjb150015 	if (smbsr_encode_result(sr, 1, 0, "bww", 1, sr->smb_fid, 0))
72*6139Sjb150015 		return (SDRC_ERROR);
735331Samw 
74*6139Sjb150015 	return (SDRC_SUCCESS);
755331Samw }
765331Samw 
775331Samw /*
785331Samw  * Create a new file and return a fid.  The file is specified using
795331Samw  * a fully qualified name relative to the tree.
805331Samw  */
816030Sjb150015 smb_sdrc_t
82*6139Sjb150015 smb_pre_create_new(smb_request_t *sr)
835331Samw {
845331Samw 	struct open_param *op = &sr->arg.open;
85*6139Sjb150015 	int rc;
865331Samw 
875331Samw 	bzero(op, sizeof (sr->arg.open));
885331Samw 
89*6139Sjb150015 	rc = smbsr_decode_vwv(sr, "wl", &op->dattr, &op->utime.tv_sec);
90*6139Sjb150015 	if (rc == 0)
91*6139Sjb150015 		rc = smbsr_decode_data(sr, "%S", sr, &op->fqi.path);
925331Samw 
935331Samw 	op->create_disposition = FILE_CREATE;
945331Samw 
95*6139Sjb150015 	DTRACE_SMB_2(op__CreateNew__start, smb_request_t *, sr,
96*6139Sjb150015 	    struct open_param *, op);
97*6139Sjb150015 
98*6139Sjb150015 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
99*6139Sjb150015 }
100*6139Sjb150015 
101*6139Sjb150015 void
102*6139Sjb150015 smb_post_create_new(smb_request_t *sr)
103*6139Sjb150015 {
104*6139Sjb150015 	DTRACE_SMB_1(op__CreateNew__done, smb_request_t *, sr);
105*6139Sjb150015 }
106*6139Sjb150015 
107*6139Sjb150015 smb_sdrc_t
108*6139Sjb150015 smb_com_create_new(smb_request_t *sr)
109*6139Sjb150015 {
1106030Sjb150015 	if (smb_common_create(sr) != NT_STATUS_SUCCESS)
111*6139Sjb150015 		return (SDRC_ERROR);
1125331Samw 
1136030Sjb150015 	if (smbsr_encode_result(sr, 1, 0, "bww", 1, sr->smb_fid, 0))
114*6139Sjb150015 		return (SDRC_ERROR);
1155331Samw 
116*6139Sjb150015 	return (SDRC_SUCCESS);
1175331Samw }
1185331Samw 
1195331Samw /*
1205331Samw  * Create a unique file in the specified directory relative to the
1215331Samw  * current tree.  No attributes are specified.
1225331Samw  */
1236030Sjb150015 smb_sdrc_t
124*6139Sjb150015 smb_pre_create_temporary(smb_request_t *sr)
125*6139Sjb150015 {
126*6139Sjb150015 	struct open_param *op = &sr->arg.open;
127*6139Sjb150015 	uint16_t reserved;
128*6139Sjb150015 	int rc;
129*6139Sjb150015 
130*6139Sjb150015 	bzero(op, sizeof (sr->arg.open));
131*6139Sjb150015 
132*6139Sjb150015 	rc = smbsr_decode_vwv(sr, "wl", &reserved, &op->utime.tv_sec);
133*6139Sjb150015 	if (rc == 0)
134*6139Sjb150015 		rc = smbsr_decode_data(sr, "%S", sr, &op->fqi.path);
135*6139Sjb150015 
136*6139Sjb150015 	op->create_disposition = FILE_CREATE;
137*6139Sjb150015 
138*6139Sjb150015 	DTRACE_SMB_2(op__CreateTemporary__start, smb_request_t *, sr,
139*6139Sjb150015 	    struct open_param *, op);
140*6139Sjb150015 
141*6139Sjb150015 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
142*6139Sjb150015 }
143*6139Sjb150015 
144*6139Sjb150015 void
145*6139Sjb150015 smb_post_create_temporary(smb_request_t *sr)
146*6139Sjb150015 {
147*6139Sjb150015 	DTRACE_SMB_1(op__CreateTemporary__done, smb_request_t *, sr);
148*6139Sjb150015 }
149*6139Sjb150015 
150*6139Sjb150015 smb_sdrc_t
151*6139Sjb150015 smb_com_create_temporary(smb_request_t *sr)
1525331Samw {
1535331Samw 	static uint16_t tmp_id = 10000;
1545331Samw 	struct open_param *op = &sr->arg.open;
1555331Samw 	char name[SMB_CREATE_NAMEBUF_SZ];
1565331Samw 	char *buf;
1575331Samw 	uint16_t bcc;
1585331Samw 
1595331Samw 	++tmp_id;
1605331Samw 	bcc = 1; /* null terminator */
1615331Samw 	bcc += snprintf(name, SMB_CREATE_NAMEBUF_SZ, "tt%05d.tmp", tmp_id);
1625331Samw 
1635331Samw 	buf = smbsr_malloc(&sr->request_storage, MAXPATHLEN);
1645331Samw 	(void) snprintf(buf, MAXPATHLEN, "%s\\%s", op->fqi.path, name);
1655331Samw 	op->fqi.path = buf;
1665331Samw 
1676030Sjb150015 	if (smb_common_create(sr) != NT_STATUS_SUCCESS)
168*6139Sjb150015 		return (SDRC_ERROR);
1695331Samw 
170*6139Sjb150015 	if (smbsr_encode_result(sr, 1, VAR_BCC, "bww%S", 1, sr->smb_fid,
171*6139Sjb150015 	    VAR_BCC, sr, name))
172*6139Sjb150015 		return (SDRC_ERROR);
1735331Samw 
174*6139Sjb150015 	return (SDRC_SUCCESS);
1755331Samw }
1765331Samw 
1775331Samw /*
1785331Samw  * Common create file function.  The file is opened in compatibility
1795331Samw  * mode with read/write access.
1805331Samw  */
1815331Samw uint32_t
182*6139Sjb150015 smb_common_create(smb_request_t *sr)
1835331Samw {
1845331Samw 	struct open_param *op = &sr->arg.open;
1855331Samw 	uint32_t status;
1865331Samw 
187*6139Sjb150015 	op->utime.tv_sec = smb_local2gmt(sr, op->utime.tv_sec);
1885331Samw 	op->utime.tv_nsec = 0;
1895331Samw 	op->omode = SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY;
1905331Samw 	op->desired_access = smb_omode_to_amask(op->omode);
1915331Samw 	op->share_access = smb_denymode_to_sharemode(op->omode, op->fqi.path);
1925331Samw 
1935331Samw 	if ((op->desired_access == ((uint32_t)SMB_INVALID_AMASK)) ||
1945331Samw 	    (op->share_access == ((uint32_t)SMB_INVALID_SHAREMODE))) {
1955772Sas200622 		smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
1965331Samw 		    ERRDOS, ERROR_INVALID_PARAMETER);
1976030Sjb150015 		return (NT_STATUS_INVALID_PARAMETER);
1985331Samw 	}
1995331Samw 
2005331Samw 	op->dsize = 0;
2015331Samw 
2025331Samw 	if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
2035331Samw 		if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY) {
2045331Samw 			op->my_flags = MYF_BATCH_OPLOCK;
2055331Samw 		} else {
2065331Samw 			op->my_flags = MYF_EXCLUSIVE_OPLOCK;
2075331Samw 		}
2085331Samw 	}
2095331Samw 
2106030Sjb150015 	status = smb_common_open(sr);
2115331Samw 
2125331Samw 	if (MYF_OPLOCK_TYPE(op->my_flags) == MYF_OPLOCK_NONE) {
2135331Samw 		sr->smb_flg &=
2145331Samw 		    ~(SMB_FLAGS_OPLOCK | SMB_FLAGS_OPLOCK_NOTIFY_ANY);
2155331Samw 	}
2165331Samw 
2175331Samw 	return (status);
2185331Samw }
219