xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_set_fileinfo.c (revision e3f2c991a8548408db0a2787bd8b43d5124821d3)
1*e3f2c991SKeyur Desai /*
2*e3f2c991SKeyur Desai  * CDDL HEADER START
3*e3f2c991SKeyur Desai  *
4*e3f2c991SKeyur Desai  * The contents of this file are subject to the terms of the
5*e3f2c991SKeyur Desai  * Common Development and Distribution License (the "License").
6*e3f2c991SKeyur Desai  * You may not use this file except in compliance with the License.
7*e3f2c991SKeyur Desai  *
8*e3f2c991SKeyur Desai  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*e3f2c991SKeyur Desai  * or http://www.opensolaris.org/os/licensing.
10*e3f2c991SKeyur Desai  * See the License for the specific language governing permissions
11*e3f2c991SKeyur Desai  * and limitations under the License.
12*e3f2c991SKeyur Desai  *
13*e3f2c991SKeyur Desai  * When distributing Covered Code, include this CDDL HEADER in each
14*e3f2c991SKeyur Desai  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*e3f2c991SKeyur Desai  * If applicable, add the following below this CDDL HEADER, with the
16*e3f2c991SKeyur Desai  * fields enclosed by brackets "[]" replaced with your own identifying
17*e3f2c991SKeyur Desai  * information: Portions Copyright [yyyy] [name of copyright owner]
18*e3f2c991SKeyur Desai  *
19*e3f2c991SKeyur Desai  * CDDL HEADER END
20*e3f2c991SKeyur Desai  */
21*e3f2c991SKeyur Desai /*
22*e3f2c991SKeyur Desai  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23*e3f2c991SKeyur Desai  * Use is subject to license terms.
24*e3f2c991SKeyur Desai  */
25*e3f2c991SKeyur Desai 
26*e3f2c991SKeyur Desai /*
27*e3f2c991SKeyur Desai  * Trans2 Set File/Path Information Levels:
28*e3f2c991SKeyur Desai  *
29*e3f2c991SKeyur Desai  * SMB_INFO_STANDARD
30*e3f2c991SKeyur Desai  * SMB_INFO_SET_EAS
31*e3f2c991SKeyur Desai  * SMB_SET_FILE_BASIC_INFO
32*e3f2c991SKeyur Desai  * SMB_SET_FILE_DISPOSITION_INFO
33*e3f2c991SKeyur Desai  * SMB_SET_FILE_END_OF_FILE_INFO
34*e3f2c991SKeyur Desai  * SMB_SET_FILE_ALLOCATION_INFO
35*e3f2c991SKeyur Desai  *
36*e3f2c991SKeyur Desai  * Supported Passthrough levels:
37*e3f2c991SKeyur Desai  * SMB_FILE_BASIC_INFORMATION
38*e3f2c991SKeyur Desai  * SMB_FILE_DISPOSITION_INFORMATION
39*e3f2c991SKeyur Desai  * SMB_FILE_END_OF_FILE_INFORMATION
40*e3f2c991SKeyur Desai  * SMB_FILE_ALLOCATION_INFORMATION
41*e3f2c991SKeyur Desai  *
42*e3f2c991SKeyur Desai  * Internal levels representing non trans2 requests
43*e3f2c991SKeyur Desai  * SMB_SET_INFORMATION
44*e3f2c991SKeyur Desai  * SMB_SET_INFORMATION2
45*e3f2c991SKeyur Desai  */
46*e3f2c991SKeyur Desai 
47*e3f2c991SKeyur Desai /*
48*e3f2c991SKeyur Desai  * Setting timestamps:
49*e3f2c991SKeyur Desai  * The behaviour when the time field is set to -1 is not documented
50*e3f2c991SKeyur Desai  * but is generally treated like 0, meaning that that server file
51*e3f2c991SKeyur Desai  * system assigned value need not be changed.
52*e3f2c991SKeyur Desai  *
53*e3f2c991SKeyur Desai  * Setting attributes - FILE_ATTRIBUTE_NORMAL:
54*e3f2c991SKeyur Desai  * SMB_SET_INFORMATION -
55*e3f2c991SKeyur Desai  * - if the specified attributes have ONLY FILE_ATTRIBUTE_NORMAL set
56*e3f2c991SKeyur Desai  *   do NOT change the file's attributes.
57*e3f2c991SKeyur Desai  * SMB_SET_BASIC_INFO -
58*e3f2c991SKeyur Desai  * - if the specified attributes have ONLY FILE_ATTRIBUTE_NORMAL set
59*e3f2c991SKeyur Desai  *   clear (0) the file's attributes.
60*e3f2c991SKeyur Desai  * - if the specified attributes are 0 do NOT change the file's
61*e3f2c991SKeyur Desai  *   attributes.
62*e3f2c991SKeyur Desai  */
63*e3f2c991SKeyur Desai 
64*e3f2c991SKeyur Desai #include <smbsrv/smb_incl.h>
65*e3f2c991SKeyur Desai #include <smbsrv/smb_fsops.h>
66*e3f2c991SKeyur Desai 
67*e3f2c991SKeyur Desai typedef struct smb_setinfo {
68*e3f2c991SKeyur Desai 	uint16_t si_infolev;
69*e3f2c991SKeyur Desai 	smb_xa_t *si_xa;
70*e3f2c991SKeyur Desai 	smb_node_t *si_node;
71*e3f2c991SKeyur Desai } smb_setinfo_t;
72*e3f2c991SKeyur Desai 
73*e3f2c991SKeyur Desai /*
74*e3f2c991SKeyur Desai  * These functions all return 0 (success)  or -1 (error).
75*e3f2c991SKeyur Desai  * They set error details in the sr when appropriate.
76*e3f2c991SKeyur Desai  */
77*e3f2c991SKeyur Desai static int smb_set_by_fid(smb_request_t *, smb_xa_t *, uint16_t);
78*e3f2c991SKeyur Desai static int smb_set_by_path(smb_request_t *, smb_xa_t *, uint16_t, char *);
79*e3f2c991SKeyur Desai static int smb_set_fileinfo(smb_request_t *, smb_setinfo_t *);
80*e3f2c991SKeyur Desai static int smb_set_information(smb_request_t *, smb_setinfo_t *);
81*e3f2c991SKeyur Desai static int smb_set_information2(smb_request_t *, smb_setinfo_t *);
82*e3f2c991SKeyur Desai static int smb_set_standard_info(smb_request_t *, smb_setinfo_t *);
83*e3f2c991SKeyur Desai static int smb_set_basic_info(smb_request_t *, smb_setinfo_t *);
84*e3f2c991SKeyur Desai static int smb_set_disposition_info(smb_request_t *, smb_setinfo_t *);
85*e3f2c991SKeyur Desai static int smb_set_eof_info(smb_request_t *sr, smb_setinfo_t *);
86*e3f2c991SKeyur Desai static int smb_set_alloc_info(smb_request_t *sr, smb_setinfo_t *);
87*e3f2c991SKeyur Desai 
88*e3f2c991SKeyur Desai /*
89*e3f2c991SKeyur Desai  * smb_com_trans2_set_file_information
90*e3f2c991SKeyur Desai  */
91*e3f2c991SKeyur Desai smb_sdrc_t
92*e3f2c991SKeyur Desai smb_com_trans2_set_file_information(smb_request_t *sr, smb_xa_t *xa)
93*e3f2c991SKeyur Desai {
94*e3f2c991SKeyur Desai 	uint16_t infolev;
95*e3f2c991SKeyur Desai 
96*e3f2c991SKeyur Desai 	if (smb_mbc_decodef(&xa->req_param_mb, "ww",
97*e3f2c991SKeyur Desai 	    &sr->smb_fid, &infolev) != 0)
98*e3f2c991SKeyur Desai 		return (SDRC_ERROR);
99*e3f2c991SKeyur Desai 
100*e3f2c991SKeyur Desai 	if (smb_set_by_fid(sr, xa, infolev) != 0)
101*e3f2c991SKeyur Desai 		return (SDRC_ERROR);
102*e3f2c991SKeyur Desai 
103*e3f2c991SKeyur Desai 	return (SDRC_SUCCESS);
104*e3f2c991SKeyur Desai }
105*e3f2c991SKeyur Desai 
106*e3f2c991SKeyur Desai /*
107*e3f2c991SKeyur Desai  * smb_com_trans2_set_path_information
108*e3f2c991SKeyur Desai  */
109*e3f2c991SKeyur Desai smb_sdrc_t
110*e3f2c991SKeyur Desai smb_com_trans2_set_path_information(smb_request_t *sr, smb_xa_t *xa)
111*e3f2c991SKeyur Desai {
112*e3f2c991SKeyur Desai 	uint16_t infolev;
113*e3f2c991SKeyur Desai 	char *path;
114*e3f2c991SKeyur Desai 
115*e3f2c991SKeyur Desai 	if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
116*e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
117*e3f2c991SKeyur Desai 		    ERRDOS, ERROR_INVALID_FUNCTION);
118*e3f2c991SKeyur Desai 		return (SDRC_ERROR);
119*e3f2c991SKeyur Desai 	}
120*e3f2c991SKeyur Desai 
121*e3f2c991SKeyur Desai 	if (smb_mbc_decodef(&xa->req_param_mb, "%w4.u",
122*e3f2c991SKeyur Desai 	    sr, &infolev, &path) != 0)
123*e3f2c991SKeyur Desai 		return (SDRC_ERROR);
124*e3f2c991SKeyur Desai 
125*e3f2c991SKeyur Desai 	if (smb_set_by_path(sr, xa, infolev, path) != 0)
126*e3f2c991SKeyur Desai 		return (SDRC_ERROR);
127*e3f2c991SKeyur Desai 
128*e3f2c991SKeyur Desai 	return (SDRC_SUCCESS);
129*e3f2c991SKeyur Desai }
130*e3f2c991SKeyur Desai 
131*e3f2c991SKeyur Desai /*
132*e3f2c991SKeyur Desai  * smb_com_set_information (aka setattr)
133*e3f2c991SKeyur Desai  */
134*e3f2c991SKeyur Desai smb_sdrc_t
135*e3f2c991SKeyur Desai smb_pre_set_information(smb_request_t *sr)
136*e3f2c991SKeyur Desai {
137*e3f2c991SKeyur Desai 	DTRACE_SMB_1(op__SetInformation__start, smb_request_t *, sr);
138*e3f2c991SKeyur Desai 	return (SDRC_SUCCESS);
139*e3f2c991SKeyur Desai }
140*e3f2c991SKeyur Desai 
141*e3f2c991SKeyur Desai void
142*e3f2c991SKeyur Desai smb_post_set_information(smb_request_t *sr)
143*e3f2c991SKeyur Desai {
144*e3f2c991SKeyur Desai 	DTRACE_SMB_1(op__SetInformation__done, smb_request_t *, sr);
145*e3f2c991SKeyur Desai }
146*e3f2c991SKeyur Desai 
147*e3f2c991SKeyur Desai smb_sdrc_t
148*e3f2c991SKeyur Desai smb_com_set_information(smb_request_t *sr)
149*e3f2c991SKeyur Desai {
150*e3f2c991SKeyur Desai 	uint16_t infolev = SMB_SET_INFORMATION;
151*e3f2c991SKeyur Desai 	char *path;
152*e3f2c991SKeyur Desai 
153*e3f2c991SKeyur Desai 	if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
154*e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
155*e3f2c991SKeyur Desai 		    ERRDOS, ERROR_ACCESS_DENIED);
156*e3f2c991SKeyur Desai 		return (SDRC_ERROR);
157*e3f2c991SKeyur Desai 	}
158*e3f2c991SKeyur Desai 
159*e3f2c991SKeyur Desai 	if (smbsr_decode_data(sr, "%S", sr, &path) != 0)
160*e3f2c991SKeyur Desai 		return (SDRC_ERROR);
161*e3f2c991SKeyur Desai 
162*e3f2c991SKeyur Desai 	if (smb_set_by_path(sr, NULL, infolev, path) != 0)
163*e3f2c991SKeyur Desai 		return (SDRC_ERROR);
164*e3f2c991SKeyur Desai 
165*e3f2c991SKeyur Desai 	if (smbsr_encode_empty_result(sr) != 0)
166*e3f2c991SKeyur Desai 		return (SDRC_ERROR);
167*e3f2c991SKeyur Desai 
168*e3f2c991SKeyur Desai 	return (SDRC_SUCCESS);
169*e3f2c991SKeyur Desai }
170*e3f2c991SKeyur Desai 
171*e3f2c991SKeyur Desai /*
172*e3f2c991SKeyur Desai  * smb_com_set_information2 (aka setattre)
173*e3f2c991SKeyur Desai  */
174*e3f2c991SKeyur Desai smb_sdrc_t
175*e3f2c991SKeyur Desai smb_pre_set_information2(smb_request_t *sr)
176*e3f2c991SKeyur Desai {
177*e3f2c991SKeyur Desai 	DTRACE_SMB_1(op__SetInformation2__start, smb_request_t *, sr);
178*e3f2c991SKeyur Desai 	return (SDRC_SUCCESS);
179*e3f2c991SKeyur Desai }
180*e3f2c991SKeyur Desai 
181*e3f2c991SKeyur Desai void
182*e3f2c991SKeyur Desai smb_post_set_information2(smb_request_t *sr)
183*e3f2c991SKeyur Desai {
184*e3f2c991SKeyur Desai 	DTRACE_SMB_1(op__SetInformation2__done, smb_request_t *, sr);
185*e3f2c991SKeyur Desai }
186*e3f2c991SKeyur Desai 
187*e3f2c991SKeyur Desai smb_sdrc_t
188*e3f2c991SKeyur Desai smb_com_set_information2(smb_request_t *sr)
189*e3f2c991SKeyur Desai {
190*e3f2c991SKeyur Desai 	uint16_t infolev = SMB_SET_INFORMATION2;
191*e3f2c991SKeyur Desai 
192*e3f2c991SKeyur Desai 	if (smbsr_decode_vwv(sr, "w", &sr->smb_fid) != 0)
193*e3f2c991SKeyur Desai 		return (SDRC_ERROR);
194*e3f2c991SKeyur Desai 
195*e3f2c991SKeyur Desai 	if (smb_set_by_fid(sr, NULL, infolev) != 0)
196*e3f2c991SKeyur Desai 		return (SDRC_ERROR);
197*e3f2c991SKeyur Desai 
198*e3f2c991SKeyur Desai 	if (smbsr_encode_empty_result(sr) != 0)
199*e3f2c991SKeyur Desai 		return (SDRC_ERROR);
200*e3f2c991SKeyur Desai 
201*e3f2c991SKeyur Desai 	return (SDRC_SUCCESS);
202*e3f2c991SKeyur Desai }
203*e3f2c991SKeyur Desai 
204*e3f2c991SKeyur Desai /*
205*e3f2c991SKeyur Desai  * smb_set_by_fid
206*e3f2c991SKeyur Desai  *
207*e3f2c991SKeyur Desai  * Common code for setting file information by open file id.
208*e3f2c991SKeyur Desai  * Use the id to identify the node object and invoke smb_set_fileinfo
209*e3f2c991SKeyur Desai  * for that node.
210*e3f2c991SKeyur Desai  *
211*e3f2c991SKeyur Desai  * Setting attributes on a named pipe by id is handled by simply
212*e3f2c991SKeyur Desai  * returning success.
213*e3f2c991SKeyur Desai  */
214*e3f2c991SKeyur Desai static int
215*e3f2c991SKeyur Desai smb_set_by_fid(smb_request_t *sr, smb_xa_t *xa, uint16_t infolev)
216*e3f2c991SKeyur Desai {
217*e3f2c991SKeyur Desai 	int rc;
218*e3f2c991SKeyur Desai 	smb_setinfo_t sinfo;
219*e3f2c991SKeyur Desai 
220*e3f2c991SKeyur Desai 	if (SMB_TREE_IS_READONLY(sr)) {
221*e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
222*e3f2c991SKeyur Desai 		    ERRDOS, ERROR_ACCESS_DENIED);
223*e3f2c991SKeyur Desai 		return (-1);
224*e3f2c991SKeyur Desai 	}
225*e3f2c991SKeyur Desai 
226*e3f2c991SKeyur Desai 	if (!STYPE_ISDSK(sr->tid_tree->t_res_type))
227*e3f2c991SKeyur Desai 		return (0);
228*e3f2c991SKeyur Desai 
229*e3f2c991SKeyur Desai 	smbsr_lookup_file(sr);
230*e3f2c991SKeyur Desai 	if (sr->fid_ofile == NULL) {
231*e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
232*e3f2c991SKeyur Desai 		return (-1);
233*e3f2c991SKeyur Desai 	}
234*e3f2c991SKeyur Desai 
235*e3f2c991SKeyur Desai 	if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
236*e3f2c991SKeyur Desai 		smbsr_release_file(sr);
237*e3f2c991SKeyur Desai 		return (0);
238*e3f2c991SKeyur Desai 	}
239*e3f2c991SKeyur Desai 
240*e3f2c991SKeyur Desai 	sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
241*e3f2c991SKeyur Desai 
242*e3f2c991SKeyur Desai 	sinfo.si_xa = xa;
243*e3f2c991SKeyur Desai 	sinfo.si_infolev = infolev;
244*e3f2c991SKeyur Desai 	sinfo.si_node = sr->fid_ofile->f_node;
245*e3f2c991SKeyur Desai 	rc = smb_set_fileinfo(sr, &sinfo);
246*e3f2c991SKeyur Desai 
247*e3f2c991SKeyur Desai 	smbsr_release_file(sr);
248*e3f2c991SKeyur Desai 	return (rc);
249*e3f2c991SKeyur Desai }
250*e3f2c991SKeyur Desai 
251*e3f2c991SKeyur Desai /*
252*e3f2c991SKeyur Desai  * smb_set_by_path
253*e3f2c991SKeyur Desai  *
254*e3f2c991SKeyur Desai  * Common code for setting file information by file name.
255*e3f2c991SKeyur Desai  * Use the file name to identify the node object and invoke
256*e3f2c991SKeyur Desai  * smb_set_fileinfo for that node.
257*e3f2c991SKeyur Desai  *
258*e3f2c991SKeyur Desai  * Setting attributes on a named pipe by name is an error and
259*e3f2c991SKeyur Desai  * is handled in the calling functions so that they can return
260*e3f2c991SKeyur Desai  * the appropriate error status code (which differs by caller).
261*e3f2c991SKeyur Desai  */
262*e3f2c991SKeyur Desai static int
263*e3f2c991SKeyur Desai smb_set_by_path(smb_request_t *sr, smb_xa_t *xa,
264*e3f2c991SKeyur Desai     uint16_t infolev, char *path)
265*e3f2c991SKeyur Desai {
266*e3f2c991SKeyur Desai 	int rc;
267*e3f2c991SKeyur Desai 	smb_setinfo_t sinfo;
268*e3f2c991SKeyur Desai 	smb_node_t *node, *dnode;
269*e3f2c991SKeyur Desai 	char *name;
270*e3f2c991SKeyur Desai 
271*e3f2c991SKeyur Desai 	if (SMB_TREE_IS_READONLY(sr)) {
272*e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
273*e3f2c991SKeyur Desai 		    ERRDOS, ERROR_ACCESS_DENIED);
274*e3f2c991SKeyur Desai 		return (-1);
275*e3f2c991SKeyur Desai 	}
276*e3f2c991SKeyur Desai 
277*e3f2c991SKeyur Desai 	name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
278*e3f2c991SKeyur Desai 	rc = smb_pathname_reduce(sr, sr->user_cr, path,
279*e3f2c991SKeyur Desai 	    sr->tid_tree->t_snode, sr->tid_tree->t_snode, &dnode, name);
280*e3f2c991SKeyur Desai 	if (rc == 0) {
281*e3f2c991SKeyur Desai 		rc = smb_fsop_lookup_name(sr, sr->user_cr, SMB_FOLLOW_LINKS,
282*e3f2c991SKeyur Desai 		    sr->tid_tree->t_snode, dnode, name, &node);
283*e3f2c991SKeyur Desai 		smb_node_release(dnode);
284*e3f2c991SKeyur Desai 	}
285*e3f2c991SKeyur Desai 	kmem_free(name, MAXNAMELEN);
286*e3f2c991SKeyur Desai 
287*e3f2c991SKeyur Desai 	if (rc != 0) {
288*e3f2c991SKeyur Desai 		smbsr_errno(sr, rc);
289*e3f2c991SKeyur Desai 		return (-1);
290*e3f2c991SKeyur Desai 	}
291*e3f2c991SKeyur Desai 
292*e3f2c991SKeyur Desai 	/* Break any conflicting oplock for subsequent attribute setting */
293*e3f2c991SKeyur Desai 	if (smb_oplock_conflict(node, sr->session, NULL)) {
294*e3f2c991SKeyur Desai 		(void) smb_oplock_break(node, sr->session, B_FALSE);
295*e3f2c991SKeyur Desai 	}
296*e3f2c991SKeyur Desai 
297*e3f2c991SKeyur Desai 	sinfo.si_xa = xa;
298*e3f2c991SKeyur Desai 	sinfo.si_infolev = infolev;
299*e3f2c991SKeyur Desai 	sinfo.si_node = node;
300*e3f2c991SKeyur Desai 	rc = smb_set_fileinfo(sr, &sinfo);
301*e3f2c991SKeyur Desai 
302*e3f2c991SKeyur Desai 	smb_node_release(node);
303*e3f2c991SKeyur Desai 	return (rc);
304*e3f2c991SKeyur Desai }
305*e3f2c991SKeyur Desai 
306*e3f2c991SKeyur Desai /*
307*e3f2c991SKeyur Desai  * smb_set_fileinfo
308*e3f2c991SKeyur Desai  */
309*e3f2c991SKeyur Desai static int
310*e3f2c991SKeyur Desai smb_set_fileinfo(smb_request_t *sr, smb_setinfo_t *sinfo)
311*e3f2c991SKeyur Desai {
312*e3f2c991SKeyur Desai 	switch (sinfo->si_infolev) {
313*e3f2c991SKeyur Desai 	case SMB_SET_INFORMATION:
314*e3f2c991SKeyur Desai 		return (smb_set_information(sr, sinfo));
315*e3f2c991SKeyur Desai 
316*e3f2c991SKeyur Desai 	case SMB_SET_INFORMATION2:
317*e3f2c991SKeyur Desai 		return (smb_set_information2(sr, sinfo));
318*e3f2c991SKeyur Desai 
319*e3f2c991SKeyur Desai 	case SMB_INFO_STANDARD:
320*e3f2c991SKeyur Desai 		return (smb_set_standard_info(sr, sinfo));
321*e3f2c991SKeyur Desai 
322*e3f2c991SKeyur Desai 	case SMB_INFO_SET_EAS:
323*e3f2c991SKeyur Desai 		/* EAs not supported */
324*e3f2c991SKeyur Desai 		return (0);
325*e3f2c991SKeyur Desai 
326*e3f2c991SKeyur Desai 	case SMB_SET_FILE_BASIC_INFO:
327*e3f2c991SKeyur Desai 	case SMB_FILE_BASIC_INFORMATION:
328*e3f2c991SKeyur Desai 		return (smb_set_basic_info(sr, sinfo));
329*e3f2c991SKeyur Desai 
330*e3f2c991SKeyur Desai 	case SMB_SET_FILE_DISPOSITION_INFO:
331*e3f2c991SKeyur Desai 	case SMB_FILE_DISPOSITION_INFORMATION:
332*e3f2c991SKeyur Desai 		return (smb_set_disposition_info(sr, sinfo));
333*e3f2c991SKeyur Desai 
334*e3f2c991SKeyur Desai 	case SMB_SET_FILE_END_OF_FILE_INFO:
335*e3f2c991SKeyur Desai 	case SMB_FILE_END_OF_FILE_INFORMATION:
336*e3f2c991SKeyur Desai 		return (smb_set_eof_info(sr, sinfo));
337*e3f2c991SKeyur Desai 
338*e3f2c991SKeyur Desai 	case SMB_SET_FILE_ALLOCATION_INFO:
339*e3f2c991SKeyur Desai 	case SMB_FILE_ALLOCATION_INFORMATION:
340*e3f2c991SKeyur Desai 		return (smb_set_alloc_info(sr, sinfo));
341*e3f2c991SKeyur Desai 
342*e3f2c991SKeyur Desai 	default:
343*e3f2c991SKeyur Desai 		break;
344*e3f2c991SKeyur Desai 	}
345*e3f2c991SKeyur Desai 
346*e3f2c991SKeyur Desai 	smbsr_error(sr, NT_STATUS_INVALID_INFO_CLASS,
347*e3f2c991SKeyur Desai 	    ERRDOS, ERROR_INVALID_PARAMETER);
348*e3f2c991SKeyur Desai 	return (-1);
349*e3f2c991SKeyur Desai }
350*e3f2c991SKeyur Desai 
351*e3f2c991SKeyur Desai /*
352*e3f2c991SKeyur Desai  * smb_set_information
353*e3f2c991SKeyur Desai  *
354*e3f2c991SKeyur Desai  * It is not valid to set FILE_ATTRIBUTE_DIRECTORY if the
355*e3f2c991SKeyur Desai  * target is not a directory.
356*e3f2c991SKeyur Desai  *
357*e3f2c991SKeyur Desai  * For compatibility with Windows Servers, if the specified
358*e3f2c991SKeyur Desai  * attributes have ONLY FILE_ATTRIBUTE_NORMAL set do NOT change
359*e3f2c991SKeyur Desai  * the file's attributes.
360*e3f2c991SKeyur Desai  */
361*e3f2c991SKeyur Desai static int
362*e3f2c991SKeyur Desai smb_set_information(smb_request_t *sr, smb_setinfo_t *sinfo)
363*e3f2c991SKeyur Desai {
364*e3f2c991SKeyur Desai 	int rc;
365*e3f2c991SKeyur Desai 	uint16_t attributes;
366*e3f2c991SKeyur Desai 	smb_node_t *node = sinfo->si_node;
367*e3f2c991SKeyur Desai 	smb_attr_t attr;
368*e3f2c991SKeyur Desai 	uint32_t mtime;
369*e3f2c991SKeyur Desai 
370*e3f2c991SKeyur Desai 	if (smbsr_decode_vwv(sr, "wl10.", &attributes, &mtime) != 0)
371*e3f2c991SKeyur Desai 		return (-1);
372*e3f2c991SKeyur Desai 
373*e3f2c991SKeyur Desai 	if ((attributes & FILE_ATTRIBUTE_DIRECTORY) &&
374*e3f2c991SKeyur Desai 	    (!smb_node_is_dir(node))) {
375*e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
376*e3f2c991SKeyur Desai 		    ERRDOS, ERROR_INVALID_PARAMETER);
377*e3f2c991SKeyur Desai 		return (-1);
378*e3f2c991SKeyur Desai 	}
379*e3f2c991SKeyur Desai 
380*e3f2c991SKeyur Desai 	bzero(&attr, sizeof (smb_attr_t));
381*e3f2c991SKeyur Desai 	if (attributes != FILE_ATTRIBUTE_NORMAL) {
382*e3f2c991SKeyur Desai 		attr.sa_dosattr = attributes;
383*e3f2c991SKeyur Desai 		attr.sa_mask |= SMB_AT_DOSATTR;
384*e3f2c991SKeyur Desai 	}
385*e3f2c991SKeyur Desai 
386*e3f2c991SKeyur Desai 	if (mtime != 0 && mtime != UINT_MAX) {
387*e3f2c991SKeyur Desai 		attr.sa_vattr.va_mtime.tv_sec =
388*e3f2c991SKeyur Desai 		    smb_time_local_to_gmt(sr, mtime);
389*e3f2c991SKeyur Desai 		attr.sa_mask |= SMB_AT_MTIME;
390*e3f2c991SKeyur Desai 	}
391*e3f2c991SKeyur Desai 
392*e3f2c991SKeyur Desai 	rc = smb_node_setattr(sr, node, sr->user_cr, NULL, &attr);
393*e3f2c991SKeyur Desai 	if (rc != 0) {
394*e3f2c991SKeyur Desai 		smbsr_errno(sr, rc);
395*e3f2c991SKeyur Desai 		return (-1);
396*e3f2c991SKeyur Desai 	}
397*e3f2c991SKeyur Desai 
398*e3f2c991SKeyur Desai 	return (0);
399*e3f2c991SKeyur Desai }
400*e3f2c991SKeyur Desai 
401*e3f2c991SKeyur Desai /*
402*e3f2c991SKeyur Desai  * smb_set_information2
403*e3f2c991SKeyur Desai  */
404*e3f2c991SKeyur Desai static int
405*e3f2c991SKeyur Desai smb_set_information2(smb_request_t *sr, smb_setinfo_t *sinfo)
406*e3f2c991SKeyur Desai {
407*e3f2c991SKeyur Desai 	int rc;
408*e3f2c991SKeyur Desai 	uint32_t crtime, atime, mtime;
409*e3f2c991SKeyur Desai 	smb_attr_t attr;
410*e3f2c991SKeyur Desai 
411*e3f2c991SKeyur Desai 	if (smbsr_decode_vwv(sr, "yyy", &crtime, &atime, &mtime) != 0)
412*e3f2c991SKeyur Desai 		return (-1);
413*e3f2c991SKeyur Desai 
414*e3f2c991SKeyur Desai 	bzero(&attr, sizeof (smb_attr_t));
415*e3f2c991SKeyur Desai 	if (mtime != 0 && mtime != UINT_MAX) {
416*e3f2c991SKeyur Desai 		attr.sa_vattr.va_mtime.tv_sec =
417*e3f2c991SKeyur Desai 		    smb_time_local_to_gmt(sr, mtime);
418*e3f2c991SKeyur Desai 		attr.sa_mask |= SMB_AT_MTIME;
419*e3f2c991SKeyur Desai 	}
420*e3f2c991SKeyur Desai 
421*e3f2c991SKeyur Desai 	if (crtime != 0 && crtime != UINT_MAX) {
422*e3f2c991SKeyur Desai 		attr.sa_crtime.tv_sec = smb_time_local_to_gmt(sr, crtime);
423*e3f2c991SKeyur Desai 		attr.sa_mask |= SMB_AT_CRTIME;
424*e3f2c991SKeyur Desai 	}
425*e3f2c991SKeyur Desai 
426*e3f2c991SKeyur Desai 	if (atime != 0 && atime != UINT_MAX) {
427*e3f2c991SKeyur Desai 		attr.sa_vattr.va_atime.tv_sec =
428*e3f2c991SKeyur Desai 		    smb_time_local_to_gmt(sr, atime);
429*e3f2c991SKeyur Desai 		attr.sa_mask |= SMB_AT_ATIME;
430*e3f2c991SKeyur Desai 	}
431*e3f2c991SKeyur Desai 
432*e3f2c991SKeyur Desai 	rc = smb_node_setattr(sr, sinfo->si_node, sr->user_cr,
433*e3f2c991SKeyur Desai 	    sr->fid_ofile, &attr);
434*e3f2c991SKeyur Desai 	if (rc != 0) {
435*e3f2c991SKeyur Desai 		smbsr_errno(sr, rc);
436*e3f2c991SKeyur Desai 		return (-1);
437*e3f2c991SKeyur Desai 	}
438*e3f2c991SKeyur Desai 
439*e3f2c991SKeyur Desai 	return (0);
440*e3f2c991SKeyur Desai }
441*e3f2c991SKeyur Desai 
442*e3f2c991SKeyur Desai /*
443*e3f2c991SKeyur Desai  * smb_set_standard_info
444*e3f2c991SKeyur Desai  *
445*e3f2c991SKeyur Desai  * Sets standard file/path information.
446*e3f2c991SKeyur Desai  */
447*e3f2c991SKeyur Desai static int
448*e3f2c991SKeyur Desai smb_set_standard_info(smb_request_t *sr, smb_setinfo_t *sinfo)
449*e3f2c991SKeyur Desai {
450*e3f2c991SKeyur Desai 	smb_attr_t attr;
451*e3f2c991SKeyur Desai 	uint32_t crtime, atime, mtime;
452*e3f2c991SKeyur Desai 	smb_node_t *node = sinfo->si_node;
453*e3f2c991SKeyur Desai 	int rc;
454*e3f2c991SKeyur Desai 
455*e3f2c991SKeyur Desai 	if (smb_mbc_decodef(&sinfo->si_xa->req_data_mb, "yyy",
456*e3f2c991SKeyur Desai 	    &crtime, &atime, &mtime) != 0) {
457*e3f2c991SKeyur Desai 		return (-1);
458*e3f2c991SKeyur Desai 	}
459*e3f2c991SKeyur Desai 
460*e3f2c991SKeyur Desai 	bzero(&attr, sizeof (smb_attr_t));
461*e3f2c991SKeyur Desai 	if (mtime != 0 && mtime != (uint32_t)-1) {
462*e3f2c991SKeyur Desai 		attr.sa_vattr.va_mtime.tv_sec =
463*e3f2c991SKeyur Desai 		    smb_time_local_to_gmt(sr, mtime);
464*e3f2c991SKeyur Desai 		attr.sa_mask |= SMB_AT_MTIME;
465*e3f2c991SKeyur Desai 	}
466*e3f2c991SKeyur Desai 
467*e3f2c991SKeyur Desai 	if (crtime != 0 && crtime != (uint32_t)-1) {
468*e3f2c991SKeyur Desai 		attr.sa_crtime.tv_sec = smb_time_local_to_gmt(sr, crtime);
469*e3f2c991SKeyur Desai 		attr.sa_mask |= SMB_AT_CRTIME;
470*e3f2c991SKeyur Desai 	}
471*e3f2c991SKeyur Desai 
472*e3f2c991SKeyur Desai 	if (atime != 0 && atime != (uint32_t)-1) {
473*e3f2c991SKeyur Desai 		attr.sa_vattr.va_atime.tv_sec =
474*e3f2c991SKeyur Desai 		    smb_time_local_to_gmt(sr, atime);
475*e3f2c991SKeyur Desai 		attr.sa_mask |= SMB_AT_ATIME;
476*e3f2c991SKeyur Desai 	}
477*e3f2c991SKeyur Desai 
478*e3f2c991SKeyur Desai 	rc = smb_node_setattr(sr, node, sr->user_cr, sr->fid_ofile, &attr);
479*e3f2c991SKeyur Desai 	if (rc != 0) {
480*e3f2c991SKeyur Desai 		smbsr_errno(sr, rc);
481*e3f2c991SKeyur Desai 		return (-1);
482*e3f2c991SKeyur Desai 	}
483*e3f2c991SKeyur Desai 
484*e3f2c991SKeyur Desai 	return (0);
485*e3f2c991SKeyur Desai }
486*e3f2c991SKeyur Desai 
487*e3f2c991SKeyur Desai /*
488*e3f2c991SKeyur Desai  * smb_set_basic_info
489*e3f2c991SKeyur Desai  *
490*e3f2c991SKeyur Desai  * Sets basic file/path information.
491*e3f2c991SKeyur Desai  *
492*e3f2c991SKeyur Desai  * It is not valid to set FILE_ATTRIBUTE_DIRECTORY if the
493*e3f2c991SKeyur Desai  * target is not a directory.
494*e3f2c991SKeyur Desai  *
495*e3f2c991SKeyur Desai  * For compatibility with windows servers:
496*e3f2c991SKeyur Desai  * - if the specified attributes have ONLY FILE_ATTRIBUTE_NORMAL set
497*e3f2c991SKeyur Desai  *   clear (0) the file's attributes.
498*e3f2c991SKeyur Desai  * - if the specified attributes are 0 do NOT change the file's attributes.
499*e3f2c991SKeyur Desai  */
500*e3f2c991SKeyur Desai static int
501*e3f2c991SKeyur Desai smb_set_basic_info(smb_request_t *sr, smb_setinfo_t *sinfo)
502*e3f2c991SKeyur Desai {
503*e3f2c991SKeyur Desai 	int rc;
504*e3f2c991SKeyur Desai 	uint64_t crtime, atime, mtime, ctime;
505*e3f2c991SKeyur Desai 	uint16_t attributes;
506*e3f2c991SKeyur Desai 	smb_attr_t attr;
507*e3f2c991SKeyur Desai 	smb_node_t *node = sinfo->si_node;
508*e3f2c991SKeyur Desai 
509*e3f2c991SKeyur Desai 	if (smb_mbc_decodef(&sinfo->si_xa->req_data_mb, "qqqqw",
510*e3f2c991SKeyur Desai 	    &crtime, &atime, &mtime, &ctime, &attributes) != 0) {
511*e3f2c991SKeyur Desai 		return (-1);
512*e3f2c991SKeyur Desai 	}
513*e3f2c991SKeyur Desai 
514*e3f2c991SKeyur Desai 	if ((attributes & FILE_ATTRIBUTE_DIRECTORY) &&
515*e3f2c991SKeyur Desai 	    (!smb_node_is_dir(node))) {
516*e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
517*e3f2c991SKeyur Desai 		    ERRDOS, ERROR_INVALID_PARAMETER);
518*e3f2c991SKeyur Desai 		return (-1);
519*e3f2c991SKeyur Desai 	}
520*e3f2c991SKeyur Desai 
521*e3f2c991SKeyur Desai 	bzero(&attr, sizeof (smb_attr_t));
522*e3f2c991SKeyur Desai 	if (ctime != 0 && ctime != (uint64_t)-1) {
523*e3f2c991SKeyur Desai 		smb_time_nt_to_unix(ctime, &attr.sa_vattr.va_ctime);
524*e3f2c991SKeyur Desai 		attr.sa_mask |= SMB_AT_CTIME;
525*e3f2c991SKeyur Desai 	}
526*e3f2c991SKeyur Desai 
527*e3f2c991SKeyur Desai 	if (crtime != 0 && crtime != (uint64_t)-1) {
528*e3f2c991SKeyur Desai 		smb_time_nt_to_unix(crtime, &attr.sa_crtime);
529*e3f2c991SKeyur Desai 		attr.sa_mask |= SMB_AT_CRTIME;
530*e3f2c991SKeyur Desai 	}
531*e3f2c991SKeyur Desai 
532*e3f2c991SKeyur Desai 	if (mtime != 0 && mtime != (uint64_t)-1) {
533*e3f2c991SKeyur Desai 		smb_time_nt_to_unix(mtime, &attr.sa_vattr.va_mtime);
534*e3f2c991SKeyur Desai 		attr.sa_mask |= SMB_AT_MTIME;
535*e3f2c991SKeyur Desai 	}
536*e3f2c991SKeyur Desai 
537*e3f2c991SKeyur Desai 	if (atime != 0 && atime != (uint64_t)-1) {
538*e3f2c991SKeyur Desai 		smb_time_nt_to_unix(atime, &attr.sa_vattr.va_atime);
539*e3f2c991SKeyur Desai 		attr.sa_mask |= SMB_AT_ATIME;
540*e3f2c991SKeyur Desai 	}
541*e3f2c991SKeyur Desai 
542*e3f2c991SKeyur Desai 	if (attributes != 0) {
543*e3f2c991SKeyur Desai 		attr.sa_dosattr = attributes;
544*e3f2c991SKeyur Desai 		attr.sa_mask |= SMB_AT_DOSATTR;
545*e3f2c991SKeyur Desai 	}
546*e3f2c991SKeyur Desai 
547*e3f2c991SKeyur Desai 	rc = smb_node_setattr(sr, node, sr->user_cr, sr->fid_ofile, &attr);
548*e3f2c991SKeyur Desai 	if (rc != 0) {
549*e3f2c991SKeyur Desai 		smbsr_errno(sr, rc);
550*e3f2c991SKeyur Desai 		return (-1);
551*e3f2c991SKeyur Desai 	}
552*e3f2c991SKeyur Desai 
553*e3f2c991SKeyur Desai 	return (0);
554*e3f2c991SKeyur Desai }
555*e3f2c991SKeyur Desai 
556*e3f2c991SKeyur Desai /*
557*e3f2c991SKeyur Desai  * smb_set_eof_info
558*e3f2c991SKeyur Desai  */
559*e3f2c991SKeyur Desai static int
560*e3f2c991SKeyur Desai smb_set_eof_info(smb_request_t *sr, smb_setinfo_t *sinfo)
561*e3f2c991SKeyur Desai {
562*e3f2c991SKeyur Desai 	int rc;
563*e3f2c991SKeyur Desai 	smb_attr_t attr;
564*e3f2c991SKeyur Desai 	uint64_t eof;
565*e3f2c991SKeyur Desai 	smb_node_t *node = sinfo->si_node;
566*e3f2c991SKeyur Desai 
567*e3f2c991SKeyur Desai 	if (smb_mbc_decodef(&sinfo->si_xa->req_data_mb, "q", &eof) != 0)
568*e3f2c991SKeyur Desai 		return (-1);
569*e3f2c991SKeyur Desai 
570*e3f2c991SKeyur Desai 	if (smb_node_is_dir(node)) {
571*e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
572*e3f2c991SKeyur Desai 		    ERRDOS, ERROR_INVALID_PARAMETER);
573*e3f2c991SKeyur Desai 		return (-1);
574*e3f2c991SKeyur Desai 	}
575*e3f2c991SKeyur Desai 
576*e3f2c991SKeyur Desai 	bzero(&attr, sizeof (smb_attr_t));
577*e3f2c991SKeyur Desai 	attr.sa_mask = SMB_AT_SIZE;
578*e3f2c991SKeyur Desai 	attr.sa_vattr.va_size = (u_offset_t)eof;
579*e3f2c991SKeyur Desai 	rc = smb_node_setattr(sr, node, sr->user_cr, sr->fid_ofile, &attr);
580*e3f2c991SKeyur Desai 	if (rc != 0) {
581*e3f2c991SKeyur Desai 		smbsr_errno(sr, rc);
582*e3f2c991SKeyur Desai 		return (-1);
583*e3f2c991SKeyur Desai 	}
584*e3f2c991SKeyur Desai 
585*e3f2c991SKeyur Desai 	return (0);
586*e3f2c991SKeyur Desai }
587*e3f2c991SKeyur Desai 
588*e3f2c991SKeyur Desai /*
589*e3f2c991SKeyur Desai  * smb_set_alloc_info
590*e3f2c991SKeyur Desai  */
591*e3f2c991SKeyur Desai static int
592*e3f2c991SKeyur Desai smb_set_alloc_info(smb_request_t *sr, smb_setinfo_t *sinfo)
593*e3f2c991SKeyur Desai {
594*e3f2c991SKeyur Desai 	int rc;
595*e3f2c991SKeyur Desai 	smb_attr_t attr;
596*e3f2c991SKeyur Desai 	uint64_t allocsz;
597*e3f2c991SKeyur Desai 	smb_node_t *node = sinfo->si_node;
598*e3f2c991SKeyur Desai 
599*e3f2c991SKeyur Desai 	if (smb_mbc_decodef(&sinfo->si_xa->req_data_mb, "q", &allocsz) != 0)
600*e3f2c991SKeyur Desai 		return (-1);
601*e3f2c991SKeyur Desai 
602*e3f2c991SKeyur Desai 	if (smb_node_is_dir(node)) {
603*e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
604*e3f2c991SKeyur Desai 		    ERRDOS, ERROR_INVALID_PARAMETER);
605*e3f2c991SKeyur Desai 		return (-1);
606*e3f2c991SKeyur Desai 	}
607*e3f2c991SKeyur Desai 
608*e3f2c991SKeyur Desai 	bzero(&attr, sizeof (smb_attr_t));
609*e3f2c991SKeyur Desai 	attr.sa_mask = SMB_AT_ALLOCSZ;
610*e3f2c991SKeyur Desai 	attr.sa_allocsz = (u_offset_t)allocsz;
611*e3f2c991SKeyur Desai 	rc = smb_node_setattr(sr, node, sr->user_cr, sr->fid_ofile, &attr);
612*e3f2c991SKeyur Desai 	if (rc != 0) {
613*e3f2c991SKeyur Desai 		smbsr_errno(sr, rc);
614*e3f2c991SKeyur Desai 		return (-1);
615*e3f2c991SKeyur Desai 	}
616*e3f2c991SKeyur Desai 
617*e3f2c991SKeyur Desai 	return (0);
618*e3f2c991SKeyur Desai }
619*e3f2c991SKeyur Desai 
620*e3f2c991SKeyur Desai /*
621*e3f2c991SKeyur Desai  * smb_set_disposition_info
622*e3f2c991SKeyur Desai  *
623*e3f2c991SKeyur Desai  * Set/Clear DELETE_ON_CLOSE flag for an open file.
624*e3f2c991SKeyur Desai  * File should have been opened with DELETE access otherwise
625*e3f2c991SKeyur Desai  * the operation is not permitted.
626*e3f2c991SKeyur Desai  *
627*e3f2c991SKeyur Desai  * NOTE: The node should be marked delete-on-close upon the receipt
628*e3f2c991SKeyur Desai  * of the Trans2SetFileInfo(SetDispositionInfo) if mark_delete is set.
629*e3f2c991SKeyur Desai  * It is different than both SmbNtCreateAndX and SmbNtTransact, which
630*e3f2c991SKeyur Desai  * set delete-on-close on the ofile and defer setting the flag on the
631*e3f2c991SKeyur Desai  * node until the file is closed.
632*e3f2c991SKeyur Desai  *
633*e3f2c991SKeyur Desai  * Observation of Windows 2000 indicates the following:
634*e3f2c991SKeyur Desai  *
635*e3f2c991SKeyur Desai  * 1) If a file is not opened with delete-on-close create options and
636*e3f2c991SKeyur Desai  * the delete-on-close is set via Trans2SetFileInfo(SetDispositionInfo)
637*e3f2c991SKeyur Desai  * using that open file handle, any subsequent open requests will fail
638*e3f2c991SKeyur Desai  * with DELETE_PENDING.
639*e3f2c991SKeyur Desai  *
640*e3f2c991SKeyur Desai  * 2) If a file is opened with delete-on-close create options and the
641*e3f2c991SKeyur Desai  * client attempts to unset delete-on-close via Trans2SetFileInfo
642*e3f2c991SKeyur Desai  * (SetDispositionInfo) prior to the file close, any subsequent open
643*e3f2c991SKeyur Desai  * requests will still fail with DELETE_PENDING after the file is closed.
644*e3f2c991SKeyur Desai  *
645*e3f2c991SKeyur Desai  * 3) If a file is opened with delete-on-close create options and that
646*e3f2c991SKeyur Desai  * file handle (not the last open handle and the only file handle
647*e3f2c991SKeyur Desai  * with delete-on-close set) is closed. Any subsequent open requests
648*e3f2c991SKeyur Desai  * will fail with DELETE_PENDING. Unsetting delete-on-close via
649*e3f2c991SKeyur Desai  * Trans2SetFileInfo(SetDispositionInfo) at this time will unset the
650*e3f2c991SKeyur Desai  * node delete-on-close flag, which will result in the file not being
651*e3f2c991SKeyur Desai  * removed even after the last file handle is closed.
652*e3f2c991SKeyur Desai  */
653*e3f2c991SKeyur Desai static int
654*e3f2c991SKeyur Desai smb_set_disposition_info(smb_request_t *sr, smb_setinfo_t *sinfo)
655*e3f2c991SKeyur Desai {
656*e3f2c991SKeyur Desai 	unsigned char	mark_delete;
657*e3f2c991SKeyur Desai 	uint32_t	flags = 0;
658*e3f2c991SKeyur Desai 
659*e3f2c991SKeyur Desai 	if (smb_mbc_decodef(&sinfo->si_xa->req_data_mb, "b", &mark_delete) != 0)
660*e3f2c991SKeyur Desai 		return (-1);
661*e3f2c991SKeyur Desai 
662*e3f2c991SKeyur Desai 	if ((sr->fid_ofile == NULL) ||
663*e3f2c991SKeyur Desai 	    !(smb_ofile_granted_access(sr->fid_ofile) & DELETE)) {
664*e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
665*e3f2c991SKeyur Desai 		    ERRDOS, ERROR_ACCESS_DENIED);
666*e3f2c991SKeyur Desai 		return (-1);
667*e3f2c991SKeyur Desai 	}
668*e3f2c991SKeyur Desai 
669*e3f2c991SKeyur Desai 	if (mark_delete) {
670*e3f2c991SKeyur Desai 		if (SMB_TREE_SUPPORTS_CATIA(sr))
671*e3f2c991SKeyur Desai 			flags |= SMB_CATIA;
672*e3f2c991SKeyur Desai 
673*e3f2c991SKeyur Desai 		if (smb_node_set_delete_on_close(sinfo->si_node,
674*e3f2c991SKeyur Desai 		    sr->user_cr, flags)) {
675*e3f2c991SKeyur Desai 			smbsr_error(sr, NT_STATUS_CANNOT_DELETE,
676*e3f2c991SKeyur Desai 			    ERRDOS, ERROR_ACCESS_DENIED);
677*e3f2c991SKeyur Desai 			return (-1);
678*e3f2c991SKeyur Desai 		}
679*e3f2c991SKeyur Desai 	} else {
680*e3f2c991SKeyur Desai 		smb_node_reset_delete_on_close(sinfo->si_node);
681*e3f2c991SKeyur Desai 	}
682*e3f2c991SKeyur Desai 	return (0);
683*e3f2c991SKeyur Desai }
684