1e3f2c991SKeyur Desai /*
2e3f2c991SKeyur Desai * CDDL HEADER START
3e3f2c991SKeyur Desai *
4e3f2c991SKeyur Desai * The contents of this file are subject to the terms of the
5e3f2c991SKeyur Desai * Common Development and Distribution License (the "License").
6e3f2c991SKeyur Desai * You may not use this file except in compliance with the License.
7e3f2c991SKeyur Desai *
8e3f2c991SKeyur Desai * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e3f2c991SKeyur Desai * or http://www.opensolaris.org/os/licensing.
10e3f2c991SKeyur Desai * See the License for the specific language governing permissions
11e3f2c991SKeyur Desai * and limitations under the License.
12e3f2c991SKeyur Desai *
13e3f2c991SKeyur Desai * When distributing Covered Code, include this CDDL HEADER in each
14e3f2c991SKeyur Desai * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15e3f2c991SKeyur Desai * If applicable, add the following below this CDDL HEADER, with the
16e3f2c991SKeyur Desai * fields enclosed by brackets "[]" replaced with your own identifying
17e3f2c991SKeyur Desai * information: Portions Copyright [yyyy] [name of copyright owner]
18e3f2c991SKeyur Desai *
19e3f2c991SKeyur Desai * CDDL HEADER END
20e3f2c991SKeyur Desai */
21e3f2c991SKeyur Desai /*
22cb174861Sjoyce mcintosh * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23*2dbda4a2SGordon Ross * Copyright 2019 Nexenta by DDN, Inc. All rights reserved.
24e3f2c991SKeyur Desai */
25e3f2c991SKeyur Desai
26e3f2c991SKeyur Desai /*
27e3f2c991SKeyur Desai * Trans2 Set File/Path Information Levels:
28e3f2c991SKeyur Desai *
29e3f2c991SKeyur Desai * SMB_INFO_STANDARD
30e3f2c991SKeyur Desai * SMB_INFO_SET_EAS
31e3f2c991SKeyur Desai * SMB_SET_FILE_BASIC_INFO
32e3f2c991SKeyur Desai * SMB_SET_FILE_DISPOSITION_INFO
33e3f2c991SKeyur Desai * SMB_SET_FILE_END_OF_FILE_INFO
34e3f2c991SKeyur Desai * SMB_SET_FILE_ALLOCATION_INFO
35e3f2c991SKeyur Desai *
36bbf6f00cSJordan Brown * Handled Passthrough levels:
37e3f2c991SKeyur Desai * SMB_FILE_BASIC_INFORMATION
38bbf6f00cSJordan Brown * SMB_FILE_RENAME_INFORMATION
39bbf6f00cSJordan Brown * SMB_FILE_LINK_INFORMATION
40e3f2c991SKeyur Desai * SMB_FILE_DISPOSITION_INFORMATION
41e3f2c991SKeyur Desai * SMB_FILE_END_OF_FILE_INFORMATION
42e3f2c991SKeyur Desai * SMB_FILE_ALLOCATION_INFORMATION
43e3f2c991SKeyur Desai *
44e3f2c991SKeyur Desai * Internal levels representing non trans2 requests
45e3f2c991SKeyur Desai * SMB_SET_INFORMATION
46e3f2c991SKeyur Desai * SMB_SET_INFORMATION2
47e3f2c991SKeyur Desai */
48e3f2c991SKeyur Desai
49e3f2c991SKeyur Desai /*
50e3f2c991SKeyur Desai * Setting timestamps:
51e3f2c991SKeyur Desai * The behaviour when the time field is set to -1 is not documented
52e3f2c991SKeyur Desai * but is generally treated like 0, meaning that that server file
53e3f2c991SKeyur Desai * system assigned value need not be changed.
54e3f2c991SKeyur Desai *
55e3f2c991SKeyur Desai * Setting attributes - FILE_ATTRIBUTE_NORMAL:
56e3f2c991SKeyur Desai * SMB_SET_INFORMATION -
57e3f2c991SKeyur Desai * - if the specified attributes have ONLY FILE_ATTRIBUTE_NORMAL set
58e3f2c991SKeyur Desai * do NOT change the file's attributes.
59e3f2c991SKeyur Desai * SMB_SET_BASIC_INFO -
60e3f2c991SKeyur Desai * - if the specified attributes have ONLY FILE_ATTRIBUTE_NORMAL set
61e3f2c991SKeyur Desai * clear (0) the file's attributes.
62e3f2c991SKeyur Desai * - if the specified attributes are 0 do NOT change the file's
63e3f2c991SKeyur Desai * attributes.
64e3f2c991SKeyur Desai */
65e3f2c991SKeyur Desai
66bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h>
67e3f2c991SKeyur Desai #include <smbsrv/smb_fsops.h>
68e3f2c991SKeyur Desai
69e3f2c991SKeyur Desai static int smb_set_by_fid(smb_request_t *, smb_xa_t *, uint16_t);
709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int smb_set_by_path(smb_request_t *, smb_xa_t *, uint16_t);
71a90cf9f2SGordon Ross
72a90cf9f2SGordon Ross /*
73a90cf9f2SGordon Ross * These functions all return and NT status code.
74a90cf9f2SGordon Ross */
75a90cf9f2SGordon Ross static uint32_t smb_set_fileinfo(smb_request_t *, smb_setinfo_t *, int);
76a90cf9f2SGordon Ross static uint32_t smb_set_information(smb_request_t *, smb_setinfo_t *);
77a90cf9f2SGordon Ross static uint32_t smb_set_information2(smb_request_t *, smb_setinfo_t *);
78a90cf9f2SGordon Ross static uint32_t smb_set_standard_info(smb_request_t *, smb_setinfo_t *);
79a90cf9f2SGordon Ross static uint32_t smb_set_rename_info(smb_request_t *sr, smb_setinfo_t *);
80e3f2c991SKeyur Desai
81e3f2c991SKeyur Desai /*
82e3f2c991SKeyur Desai * smb_com_trans2_set_file_information
83e3f2c991SKeyur Desai */
84e3f2c991SKeyur Desai smb_sdrc_t
smb_com_trans2_set_file_information(smb_request_t * sr,smb_xa_t * xa)85e3f2c991SKeyur Desai smb_com_trans2_set_file_information(smb_request_t *sr, smb_xa_t *xa)
86e3f2c991SKeyur Desai {
87e3f2c991SKeyur Desai uint16_t infolev;
88e3f2c991SKeyur Desai
89e3f2c991SKeyur Desai if (smb_mbc_decodef(&xa->req_param_mb, "ww",
90e3f2c991SKeyur Desai &sr->smb_fid, &infolev) != 0)
91e3f2c991SKeyur Desai return (SDRC_ERROR);
92e3f2c991SKeyur Desai
93e3f2c991SKeyur Desai if (smb_set_by_fid(sr, xa, infolev) != 0)
94e3f2c991SKeyur Desai return (SDRC_ERROR);
95e3f2c991SKeyur Desai
96e3f2c991SKeyur Desai return (SDRC_SUCCESS);
97e3f2c991SKeyur Desai }
98e3f2c991SKeyur Desai
99e3f2c991SKeyur Desai /*
100e3f2c991SKeyur Desai * smb_com_trans2_set_path_information
101e3f2c991SKeyur Desai */
102e3f2c991SKeyur Desai smb_sdrc_t
smb_com_trans2_set_path_information(smb_request_t * sr,smb_xa_t * xa)103e3f2c991SKeyur Desai smb_com_trans2_set_path_information(smb_request_t *sr, smb_xa_t *xa)
104e3f2c991SKeyur Desai {
105e3f2c991SKeyur Desai uint16_t infolev;
1069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_fqi_t *fqi = &sr->arg.dirop.fqi;
107e3f2c991SKeyur Desai
108f96bd5c8SAlan Wright if (STYPE_ISIPC(sr->tid_tree->t_res_type)) {
109e3f2c991SKeyur Desai smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
110e3f2c991SKeyur Desai ERRDOS, ERROR_INVALID_FUNCTION);
111e3f2c991SKeyur Desai return (SDRC_ERROR);
112e3f2c991SKeyur Desai }
113e3f2c991SKeyur Desai
114e3f2c991SKeyur Desai if (smb_mbc_decodef(&xa->req_param_mb, "%w4.u",
1159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States sr, &infolev, &fqi->fq_path.pn_path) != 0)
116e3f2c991SKeyur Desai return (SDRC_ERROR);
117e3f2c991SKeyur Desai
1189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (smb_set_by_path(sr, xa, infolev) != 0)
119e3f2c991SKeyur Desai return (SDRC_ERROR);
120e3f2c991SKeyur Desai
121e3f2c991SKeyur Desai return (SDRC_SUCCESS);
122e3f2c991SKeyur Desai }
123e3f2c991SKeyur Desai
124e3f2c991SKeyur Desai /*
125e3f2c991SKeyur Desai * smb_com_set_information (aka setattr)
126e3f2c991SKeyur Desai */
127e3f2c991SKeyur Desai smb_sdrc_t
smb_pre_set_information(smb_request_t * sr)128e3f2c991SKeyur Desai smb_pre_set_information(smb_request_t *sr)
129e3f2c991SKeyur Desai {
13093bc28dbSGordon Ross DTRACE_SMB_START(op__SetInformation, smb_request_t *, sr);
131e3f2c991SKeyur Desai return (SDRC_SUCCESS);
132e3f2c991SKeyur Desai }
133e3f2c991SKeyur Desai
134e3f2c991SKeyur Desai void
smb_post_set_information(smb_request_t * sr)135e3f2c991SKeyur Desai smb_post_set_information(smb_request_t *sr)
136e3f2c991SKeyur Desai {
13793bc28dbSGordon Ross DTRACE_SMB_DONE(op__SetInformation, smb_request_t *, sr);
138e3f2c991SKeyur Desai }
139e3f2c991SKeyur Desai
140e3f2c991SKeyur Desai smb_sdrc_t
smb_com_set_information(smb_request_t * sr)141e3f2c991SKeyur Desai smb_com_set_information(smb_request_t *sr)
142e3f2c991SKeyur Desai {
143e3f2c991SKeyur Desai uint16_t infolev = SMB_SET_INFORMATION;
1449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_fqi_t *fqi = &sr->arg.dirop.fqi;
145e3f2c991SKeyur Desai
146f96bd5c8SAlan Wright if (STYPE_ISIPC(sr->tid_tree->t_res_type)) {
147e3f2c991SKeyur Desai smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
148e3f2c991SKeyur Desai ERRDOS, ERROR_ACCESS_DENIED);
149e3f2c991SKeyur Desai return (SDRC_ERROR);
150e3f2c991SKeyur Desai }
151e3f2c991SKeyur Desai
1529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (smbsr_decode_data(sr, "%S", sr, &fqi->fq_path.pn_path) != 0)
153e3f2c991SKeyur Desai return (SDRC_ERROR);
154e3f2c991SKeyur Desai
1559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (smb_set_by_path(sr, NULL, infolev) != 0)
156e3f2c991SKeyur Desai return (SDRC_ERROR);
157e3f2c991SKeyur Desai
158e3f2c991SKeyur Desai if (smbsr_encode_empty_result(sr) != 0)
159e3f2c991SKeyur Desai return (SDRC_ERROR);
160e3f2c991SKeyur Desai
161e3f2c991SKeyur Desai return (SDRC_SUCCESS);
162e3f2c991SKeyur Desai }
163e3f2c991SKeyur Desai
164e3f2c991SKeyur Desai /*
165e3f2c991SKeyur Desai * smb_com_set_information2 (aka setattre)
166e3f2c991SKeyur Desai */
167e3f2c991SKeyur Desai smb_sdrc_t
smb_pre_set_information2(smb_request_t * sr)168e3f2c991SKeyur Desai smb_pre_set_information2(smb_request_t *sr)
169e3f2c991SKeyur Desai {
17093bc28dbSGordon Ross DTRACE_SMB_START(op__SetInformation2, smb_request_t *, sr);
171e3f2c991SKeyur Desai return (SDRC_SUCCESS);
172e3f2c991SKeyur Desai }
173e3f2c991SKeyur Desai
174e3f2c991SKeyur Desai void
smb_post_set_information2(smb_request_t * sr)175e3f2c991SKeyur Desai smb_post_set_information2(smb_request_t *sr)
176e3f2c991SKeyur Desai {
17793bc28dbSGordon Ross DTRACE_SMB_DONE(op__SetInformation2, smb_request_t *, sr);
178e3f2c991SKeyur Desai }
179e3f2c991SKeyur Desai
180e3f2c991SKeyur Desai smb_sdrc_t
smb_com_set_information2(smb_request_t * sr)181e3f2c991SKeyur Desai smb_com_set_information2(smb_request_t *sr)
182e3f2c991SKeyur Desai {
183e3f2c991SKeyur Desai uint16_t infolev = SMB_SET_INFORMATION2;
184e3f2c991SKeyur Desai
185e3f2c991SKeyur Desai if (smbsr_decode_vwv(sr, "w", &sr->smb_fid) != 0)
186e3f2c991SKeyur Desai return (SDRC_ERROR);
187e3f2c991SKeyur Desai
188e3f2c991SKeyur Desai if (smb_set_by_fid(sr, NULL, infolev) != 0)
189e3f2c991SKeyur Desai return (SDRC_ERROR);
190e3f2c991SKeyur Desai
191e3f2c991SKeyur Desai if (smbsr_encode_empty_result(sr) != 0)
192e3f2c991SKeyur Desai return (SDRC_ERROR);
193e3f2c991SKeyur Desai
194e3f2c991SKeyur Desai return (SDRC_SUCCESS);
195e3f2c991SKeyur Desai }
196e3f2c991SKeyur Desai
197e3f2c991SKeyur Desai /*
198e3f2c991SKeyur Desai * smb_set_by_fid
199e3f2c991SKeyur Desai *
200e3f2c991SKeyur Desai * Common code for setting file information by open file id.
201e3f2c991SKeyur Desai * Use the id to identify the node object and invoke smb_set_fileinfo
202e3f2c991SKeyur Desai * for that node.
203e3f2c991SKeyur Desai *
204e3f2c991SKeyur Desai * Setting attributes on a named pipe by id is handled by simply
205e3f2c991SKeyur Desai * returning success.
206e3f2c991SKeyur Desai */
207e3f2c991SKeyur Desai static int
smb_set_by_fid(smb_request_t * sr,smb_xa_t * xa,uint16_t infolev)208e3f2c991SKeyur Desai smb_set_by_fid(smb_request_t *sr, smb_xa_t *xa, uint16_t infolev)
209e3f2c991SKeyur Desai {
210e3f2c991SKeyur Desai smb_setinfo_t sinfo;
211a90cf9f2SGordon Ross uint32_t status;
212a90cf9f2SGordon Ross int rc = 0;
213e3f2c991SKeyur Desai
214e3f2c991SKeyur Desai if (SMB_TREE_IS_READONLY(sr)) {
215e3f2c991SKeyur Desai smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
216e3f2c991SKeyur Desai ERRDOS, ERROR_ACCESS_DENIED);
217e3f2c991SKeyur Desai return (-1);
218e3f2c991SKeyur Desai }
219e3f2c991SKeyur Desai
220f96bd5c8SAlan Wright if (STYPE_ISIPC(sr->tid_tree->t_res_type))
221e3f2c991SKeyur Desai return (0);
222e3f2c991SKeyur Desai
223e3f2c991SKeyur Desai smbsr_lookup_file(sr);
224e3f2c991SKeyur Desai if (sr->fid_ofile == NULL) {
225e3f2c991SKeyur Desai smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
226e3f2c991SKeyur Desai return (-1);
227e3f2c991SKeyur Desai }
228e3f2c991SKeyur Desai
229e3f2c991SKeyur Desai if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
230e3f2c991SKeyur Desai smbsr_release_file(sr);
231e3f2c991SKeyur Desai return (0);
232e3f2c991SKeyur Desai }
233e3f2c991SKeyur Desai
234e3f2c991SKeyur Desai sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
235e3f2c991SKeyur Desai
236a90cf9f2SGordon Ross bzero(&sinfo, sizeof (sinfo));
237e3f2c991SKeyur Desai sinfo.si_node = sr->fid_ofile->f_node;
238a90cf9f2SGordon Ross if (xa != NULL)
239a90cf9f2SGordon Ross sinfo.si_data = xa->req_data_mb;
240a90cf9f2SGordon Ross status = smb_set_fileinfo(sr, &sinfo, infolev);
241a90cf9f2SGordon Ross if (status != 0) {
242a90cf9f2SGordon Ross smbsr_error(sr, status, 0, 0);
243a90cf9f2SGordon Ross rc = -1;
244a90cf9f2SGordon Ross }
245e3f2c991SKeyur Desai
246e3f2c991SKeyur Desai smbsr_release_file(sr);
247e3f2c991SKeyur Desai return (rc);
248e3f2c991SKeyur Desai }
249e3f2c991SKeyur Desai
250e3f2c991SKeyur Desai /*
251e3f2c991SKeyur Desai * smb_set_by_path
252e3f2c991SKeyur Desai *
253e3f2c991SKeyur Desai * Common code for setting file information by file name.
254e3f2c991SKeyur Desai * Use the file name to identify the node object and invoke
255e3f2c991SKeyur Desai * smb_set_fileinfo for that node.
256e3f2c991SKeyur Desai *
2579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Path should be set in sr->arg.dirop.fqi.fq_path prior to
2589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * calling smb_set_by_path.
2599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States *
260e3f2c991SKeyur Desai * Setting attributes on a named pipe by name is an error and
261e3f2c991SKeyur Desai * is handled in the calling functions so that they can return
262e3f2c991SKeyur Desai * the appropriate error status code (which differs by caller).
263e3f2c991SKeyur Desai */
264e3f2c991SKeyur Desai static int
smb_set_by_path(smb_request_t * sr,smb_xa_t * xa,uint16_t infolev)2659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_set_by_path(smb_request_t *sr, smb_xa_t *xa, uint16_t infolev)
266e3f2c991SKeyur Desai {
267e3f2c991SKeyur Desai int rc;
268a90cf9f2SGordon Ross uint32_t status;
269e3f2c991SKeyur Desai smb_setinfo_t sinfo;
270e3f2c991SKeyur Desai smb_node_t *node, *dnode;
271e3f2c991SKeyur Desai char *name;
2729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_t *pn;
273e3f2c991SKeyur Desai
274e3f2c991SKeyur Desai if (SMB_TREE_IS_READONLY(sr)) {
275e3f2c991SKeyur Desai smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
276e3f2c991SKeyur Desai ERRDOS, ERROR_ACCESS_DENIED);
277e3f2c991SKeyur Desai return (-1);
278e3f2c991SKeyur Desai }
279e3f2c991SKeyur Desai
280*2dbda4a2SGordon Ross if (STYPE_ISIPC(sr->tid_tree->t_res_type))
281*2dbda4a2SGordon Ross return (0);
282*2dbda4a2SGordon Ross
2839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States pn = &sr->arg.dirop.fqi.fq_path;
2849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_init(sr, pn, pn->pn_path);
2859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (!smb_pathname_validate(sr, pn))
2869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (-1);
2879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
288e3f2c991SKeyur Desai name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
2899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States rc = smb_pathname_reduce(sr, sr->user_cr, pn->pn_path,
290e3f2c991SKeyur Desai sr->tid_tree->t_snode, sr->tid_tree->t_snode, &dnode, name);
291e3f2c991SKeyur Desai if (rc == 0) {
292e3f2c991SKeyur Desai rc = smb_fsop_lookup_name(sr, sr->user_cr, SMB_FOLLOW_LINKS,
293e3f2c991SKeyur Desai sr->tid_tree->t_snode, dnode, name, &node);
294e3f2c991SKeyur Desai smb_node_release(dnode);
295e3f2c991SKeyur Desai }
296e3f2c991SKeyur Desai kmem_free(name, MAXNAMELEN);
297e3f2c991SKeyur Desai
298e3f2c991SKeyur Desai if (rc != 0) {
299e3f2c991SKeyur Desai smbsr_errno(sr, rc);
300e3f2c991SKeyur Desai return (-1);
301e3f2c991SKeyur Desai }
302e3f2c991SKeyur Desai
303a90cf9f2SGordon Ross bzero(&sinfo, sizeof (sinfo));
304e3f2c991SKeyur Desai sinfo.si_node = node;
305a90cf9f2SGordon Ross if (xa != NULL)
306a90cf9f2SGordon Ross sinfo.si_data = xa->req_data_mb;
307a90cf9f2SGordon Ross status = smb_set_fileinfo(sr, &sinfo, infolev);
308a90cf9f2SGordon Ross if (status != 0) {
309a90cf9f2SGordon Ross smbsr_error(sr, status, 0, 0);
310a90cf9f2SGordon Ross rc = -1;
311a90cf9f2SGordon Ross }
312e3f2c991SKeyur Desai
313e3f2c991SKeyur Desai smb_node_release(node);
314e3f2c991SKeyur Desai return (rc);
315e3f2c991SKeyur Desai }
316e3f2c991SKeyur Desai
317e3f2c991SKeyur Desai /*
318e3f2c991SKeyur Desai * smb_set_fileinfo
319bbf6f00cSJordan Brown *
320bbf6f00cSJordan Brown * For compatibility with windows servers, SMB_FILE_LINK_INFORMATION
321bbf6f00cSJordan Brown * is handled by returning NT_STATUS_NOT_SUPPORTED.
322e3f2c991SKeyur Desai */
323a90cf9f2SGordon Ross static uint32_t
smb_set_fileinfo(smb_request_t * sr,smb_setinfo_t * sinfo,int infolev)324a90cf9f2SGordon Ross smb_set_fileinfo(smb_request_t *sr, smb_setinfo_t *sinfo, int infolev)
325e3f2c991SKeyur Desai {
326a90cf9f2SGordon Ross uint32_t status;
327a90cf9f2SGordon Ross
328a90cf9f2SGordon Ross switch (infolev) {
329e3f2c991SKeyur Desai case SMB_SET_INFORMATION:
330a90cf9f2SGordon Ross status = smb_set_information(sr, sinfo);
331a90cf9f2SGordon Ross break;
332e3f2c991SKeyur Desai
333e3f2c991SKeyur Desai case SMB_SET_INFORMATION2:
334a90cf9f2SGordon Ross status = smb_set_information2(sr, sinfo);
335a90cf9f2SGordon Ross break;
336e3f2c991SKeyur Desai
337e3f2c991SKeyur Desai case SMB_INFO_STANDARD:
338a90cf9f2SGordon Ross status = smb_set_standard_info(sr, sinfo);
339a90cf9f2SGordon Ross break;
340e3f2c991SKeyur Desai
341e3f2c991SKeyur Desai case SMB_INFO_SET_EAS:
3423bd40d98SGordon Ross status = NT_STATUS_EAS_NOT_SUPPORTED;
343a90cf9f2SGordon Ross break;
344e3f2c991SKeyur Desai
345e3f2c991SKeyur Desai case SMB_SET_FILE_BASIC_INFO:
346e3f2c991SKeyur Desai case SMB_FILE_BASIC_INFORMATION:
347a90cf9f2SGordon Ross status = smb_set_basic_info(sr, sinfo);
348a90cf9f2SGordon Ross break;
349e3f2c991SKeyur Desai
350e3f2c991SKeyur Desai case SMB_SET_FILE_DISPOSITION_INFO:
351e3f2c991SKeyur Desai case SMB_FILE_DISPOSITION_INFORMATION:
352a90cf9f2SGordon Ross status = smb_set_disposition_info(sr, sinfo);
353a90cf9f2SGordon Ross break;
354e3f2c991SKeyur Desai
355e3f2c991SKeyur Desai case SMB_SET_FILE_END_OF_FILE_INFO:
356e3f2c991SKeyur Desai case SMB_FILE_END_OF_FILE_INFORMATION:
357a90cf9f2SGordon Ross status = smb_set_eof_info(sr, sinfo);
358a90cf9f2SGordon Ross break;
359e3f2c991SKeyur Desai
360e3f2c991SKeyur Desai case SMB_SET_FILE_ALLOCATION_INFO:
361e3f2c991SKeyur Desai case SMB_FILE_ALLOCATION_INFORMATION:
362a90cf9f2SGordon Ross status = smb_set_alloc_info(sr, sinfo);
363a90cf9f2SGordon Ross break;
364e3f2c991SKeyur Desai
365bbf6f00cSJordan Brown case SMB_FILE_RENAME_INFORMATION:
366a90cf9f2SGordon Ross status = smb_set_rename_info(sr, sinfo);
367a90cf9f2SGordon Ross break;
368bbf6f00cSJordan Brown
369bbf6f00cSJordan Brown case SMB_FILE_LINK_INFORMATION:
370a90cf9f2SGordon Ross status = NT_STATUS_NOT_SUPPORTED;
371a90cf9f2SGordon Ross break;
372a90cf9f2SGordon Ross
373e3f2c991SKeyur Desai default:
374a90cf9f2SGordon Ross status = NT_STATUS_INVALID_INFO_CLASS;
375e3f2c991SKeyur Desai break;
376e3f2c991SKeyur Desai }
377e3f2c991SKeyur Desai
378a90cf9f2SGordon Ross return (status);
379e3f2c991SKeyur Desai }
380e3f2c991SKeyur Desai
381e3f2c991SKeyur Desai /*
382e3f2c991SKeyur Desai * smb_set_information
383e3f2c991SKeyur Desai *
384e3f2c991SKeyur Desai * It is not valid to set FILE_ATTRIBUTE_DIRECTORY if the
385e3f2c991SKeyur Desai * target is not a directory.
386e3f2c991SKeyur Desai *
387e3f2c991SKeyur Desai * For compatibility with Windows Servers, if the specified
388e3f2c991SKeyur Desai * attributes have ONLY FILE_ATTRIBUTE_NORMAL set do NOT change
389e3f2c991SKeyur Desai * the file's attributes.
390e3f2c991SKeyur Desai */
391a90cf9f2SGordon Ross static uint32_t
smb_set_information(smb_request_t * sr,smb_setinfo_t * sinfo)392e3f2c991SKeyur Desai smb_set_information(smb_request_t *sr, smb_setinfo_t *sinfo)
393e3f2c991SKeyur Desai {
394e3f2c991SKeyur Desai smb_attr_t attr;
395a90cf9f2SGordon Ross smb_node_t *node = sinfo->si_node;
396a90cf9f2SGordon Ross uint32_t status = 0;
397e3f2c991SKeyur Desai uint32_t mtime;
398a90cf9f2SGordon Ross uint16_t attributes;
399a90cf9f2SGordon Ross int rc;
400e3f2c991SKeyur Desai
401e3f2c991SKeyur Desai if (smbsr_decode_vwv(sr, "wl10.", &attributes, &mtime) != 0)
402a90cf9f2SGordon Ross return (NT_STATUS_INFO_LENGTH_MISMATCH);
403e3f2c991SKeyur Desai
404e3f2c991SKeyur Desai if ((attributes & FILE_ATTRIBUTE_DIRECTORY) &&
405e3f2c991SKeyur Desai (!smb_node_is_dir(node))) {
406a90cf9f2SGordon Ross return (NT_STATUS_INVALID_PARAMETER);
407e3f2c991SKeyur Desai }
408e3f2c991SKeyur Desai
409e3f2c991SKeyur Desai bzero(&attr, sizeof (smb_attr_t));
410e3f2c991SKeyur Desai if (attributes != FILE_ATTRIBUTE_NORMAL) {
411e3f2c991SKeyur Desai attr.sa_dosattr = attributes;
412e3f2c991SKeyur Desai attr.sa_mask |= SMB_AT_DOSATTR;
413e3f2c991SKeyur Desai }
414e3f2c991SKeyur Desai
415e3f2c991SKeyur Desai if (mtime != 0 && mtime != UINT_MAX) {
416e3f2c991SKeyur Desai attr.sa_vattr.va_mtime.tv_sec =
417e3f2c991SKeyur Desai smb_time_local_to_gmt(sr, mtime);
418e3f2c991SKeyur Desai attr.sa_mask |= SMB_AT_MTIME;
419e3f2c991SKeyur Desai }
420e3f2c991SKeyur Desai
421e3f2c991SKeyur Desai rc = smb_node_setattr(sr, node, sr->user_cr, NULL, &attr);
422a90cf9f2SGordon Ross if (rc != 0)
423a90cf9f2SGordon Ross status = smb_errno2status(rc);
424e3f2c991SKeyur Desai
425a90cf9f2SGordon Ross return (status);
426e3f2c991SKeyur Desai }
427e3f2c991SKeyur Desai
428e3f2c991SKeyur Desai /*
429e3f2c991SKeyur Desai * smb_set_information2
430e3f2c991SKeyur Desai */
431a90cf9f2SGordon Ross static uint32_t
smb_set_information2(smb_request_t * sr,smb_setinfo_t * sinfo)432e3f2c991SKeyur Desai smb_set_information2(smb_request_t *sr, smb_setinfo_t *sinfo)
433e3f2c991SKeyur Desai {
434e3f2c991SKeyur Desai smb_attr_t attr;
435a90cf9f2SGordon Ross uint32_t crtime, atime, mtime;
436a90cf9f2SGordon Ross uint32_t status = 0;
437a90cf9f2SGordon Ross int rc;
438e3f2c991SKeyur Desai
439e3f2c991SKeyur Desai if (smbsr_decode_vwv(sr, "yyy", &crtime, &atime, &mtime) != 0)
440a90cf9f2SGordon Ross return (NT_STATUS_INFO_LENGTH_MISMATCH);
441e3f2c991SKeyur Desai
442e3f2c991SKeyur Desai bzero(&attr, sizeof (smb_attr_t));
443e3f2c991SKeyur Desai if (mtime != 0 && mtime != UINT_MAX) {
444e3f2c991SKeyur Desai attr.sa_vattr.va_mtime.tv_sec =
445e3f2c991SKeyur Desai smb_time_local_to_gmt(sr, mtime);
446e3f2c991SKeyur Desai attr.sa_mask |= SMB_AT_MTIME;
447e3f2c991SKeyur Desai }
448e3f2c991SKeyur Desai
449e3f2c991SKeyur Desai if (crtime != 0 && crtime != UINT_MAX) {
450e3f2c991SKeyur Desai attr.sa_crtime.tv_sec = smb_time_local_to_gmt(sr, crtime);
451e3f2c991SKeyur Desai attr.sa_mask |= SMB_AT_CRTIME;
452e3f2c991SKeyur Desai }
453e3f2c991SKeyur Desai
454e3f2c991SKeyur Desai if (atime != 0 && atime != UINT_MAX) {
455e3f2c991SKeyur Desai attr.sa_vattr.va_atime.tv_sec =
456e3f2c991SKeyur Desai smb_time_local_to_gmt(sr, atime);
457e3f2c991SKeyur Desai attr.sa_mask |= SMB_AT_ATIME;
458e3f2c991SKeyur Desai }
459e3f2c991SKeyur Desai
460e3f2c991SKeyur Desai rc = smb_node_setattr(sr, sinfo->si_node, sr->user_cr,
461e3f2c991SKeyur Desai sr->fid_ofile, &attr);
462a90cf9f2SGordon Ross if (rc != 0)
463a90cf9f2SGordon Ross status = smb_errno2status(rc);
464e3f2c991SKeyur Desai
465a90cf9f2SGordon Ross return (status);
466e3f2c991SKeyur Desai }
467e3f2c991SKeyur Desai
468e3f2c991SKeyur Desai /*
469e3f2c991SKeyur Desai * smb_set_standard_info
470e3f2c991SKeyur Desai *
471e3f2c991SKeyur Desai * Sets standard file/path information.
472e3f2c991SKeyur Desai */
473a90cf9f2SGordon Ross static uint32_t
smb_set_standard_info(smb_request_t * sr,smb_setinfo_t * sinfo)474e3f2c991SKeyur Desai smb_set_standard_info(smb_request_t *sr, smb_setinfo_t *sinfo)
475e3f2c991SKeyur Desai {
476e3f2c991SKeyur Desai smb_attr_t attr;
477e3f2c991SKeyur Desai smb_node_t *node = sinfo->si_node;
478a90cf9f2SGordon Ross uint32_t crtime, atime, mtime;
479a90cf9f2SGordon Ross uint32_t status = 0;
480e3f2c991SKeyur Desai int rc;
481e3f2c991SKeyur Desai
482a90cf9f2SGordon Ross if (smb_mbc_decodef(&sinfo->si_data, "yyy",
483a90cf9f2SGordon Ross &crtime, &atime, &mtime) != 0)
484a90cf9f2SGordon Ross return (NT_STATUS_INFO_LENGTH_MISMATCH);
485e3f2c991SKeyur Desai
486e3f2c991SKeyur Desai bzero(&attr, sizeof (smb_attr_t));
487e3f2c991SKeyur Desai if (mtime != 0 && mtime != (uint32_t)-1) {
488e3f2c991SKeyur Desai attr.sa_vattr.va_mtime.tv_sec =
489e3f2c991SKeyur Desai smb_time_local_to_gmt(sr, mtime);
490e3f2c991SKeyur Desai attr.sa_mask |= SMB_AT_MTIME;
491e3f2c991SKeyur Desai }
492e3f2c991SKeyur Desai
493e3f2c991SKeyur Desai if (crtime != 0 && crtime != (uint32_t)-1) {
494e3f2c991SKeyur Desai attr.sa_crtime.tv_sec = smb_time_local_to_gmt(sr, crtime);
495e3f2c991SKeyur Desai attr.sa_mask |= SMB_AT_CRTIME;
496e3f2c991SKeyur Desai }
497e3f2c991SKeyur Desai
498e3f2c991SKeyur Desai if (atime != 0 && atime != (uint32_t)-1) {
499e3f2c991SKeyur Desai attr.sa_vattr.va_atime.tv_sec =
500e3f2c991SKeyur Desai smb_time_local_to_gmt(sr, atime);
501e3f2c991SKeyur Desai attr.sa_mask |= SMB_AT_ATIME;
502e3f2c991SKeyur Desai }
503e3f2c991SKeyur Desai
504e3f2c991SKeyur Desai rc = smb_node_setattr(sr, node, sr->user_cr, sr->fid_ofile, &attr);
505a90cf9f2SGordon Ross if (rc != 0)
506a90cf9f2SGordon Ross status = smb_errno2status(rc);
507e3f2c991SKeyur Desai
508a90cf9f2SGordon Ross return (status);
509e3f2c991SKeyur Desai }
510bbf6f00cSJordan Brown
511bbf6f00cSJordan Brown /*
512bbf6f00cSJordan Brown * smb_set_rename_info
513bbf6f00cSJordan Brown *
514a90cf9f2SGordon Ross * This call only allows a rename in the same directory, and the
515a90cf9f2SGordon Ross * directory name is not part of the new name provided.
516a90cf9f2SGordon Ross *
517cb174861Sjoyce mcintosh * Explicitly specified parameter validation rules:
518bbf6f00cSJordan Brown * - If rootdir is not NULL respond with NT_STATUS_INVALID_PARAMETER.
519bbf6f00cSJordan Brown * - If the filename contains a separator character respond with
520bbf6f00cSJordan Brown * NT_STATUS_INVALID_PARAMETER.
521cb174861Sjoyce mcintosh *
522cb174861Sjoyce mcintosh * Oplock break:
523cb174861Sjoyce mcintosh * Some Windows servers break BATCH oplocks prior to the rename.
524cb174861Sjoyce mcintosh * W2K3 does not. We behave as W2K3; we do not send an oplock break.
525bbf6f00cSJordan Brown */
526a90cf9f2SGordon Ross static uint32_t
smb_set_rename_info(smb_request_t * sr,smb_setinfo_t * sinfo)527bbf6f00cSJordan Brown smb_set_rename_info(smb_request_t *sr, smb_setinfo_t *sinfo)
528bbf6f00cSJordan Brown {
529a90cf9f2SGordon Ross smb_fqi_t *src_fqi = &sr->arg.dirop.fqi;
530a90cf9f2SGordon Ross smb_fqi_t *dst_fqi = &sr->arg.dirop.dst_fqi;
531bbf6f00cSJordan Brown char *fname;
532a90cf9f2SGordon Ross char *path;
533a90cf9f2SGordon Ross uint8_t flags;
534a90cf9f2SGordon Ross uint32_t rootdir, namelen;
535a90cf9f2SGordon Ross uint32_t status = 0;
536a90cf9f2SGordon Ross int rc;
537bbf6f00cSJordan Brown
538a90cf9f2SGordon Ross rc = smb_mbc_decodef(&sinfo->si_data, "b...ll",
539bbf6f00cSJordan Brown &flags, &rootdir, &namelen);
540bbf6f00cSJordan Brown if (rc == 0) {
541a90cf9f2SGordon Ross rc = smb_mbc_decodef(&sinfo->si_data, "%#U",
542bbf6f00cSJordan Brown sr, namelen, &fname);
543bbf6f00cSJordan Brown }
544bbf6f00cSJordan Brown if (rc != 0)
545a90cf9f2SGordon Ross return (NT_STATUS_INFO_LENGTH_MISMATCH);
546bbf6f00cSJordan Brown
547bbf6f00cSJordan Brown if ((rootdir != 0) || (namelen == 0) || (namelen >= MAXNAMELEN)) {
548a90cf9f2SGordon Ross return (NT_STATUS_INVALID_PARAMETER);
549bbf6f00cSJordan Brown }
550bbf6f00cSJordan Brown
551bbf6f00cSJordan Brown if (strchr(fname, '\\') != NULL) {
552a90cf9f2SGordon Ross return (NT_STATUS_NOT_SUPPORTED);
553bbf6f00cSJordan Brown }
554bbf6f00cSJordan Brown
555a90cf9f2SGordon Ross /*
556a90cf9f2SGordon Ross * Construct the full dst. path relative to the share root.
557a90cf9f2SGordon Ross * Allocated path is free'd in smb_request_free.
558a90cf9f2SGordon Ross */
559a90cf9f2SGordon Ross path = smb_srm_zalloc(sr, SMB_MAXPATHLEN);
560a90cf9f2SGordon Ross if (src_fqi->fq_path.pn_pname) {
561a90cf9f2SGordon Ross /* Got here via: smb_set_by_path */
562a90cf9f2SGordon Ross (void) snprintf(path, SMB_MAXPATHLEN, "%s\\%s",
563a90cf9f2SGordon Ross src_fqi->fq_path.pn_pname, fname);
564a90cf9f2SGordon Ross } else {
565a90cf9f2SGordon Ross /* Got here via: smb_set_by_fid */
566a90cf9f2SGordon Ross rc = smb_node_getshrpath(sinfo->si_node->n_dnode,
567a90cf9f2SGordon Ross sr->tid_tree, path, SMB_MAXPATHLEN);
568a90cf9f2SGordon Ross if (rc != 0) {
569a90cf9f2SGordon Ross status = smb_errno2status(rc);
570a90cf9f2SGordon Ross return (status);
571a90cf9f2SGordon Ross }
572a90cf9f2SGordon Ross (void) strlcat(path, "\\", SMB_MAXPATHLEN);
573a90cf9f2SGordon Ross (void) strlcat(path, fname, SMB_MAXPATHLEN);
574a90cf9f2SGordon Ross }
575bbf6f00cSJordan Brown
576a90cf9f2SGordon Ross /*
577a90cf9f2SGordon Ross * The common rename code can slightly optimize a
578a90cf9f2SGordon Ross * rename in the same directory when we set the
579a90cf9f2SGordon Ross * dst_fqi->fq_dnode, dst_fqi->fq_last_comp
580a90cf9f2SGordon Ross */
581a90cf9f2SGordon Ross dst_fqi->fq_dnode = sinfo->si_node->n_dnode;
582a90cf9f2SGordon Ross (void) strlcpy(dst_fqi->fq_last_comp, fname, MAXNAMELEN);
583a90cf9f2SGordon Ross
584a90cf9f2SGordon Ross status = smb_setinfo_rename(sr, sinfo->si_node, path, flags);
585a90cf9f2SGordon Ross return (status);
586bbf6f00cSJordan Brown }
587