110504SKeyur.Desai@Sun.COM /*
210504SKeyur.Desai@Sun.COM * CDDL HEADER START
310504SKeyur.Desai@Sun.COM *
410504SKeyur.Desai@Sun.COM * The contents of this file are subject to the terms of the
510504SKeyur.Desai@Sun.COM * Common Development and Distribution License (the "License").
610504SKeyur.Desai@Sun.COM * You may not use this file except in compliance with the License.
710504SKeyur.Desai@Sun.COM *
810504SKeyur.Desai@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910504SKeyur.Desai@Sun.COM * or http://www.opensolaris.org/os/licensing.
1010504SKeyur.Desai@Sun.COM * See the License for the specific language governing permissions
1110504SKeyur.Desai@Sun.COM * and limitations under the License.
1210504SKeyur.Desai@Sun.COM *
1310504SKeyur.Desai@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
1410504SKeyur.Desai@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510504SKeyur.Desai@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
1610504SKeyur.Desai@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
1710504SKeyur.Desai@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
1810504SKeyur.Desai@Sun.COM *
1910504SKeyur.Desai@Sun.COM * CDDL HEADER END
2010504SKeyur.Desai@Sun.COM */
2110504SKeyur.Desai@Sun.COM /*
22*12890SJoyce.McIntosh@Sun.COM * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
2310504SKeyur.Desai@Sun.COM */
2410504SKeyur.Desai@Sun.COM
2510504SKeyur.Desai@Sun.COM /*
2610504SKeyur.Desai@Sun.COM * Trans2 Set File/Path Information Levels:
2710504SKeyur.Desai@Sun.COM *
2810504SKeyur.Desai@Sun.COM * SMB_INFO_STANDARD
2910504SKeyur.Desai@Sun.COM * SMB_INFO_SET_EAS
3010504SKeyur.Desai@Sun.COM * SMB_SET_FILE_BASIC_INFO
3110504SKeyur.Desai@Sun.COM * SMB_SET_FILE_DISPOSITION_INFO
3210504SKeyur.Desai@Sun.COM * SMB_SET_FILE_END_OF_FILE_INFO
3310504SKeyur.Desai@Sun.COM * SMB_SET_FILE_ALLOCATION_INFO
3410504SKeyur.Desai@Sun.COM *
3510966SJordan.Brown@Sun.COM * Handled Passthrough levels:
3610504SKeyur.Desai@Sun.COM * SMB_FILE_BASIC_INFORMATION
3710966SJordan.Brown@Sun.COM * SMB_FILE_RENAME_INFORMATION
3810966SJordan.Brown@Sun.COM * SMB_FILE_LINK_INFORMATION
3910504SKeyur.Desai@Sun.COM * SMB_FILE_DISPOSITION_INFORMATION
4010504SKeyur.Desai@Sun.COM * SMB_FILE_END_OF_FILE_INFORMATION
4110504SKeyur.Desai@Sun.COM * SMB_FILE_ALLOCATION_INFORMATION
4210504SKeyur.Desai@Sun.COM *
4310504SKeyur.Desai@Sun.COM * Internal levels representing non trans2 requests
4410504SKeyur.Desai@Sun.COM * SMB_SET_INFORMATION
4510504SKeyur.Desai@Sun.COM * SMB_SET_INFORMATION2
4610504SKeyur.Desai@Sun.COM */
4710504SKeyur.Desai@Sun.COM
4810504SKeyur.Desai@Sun.COM /*
4910504SKeyur.Desai@Sun.COM * Setting timestamps:
5010504SKeyur.Desai@Sun.COM * The behaviour when the time field is set to -1 is not documented
5110504SKeyur.Desai@Sun.COM * but is generally treated like 0, meaning that that server file
5210504SKeyur.Desai@Sun.COM * system assigned value need not be changed.
5310504SKeyur.Desai@Sun.COM *
5410504SKeyur.Desai@Sun.COM * Setting attributes - FILE_ATTRIBUTE_NORMAL:
5510504SKeyur.Desai@Sun.COM * SMB_SET_INFORMATION -
5610504SKeyur.Desai@Sun.COM * - if the specified attributes have ONLY FILE_ATTRIBUTE_NORMAL set
5710504SKeyur.Desai@Sun.COM * do NOT change the file's attributes.
5810504SKeyur.Desai@Sun.COM * SMB_SET_BASIC_INFO -
5910504SKeyur.Desai@Sun.COM * - if the specified attributes have ONLY FILE_ATTRIBUTE_NORMAL set
6010504SKeyur.Desai@Sun.COM * clear (0) the file's attributes.
6110504SKeyur.Desai@Sun.COM * - if the specified attributes are 0 do NOT change the file's
6210504SKeyur.Desai@Sun.COM * attributes.
6310504SKeyur.Desai@Sun.COM */
6410504SKeyur.Desai@Sun.COM
6510966SJordan.Brown@Sun.COM #include <smbsrv/smb_kproto.h>
6610504SKeyur.Desai@Sun.COM #include <smbsrv/smb_fsops.h>
6710504SKeyur.Desai@Sun.COM
6810504SKeyur.Desai@Sun.COM typedef struct smb_setinfo {
6910504SKeyur.Desai@Sun.COM uint16_t si_infolev;
7010504SKeyur.Desai@Sun.COM smb_xa_t *si_xa;
7110504SKeyur.Desai@Sun.COM smb_node_t *si_node;
7210504SKeyur.Desai@Sun.COM } smb_setinfo_t;
7310504SKeyur.Desai@Sun.COM
7410504SKeyur.Desai@Sun.COM /*
7510504SKeyur.Desai@Sun.COM * These functions all return 0 (success) or -1 (error).
7610504SKeyur.Desai@Sun.COM * They set error details in the sr when appropriate.
7710504SKeyur.Desai@Sun.COM */
7810504SKeyur.Desai@Sun.COM static int smb_set_by_fid(smb_request_t *, smb_xa_t *, uint16_t);
7911963SAfshin.Ardakani@Sun.COM static int smb_set_by_path(smb_request_t *, smb_xa_t *, uint16_t);
8010504SKeyur.Desai@Sun.COM static int smb_set_fileinfo(smb_request_t *, smb_setinfo_t *);
8110504SKeyur.Desai@Sun.COM static int smb_set_information(smb_request_t *, smb_setinfo_t *);
8210504SKeyur.Desai@Sun.COM static int smb_set_information2(smb_request_t *, smb_setinfo_t *);
8310504SKeyur.Desai@Sun.COM static int smb_set_standard_info(smb_request_t *, smb_setinfo_t *);
8410504SKeyur.Desai@Sun.COM static int smb_set_basic_info(smb_request_t *, smb_setinfo_t *);
8510504SKeyur.Desai@Sun.COM static int smb_set_disposition_info(smb_request_t *, smb_setinfo_t *);
8610504SKeyur.Desai@Sun.COM static int smb_set_eof_info(smb_request_t *sr, smb_setinfo_t *);
8710504SKeyur.Desai@Sun.COM static int smb_set_alloc_info(smb_request_t *sr, smb_setinfo_t *);
8810966SJordan.Brown@Sun.COM static int smb_set_rename_info(smb_request_t *sr, smb_setinfo_t *);
8910504SKeyur.Desai@Sun.COM
9010504SKeyur.Desai@Sun.COM /*
9110504SKeyur.Desai@Sun.COM * smb_com_trans2_set_file_information
9210504SKeyur.Desai@Sun.COM */
9310504SKeyur.Desai@Sun.COM smb_sdrc_t
smb_com_trans2_set_file_information(smb_request_t * sr,smb_xa_t * xa)9410504SKeyur.Desai@Sun.COM smb_com_trans2_set_file_information(smb_request_t *sr, smb_xa_t *xa)
9510504SKeyur.Desai@Sun.COM {
9610504SKeyur.Desai@Sun.COM uint16_t infolev;
9710504SKeyur.Desai@Sun.COM
9810504SKeyur.Desai@Sun.COM if (smb_mbc_decodef(&xa->req_param_mb, "ww",
9910504SKeyur.Desai@Sun.COM &sr->smb_fid, &infolev) != 0)
10010504SKeyur.Desai@Sun.COM return (SDRC_ERROR);
10110504SKeyur.Desai@Sun.COM
10210504SKeyur.Desai@Sun.COM if (smb_set_by_fid(sr, xa, infolev) != 0)
10310504SKeyur.Desai@Sun.COM return (SDRC_ERROR);
10410504SKeyur.Desai@Sun.COM
10510504SKeyur.Desai@Sun.COM return (SDRC_SUCCESS);
10610504SKeyur.Desai@Sun.COM }
10710504SKeyur.Desai@Sun.COM
10810504SKeyur.Desai@Sun.COM /*
10910504SKeyur.Desai@Sun.COM * smb_com_trans2_set_path_information
11010504SKeyur.Desai@Sun.COM */
11110504SKeyur.Desai@Sun.COM smb_sdrc_t
smb_com_trans2_set_path_information(smb_request_t * sr,smb_xa_t * xa)11210504SKeyur.Desai@Sun.COM smb_com_trans2_set_path_information(smb_request_t *sr, smb_xa_t *xa)
11310504SKeyur.Desai@Sun.COM {
11411963SAfshin.Ardakani@Sun.COM uint16_t infolev;
11511963SAfshin.Ardakani@Sun.COM smb_fqi_t *fqi = &sr->arg.dirop.fqi;
11610504SKeyur.Desai@Sun.COM
11711447Samw@Sun.COM if (STYPE_ISIPC(sr->tid_tree->t_res_type)) {
11810504SKeyur.Desai@Sun.COM smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
11910504SKeyur.Desai@Sun.COM ERRDOS, ERROR_INVALID_FUNCTION);
12010504SKeyur.Desai@Sun.COM return (SDRC_ERROR);
12110504SKeyur.Desai@Sun.COM }
12210504SKeyur.Desai@Sun.COM
12310504SKeyur.Desai@Sun.COM if (smb_mbc_decodef(&xa->req_param_mb, "%w4.u",
12411963SAfshin.Ardakani@Sun.COM sr, &infolev, &fqi->fq_path.pn_path) != 0)
12510504SKeyur.Desai@Sun.COM return (SDRC_ERROR);
12610504SKeyur.Desai@Sun.COM
12711963SAfshin.Ardakani@Sun.COM if (smb_set_by_path(sr, xa, infolev) != 0)
12810504SKeyur.Desai@Sun.COM return (SDRC_ERROR);
12910504SKeyur.Desai@Sun.COM
13010504SKeyur.Desai@Sun.COM return (SDRC_SUCCESS);
13110504SKeyur.Desai@Sun.COM }
13210504SKeyur.Desai@Sun.COM
13310504SKeyur.Desai@Sun.COM /*
13410504SKeyur.Desai@Sun.COM * smb_com_set_information (aka setattr)
13510504SKeyur.Desai@Sun.COM */
13610504SKeyur.Desai@Sun.COM smb_sdrc_t
smb_pre_set_information(smb_request_t * sr)13710504SKeyur.Desai@Sun.COM smb_pre_set_information(smb_request_t *sr)
13810504SKeyur.Desai@Sun.COM {
13910504SKeyur.Desai@Sun.COM DTRACE_SMB_1(op__SetInformation__start, smb_request_t *, sr);
14010504SKeyur.Desai@Sun.COM return (SDRC_SUCCESS);
14110504SKeyur.Desai@Sun.COM }
14210504SKeyur.Desai@Sun.COM
14310504SKeyur.Desai@Sun.COM void
smb_post_set_information(smb_request_t * sr)14410504SKeyur.Desai@Sun.COM smb_post_set_information(smb_request_t *sr)
14510504SKeyur.Desai@Sun.COM {
14610504SKeyur.Desai@Sun.COM DTRACE_SMB_1(op__SetInformation__done, smb_request_t *, sr);
14710504SKeyur.Desai@Sun.COM }
14810504SKeyur.Desai@Sun.COM
14910504SKeyur.Desai@Sun.COM smb_sdrc_t
smb_com_set_information(smb_request_t * sr)15010504SKeyur.Desai@Sun.COM smb_com_set_information(smb_request_t *sr)
15110504SKeyur.Desai@Sun.COM {
15211963SAfshin.Ardakani@Sun.COM uint16_t infolev = SMB_SET_INFORMATION;
15311963SAfshin.Ardakani@Sun.COM smb_fqi_t *fqi = &sr->arg.dirop.fqi;
15410504SKeyur.Desai@Sun.COM
15511447Samw@Sun.COM if (STYPE_ISIPC(sr->tid_tree->t_res_type)) {
15610504SKeyur.Desai@Sun.COM smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
15710504SKeyur.Desai@Sun.COM ERRDOS, ERROR_ACCESS_DENIED);
15810504SKeyur.Desai@Sun.COM return (SDRC_ERROR);
15910504SKeyur.Desai@Sun.COM }
16010504SKeyur.Desai@Sun.COM
16111963SAfshin.Ardakani@Sun.COM if (smbsr_decode_data(sr, "%S", sr, &fqi->fq_path.pn_path) != 0)
16210504SKeyur.Desai@Sun.COM return (SDRC_ERROR);
16310504SKeyur.Desai@Sun.COM
16411963SAfshin.Ardakani@Sun.COM if (smb_set_by_path(sr, NULL, infolev) != 0)
16510504SKeyur.Desai@Sun.COM return (SDRC_ERROR);
16610504SKeyur.Desai@Sun.COM
16710504SKeyur.Desai@Sun.COM if (smbsr_encode_empty_result(sr) != 0)
16810504SKeyur.Desai@Sun.COM return (SDRC_ERROR);
16910504SKeyur.Desai@Sun.COM
17010504SKeyur.Desai@Sun.COM return (SDRC_SUCCESS);
17110504SKeyur.Desai@Sun.COM }
17210504SKeyur.Desai@Sun.COM
17310504SKeyur.Desai@Sun.COM /*
17410504SKeyur.Desai@Sun.COM * smb_com_set_information2 (aka setattre)
17510504SKeyur.Desai@Sun.COM */
17610504SKeyur.Desai@Sun.COM smb_sdrc_t
smb_pre_set_information2(smb_request_t * sr)17710504SKeyur.Desai@Sun.COM smb_pre_set_information2(smb_request_t *sr)
17810504SKeyur.Desai@Sun.COM {
17910504SKeyur.Desai@Sun.COM DTRACE_SMB_1(op__SetInformation2__start, smb_request_t *, sr);
18010504SKeyur.Desai@Sun.COM return (SDRC_SUCCESS);
18110504SKeyur.Desai@Sun.COM }
18210504SKeyur.Desai@Sun.COM
18310504SKeyur.Desai@Sun.COM void
smb_post_set_information2(smb_request_t * sr)18410504SKeyur.Desai@Sun.COM smb_post_set_information2(smb_request_t *sr)
18510504SKeyur.Desai@Sun.COM {
18610504SKeyur.Desai@Sun.COM DTRACE_SMB_1(op__SetInformation2__done, smb_request_t *, sr);
18710504SKeyur.Desai@Sun.COM }
18810504SKeyur.Desai@Sun.COM
18910504SKeyur.Desai@Sun.COM smb_sdrc_t
smb_com_set_information2(smb_request_t * sr)19010504SKeyur.Desai@Sun.COM smb_com_set_information2(smb_request_t *sr)
19110504SKeyur.Desai@Sun.COM {
19210504SKeyur.Desai@Sun.COM uint16_t infolev = SMB_SET_INFORMATION2;
19310504SKeyur.Desai@Sun.COM
19410504SKeyur.Desai@Sun.COM if (smbsr_decode_vwv(sr, "w", &sr->smb_fid) != 0)
19510504SKeyur.Desai@Sun.COM return (SDRC_ERROR);
19610504SKeyur.Desai@Sun.COM
19710504SKeyur.Desai@Sun.COM if (smb_set_by_fid(sr, NULL, infolev) != 0)
19810504SKeyur.Desai@Sun.COM return (SDRC_ERROR);
19910504SKeyur.Desai@Sun.COM
20010504SKeyur.Desai@Sun.COM if (smbsr_encode_empty_result(sr) != 0)
20110504SKeyur.Desai@Sun.COM return (SDRC_ERROR);
20210504SKeyur.Desai@Sun.COM
20310504SKeyur.Desai@Sun.COM return (SDRC_SUCCESS);
20410504SKeyur.Desai@Sun.COM }
20510504SKeyur.Desai@Sun.COM
20610504SKeyur.Desai@Sun.COM /*
20710504SKeyur.Desai@Sun.COM * smb_set_by_fid
20810504SKeyur.Desai@Sun.COM *
20910504SKeyur.Desai@Sun.COM * Common code for setting file information by open file id.
21010504SKeyur.Desai@Sun.COM * Use the id to identify the node object and invoke smb_set_fileinfo
21110504SKeyur.Desai@Sun.COM * for that node.
21210504SKeyur.Desai@Sun.COM *
21310504SKeyur.Desai@Sun.COM * Setting attributes on a named pipe by id is handled by simply
21410504SKeyur.Desai@Sun.COM * returning success.
21510504SKeyur.Desai@Sun.COM */
21610504SKeyur.Desai@Sun.COM static int
smb_set_by_fid(smb_request_t * sr,smb_xa_t * xa,uint16_t infolev)21710504SKeyur.Desai@Sun.COM smb_set_by_fid(smb_request_t *sr, smb_xa_t *xa, uint16_t infolev)
21810504SKeyur.Desai@Sun.COM {
21910504SKeyur.Desai@Sun.COM int rc;
22010504SKeyur.Desai@Sun.COM smb_setinfo_t sinfo;
22110504SKeyur.Desai@Sun.COM
22210504SKeyur.Desai@Sun.COM if (SMB_TREE_IS_READONLY(sr)) {
22310504SKeyur.Desai@Sun.COM smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
22410504SKeyur.Desai@Sun.COM ERRDOS, ERROR_ACCESS_DENIED);
22510504SKeyur.Desai@Sun.COM return (-1);
22610504SKeyur.Desai@Sun.COM }
22710504SKeyur.Desai@Sun.COM
22811447Samw@Sun.COM if (STYPE_ISIPC(sr->tid_tree->t_res_type))
22910504SKeyur.Desai@Sun.COM return (0);
23010504SKeyur.Desai@Sun.COM
23110504SKeyur.Desai@Sun.COM smbsr_lookup_file(sr);
23210504SKeyur.Desai@Sun.COM if (sr->fid_ofile == NULL) {
23310504SKeyur.Desai@Sun.COM smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
23410504SKeyur.Desai@Sun.COM return (-1);
23510504SKeyur.Desai@Sun.COM }
23610504SKeyur.Desai@Sun.COM
23710504SKeyur.Desai@Sun.COM if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
23810504SKeyur.Desai@Sun.COM smbsr_release_file(sr);
23910504SKeyur.Desai@Sun.COM return (0);
24010504SKeyur.Desai@Sun.COM }
24110504SKeyur.Desai@Sun.COM
24210504SKeyur.Desai@Sun.COM sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
24310504SKeyur.Desai@Sun.COM
24410504SKeyur.Desai@Sun.COM sinfo.si_xa = xa;
24510504SKeyur.Desai@Sun.COM sinfo.si_infolev = infolev;
24610504SKeyur.Desai@Sun.COM sinfo.si_node = sr->fid_ofile->f_node;
24710504SKeyur.Desai@Sun.COM rc = smb_set_fileinfo(sr, &sinfo);
24810504SKeyur.Desai@Sun.COM
24910504SKeyur.Desai@Sun.COM smbsr_release_file(sr);
25010504SKeyur.Desai@Sun.COM return (rc);
25110504SKeyur.Desai@Sun.COM }
25210504SKeyur.Desai@Sun.COM
25310504SKeyur.Desai@Sun.COM /*
25410504SKeyur.Desai@Sun.COM * smb_set_by_path
25510504SKeyur.Desai@Sun.COM *
25610504SKeyur.Desai@Sun.COM * Common code for setting file information by file name.
25710504SKeyur.Desai@Sun.COM * Use the file name to identify the node object and invoke
25810504SKeyur.Desai@Sun.COM * smb_set_fileinfo for that node.
25910504SKeyur.Desai@Sun.COM *
26011963SAfshin.Ardakani@Sun.COM * Path should be set in sr->arg.dirop.fqi.fq_path prior to
26111963SAfshin.Ardakani@Sun.COM * calling smb_set_by_path.
26211963SAfshin.Ardakani@Sun.COM *
26310504SKeyur.Desai@Sun.COM * Setting attributes on a named pipe by name is an error and
26410504SKeyur.Desai@Sun.COM * is handled in the calling functions so that they can return
26510504SKeyur.Desai@Sun.COM * the appropriate error status code (which differs by caller).
26610504SKeyur.Desai@Sun.COM */
26710504SKeyur.Desai@Sun.COM static int
smb_set_by_path(smb_request_t * sr,smb_xa_t * xa,uint16_t infolev)26811963SAfshin.Ardakani@Sun.COM smb_set_by_path(smb_request_t *sr, smb_xa_t *xa, uint16_t infolev)
26910504SKeyur.Desai@Sun.COM {
27010504SKeyur.Desai@Sun.COM int rc;
27110504SKeyur.Desai@Sun.COM smb_setinfo_t sinfo;
27210504SKeyur.Desai@Sun.COM smb_node_t *node, *dnode;
27310504SKeyur.Desai@Sun.COM char *name;
27411963SAfshin.Ardakani@Sun.COM smb_pathname_t *pn;
27510504SKeyur.Desai@Sun.COM
27610504SKeyur.Desai@Sun.COM if (SMB_TREE_IS_READONLY(sr)) {
27710504SKeyur.Desai@Sun.COM smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
27810504SKeyur.Desai@Sun.COM ERRDOS, ERROR_ACCESS_DENIED);
27910504SKeyur.Desai@Sun.COM return (-1);
28010504SKeyur.Desai@Sun.COM }
28110504SKeyur.Desai@Sun.COM
28211963SAfshin.Ardakani@Sun.COM pn = &sr->arg.dirop.fqi.fq_path;
28311963SAfshin.Ardakani@Sun.COM smb_pathname_init(sr, pn, pn->pn_path);
28411963SAfshin.Ardakani@Sun.COM if (!smb_pathname_validate(sr, pn))
28511963SAfshin.Ardakani@Sun.COM return (-1);
28611963SAfshin.Ardakani@Sun.COM
28710504SKeyur.Desai@Sun.COM name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
28811963SAfshin.Ardakani@Sun.COM rc = smb_pathname_reduce(sr, sr->user_cr, pn->pn_path,
28910504SKeyur.Desai@Sun.COM sr->tid_tree->t_snode, sr->tid_tree->t_snode, &dnode, name);
29010504SKeyur.Desai@Sun.COM if (rc == 0) {
29110504SKeyur.Desai@Sun.COM rc = smb_fsop_lookup_name(sr, sr->user_cr, SMB_FOLLOW_LINKS,
29210504SKeyur.Desai@Sun.COM sr->tid_tree->t_snode, dnode, name, &node);
29310504SKeyur.Desai@Sun.COM smb_node_release(dnode);
29410504SKeyur.Desai@Sun.COM }
29510504SKeyur.Desai@Sun.COM kmem_free(name, MAXNAMELEN);
29610504SKeyur.Desai@Sun.COM
29710504SKeyur.Desai@Sun.COM if (rc != 0) {
29810966SJordan.Brown@Sun.COM if (rc == ENOENT) {
29910966SJordan.Brown@Sun.COM smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
30010966SJordan.Brown@Sun.COM ERRDOS, ERROR_FILE_NOT_FOUND);
30110966SJordan.Brown@Sun.COM } else {
30210966SJordan.Brown@Sun.COM smbsr_errno(sr, rc);
30310966SJordan.Brown@Sun.COM }
30410504SKeyur.Desai@Sun.COM return (-1);
30510504SKeyur.Desai@Sun.COM }
30610504SKeyur.Desai@Sun.COM
30710504SKeyur.Desai@Sun.COM sinfo.si_xa = xa;
30810504SKeyur.Desai@Sun.COM sinfo.si_infolev = infolev;
30910504SKeyur.Desai@Sun.COM sinfo.si_node = node;
31010504SKeyur.Desai@Sun.COM rc = smb_set_fileinfo(sr, &sinfo);
31110504SKeyur.Desai@Sun.COM
31210504SKeyur.Desai@Sun.COM smb_node_release(node);
31310504SKeyur.Desai@Sun.COM return (rc);
31410504SKeyur.Desai@Sun.COM }
31510504SKeyur.Desai@Sun.COM
31610504SKeyur.Desai@Sun.COM /*
31710504SKeyur.Desai@Sun.COM * smb_set_fileinfo
31810966SJordan.Brown@Sun.COM *
31910966SJordan.Brown@Sun.COM * For compatibility with windows servers, SMB_FILE_LINK_INFORMATION
32010966SJordan.Brown@Sun.COM * is handled by returning NT_STATUS_NOT_SUPPORTED.
32110504SKeyur.Desai@Sun.COM */
32210504SKeyur.Desai@Sun.COM static int
smb_set_fileinfo(smb_request_t * sr,smb_setinfo_t * sinfo)32310504SKeyur.Desai@Sun.COM smb_set_fileinfo(smb_request_t *sr, smb_setinfo_t *sinfo)
32410504SKeyur.Desai@Sun.COM {
32510504SKeyur.Desai@Sun.COM switch (sinfo->si_infolev) {
32610504SKeyur.Desai@Sun.COM case SMB_SET_INFORMATION:
32710504SKeyur.Desai@Sun.COM return (smb_set_information(sr, sinfo));
32810504SKeyur.Desai@Sun.COM
32910504SKeyur.Desai@Sun.COM case SMB_SET_INFORMATION2:
33010504SKeyur.Desai@Sun.COM return (smb_set_information2(sr, sinfo));
33110504SKeyur.Desai@Sun.COM
33210504SKeyur.Desai@Sun.COM case SMB_INFO_STANDARD:
33310504SKeyur.Desai@Sun.COM return (smb_set_standard_info(sr, sinfo));
33410504SKeyur.Desai@Sun.COM
33510504SKeyur.Desai@Sun.COM case SMB_INFO_SET_EAS:
33610504SKeyur.Desai@Sun.COM /* EAs not supported */
33710504SKeyur.Desai@Sun.COM return (0);
33810504SKeyur.Desai@Sun.COM
33910504SKeyur.Desai@Sun.COM case SMB_SET_FILE_BASIC_INFO:
34010504SKeyur.Desai@Sun.COM case SMB_FILE_BASIC_INFORMATION:
34110504SKeyur.Desai@Sun.COM return (smb_set_basic_info(sr, sinfo));
34210504SKeyur.Desai@Sun.COM
34310504SKeyur.Desai@Sun.COM case SMB_SET_FILE_DISPOSITION_INFO:
34410504SKeyur.Desai@Sun.COM case SMB_FILE_DISPOSITION_INFORMATION:
34510504SKeyur.Desai@Sun.COM return (smb_set_disposition_info(sr, sinfo));
34610504SKeyur.Desai@Sun.COM
34710504SKeyur.Desai@Sun.COM case SMB_SET_FILE_END_OF_FILE_INFO:
34810504SKeyur.Desai@Sun.COM case SMB_FILE_END_OF_FILE_INFORMATION:
34910504SKeyur.Desai@Sun.COM return (smb_set_eof_info(sr, sinfo));
35010504SKeyur.Desai@Sun.COM
35110504SKeyur.Desai@Sun.COM case SMB_SET_FILE_ALLOCATION_INFO:
35210504SKeyur.Desai@Sun.COM case SMB_FILE_ALLOCATION_INFORMATION:
35310504SKeyur.Desai@Sun.COM return (smb_set_alloc_info(sr, sinfo));
35410504SKeyur.Desai@Sun.COM
35510966SJordan.Brown@Sun.COM case SMB_FILE_RENAME_INFORMATION:
35610966SJordan.Brown@Sun.COM return (smb_set_rename_info(sr, sinfo));
35710966SJordan.Brown@Sun.COM
35810966SJordan.Brown@Sun.COM case SMB_FILE_LINK_INFORMATION:
35910966SJordan.Brown@Sun.COM smbsr_error(sr, NT_STATUS_NOT_SUPPORTED,
36010966SJordan.Brown@Sun.COM ERRDOS, ERROR_NOT_SUPPORTED);
36110966SJordan.Brown@Sun.COM return (-1);
36210504SKeyur.Desai@Sun.COM default:
36310504SKeyur.Desai@Sun.COM break;
36410504SKeyur.Desai@Sun.COM }
36510504SKeyur.Desai@Sun.COM
36610504SKeyur.Desai@Sun.COM smbsr_error(sr, NT_STATUS_INVALID_INFO_CLASS,
36710504SKeyur.Desai@Sun.COM ERRDOS, ERROR_INVALID_PARAMETER);
36810504SKeyur.Desai@Sun.COM return (-1);
36910504SKeyur.Desai@Sun.COM }
37010504SKeyur.Desai@Sun.COM
37110504SKeyur.Desai@Sun.COM /*
37210504SKeyur.Desai@Sun.COM * smb_set_information
37310504SKeyur.Desai@Sun.COM *
37410504SKeyur.Desai@Sun.COM * It is not valid to set FILE_ATTRIBUTE_DIRECTORY if the
37510504SKeyur.Desai@Sun.COM * target is not a directory.
37610504SKeyur.Desai@Sun.COM *
37710504SKeyur.Desai@Sun.COM * For compatibility with Windows Servers, if the specified
37810504SKeyur.Desai@Sun.COM * attributes have ONLY FILE_ATTRIBUTE_NORMAL set do NOT change
37910504SKeyur.Desai@Sun.COM * the file's attributes.
38010504SKeyur.Desai@Sun.COM */
38110504SKeyur.Desai@Sun.COM static int
smb_set_information(smb_request_t * sr,smb_setinfo_t * sinfo)38210504SKeyur.Desai@Sun.COM smb_set_information(smb_request_t *sr, smb_setinfo_t *sinfo)
38310504SKeyur.Desai@Sun.COM {
38410504SKeyur.Desai@Sun.COM int rc;
38510504SKeyur.Desai@Sun.COM uint16_t attributes;
38610504SKeyur.Desai@Sun.COM smb_node_t *node = sinfo->si_node;
38710504SKeyur.Desai@Sun.COM smb_attr_t attr;
38810504SKeyur.Desai@Sun.COM uint32_t mtime;
38910504SKeyur.Desai@Sun.COM
39010504SKeyur.Desai@Sun.COM if (smbsr_decode_vwv(sr, "wl10.", &attributes, &mtime) != 0)
39110504SKeyur.Desai@Sun.COM return (-1);
39210504SKeyur.Desai@Sun.COM
39310504SKeyur.Desai@Sun.COM if ((attributes & FILE_ATTRIBUTE_DIRECTORY) &&
39410504SKeyur.Desai@Sun.COM (!smb_node_is_dir(node))) {
39510504SKeyur.Desai@Sun.COM smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
39610504SKeyur.Desai@Sun.COM ERRDOS, ERROR_INVALID_PARAMETER);
39710504SKeyur.Desai@Sun.COM return (-1);
39810504SKeyur.Desai@Sun.COM }
39910504SKeyur.Desai@Sun.COM
40010504SKeyur.Desai@Sun.COM bzero(&attr, sizeof (smb_attr_t));
40110504SKeyur.Desai@Sun.COM if (attributes != FILE_ATTRIBUTE_NORMAL) {
40210504SKeyur.Desai@Sun.COM attr.sa_dosattr = attributes;
40310504SKeyur.Desai@Sun.COM attr.sa_mask |= SMB_AT_DOSATTR;
40410504SKeyur.Desai@Sun.COM }
40510504SKeyur.Desai@Sun.COM
40610504SKeyur.Desai@Sun.COM if (mtime != 0 && mtime != UINT_MAX) {
40710504SKeyur.Desai@Sun.COM attr.sa_vattr.va_mtime.tv_sec =
40810504SKeyur.Desai@Sun.COM smb_time_local_to_gmt(sr, mtime);
40910504SKeyur.Desai@Sun.COM attr.sa_mask |= SMB_AT_MTIME;
41010504SKeyur.Desai@Sun.COM }
41110504SKeyur.Desai@Sun.COM
41210504SKeyur.Desai@Sun.COM rc = smb_node_setattr(sr, node, sr->user_cr, NULL, &attr);
41310504SKeyur.Desai@Sun.COM if (rc != 0) {
41410504SKeyur.Desai@Sun.COM smbsr_errno(sr, rc);
41510504SKeyur.Desai@Sun.COM return (-1);
41610504SKeyur.Desai@Sun.COM }
41710504SKeyur.Desai@Sun.COM
41810504SKeyur.Desai@Sun.COM return (0);
41910504SKeyur.Desai@Sun.COM }
42010504SKeyur.Desai@Sun.COM
42110504SKeyur.Desai@Sun.COM /*
42210504SKeyur.Desai@Sun.COM * smb_set_information2
42310504SKeyur.Desai@Sun.COM */
42410504SKeyur.Desai@Sun.COM static int
smb_set_information2(smb_request_t * sr,smb_setinfo_t * sinfo)42510504SKeyur.Desai@Sun.COM smb_set_information2(smb_request_t *sr, smb_setinfo_t *sinfo)
42610504SKeyur.Desai@Sun.COM {
42710504SKeyur.Desai@Sun.COM int rc;
42810504SKeyur.Desai@Sun.COM uint32_t crtime, atime, mtime;
42910504SKeyur.Desai@Sun.COM smb_attr_t attr;
43010504SKeyur.Desai@Sun.COM
43110504SKeyur.Desai@Sun.COM if (smbsr_decode_vwv(sr, "yyy", &crtime, &atime, &mtime) != 0)
43210504SKeyur.Desai@Sun.COM return (-1);
43310504SKeyur.Desai@Sun.COM
43410504SKeyur.Desai@Sun.COM bzero(&attr, sizeof (smb_attr_t));
43510504SKeyur.Desai@Sun.COM if (mtime != 0 && mtime != UINT_MAX) {
43610504SKeyur.Desai@Sun.COM attr.sa_vattr.va_mtime.tv_sec =
43710504SKeyur.Desai@Sun.COM smb_time_local_to_gmt(sr, mtime);
43810504SKeyur.Desai@Sun.COM attr.sa_mask |= SMB_AT_MTIME;
43910504SKeyur.Desai@Sun.COM }
44010504SKeyur.Desai@Sun.COM
44110504SKeyur.Desai@Sun.COM if (crtime != 0 && crtime != UINT_MAX) {
44210504SKeyur.Desai@Sun.COM attr.sa_crtime.tv_sec = smb_time_local_to_gmt(sr, crtime);
44310504SKeyur.Desai@Sun.COM attr.sa_mask |= SMB_AT_CRTIME;
44410504SKeyur.Desai@Sun.COM }
44510504SKeyur.Desai@Sun.COM
44610504SKeyur.Desai@Sun.COM if (atime != 0 && atime != UINT_MAX) {
44710504SKeyur.Desai@Sun.COM attr.sa_vattr.va_atime.tv_sec =
44810504SKeyur.Desai@Sun.COM smb_time_local_to_gmt(sr, atime);
44910504SKeyur.Desai@Sun.COM attr.sa_mask |= SMB_AT_ATIME;
45010504SKeyur.Desai@Sun.COM }
45110504SKeyur.Desai@Sun.COM
45210504SKeyur.Desai@Sun.COM rc = smb_node_setattr(sr, sinfo->si_node, sr->user_cr,
45310504SKeyur.Desai@Sun.COM sr->fid_ofile, &attr);
45410504SKeyur.Desai@Sun.COM if (rc != 0) {
45510504SKeyur.Desai@Sun.COM smbsr_errno(sr, rc);
45610504SKeyur.Desai@Sun.COM return (-1);
45710504SKeyur.Desai@Sun.COM }
45810504SKeyur.Desai@Sun.COM
45910504SKeyur.Desai@Sun.COM return (0);
46010504SKeyur.Desai@Sun.COM }
46110504SKeyur.Desai@Sun.COM
46210504SKeyur.Desai@Sun.COM /*
46310504SKeyur.Desai@Sun.COM * smb_set_standard_info
46410504SKeyur.Desai@Sun.COM *
46510504SKeyur.Desai@Sun.COM * Sets standard file/path information.
46610504SKeyur.Desai@Sun.COM */
46710504SKeyur.Desai@Sun.COM static int
smb_set_standard_info(smb_request_t * sr,smb_setinfo_t * sinfo)46810504SKeyur.Desai@Sun.COM smb_set_standard_info(smb_request_t *sr, smb_setinfo_t *sinfo)
46910504SKeyur.Desai@Sun.COM {
47010504SKeyur.Desai@Sun.COM smb_attr_t attr;
47110504SKeyur.Desai@Sun.COM uint32_t crtime, atime, mtime;
47210504SKeyur.Desai@Sun.COM smb_node_t *node = sinfo->si_node;
47310504SKeyur.Desai@Sun.COM int rc;
47410504SKeyur.Desai@Sun.COM
47510504SKeyur.Desai@Sun.COM if (smb_mbc_decodef(&sinfo->si_xa->req_data_mb, "yyy",
47610504SKeyur.Desai@Sun.COM &crtime, &atime, &mtime) != 0) {
47710504SKeyur.Desai@Sun.COM return (-1);
47810504SKeyur.Desai@Sun.COM }
47910504SKeyur.Desai@Sun.COM
48010504SKeyur.Desai@Sun.COM bzero(&attr, sizeof (smb_attr_t));
48110504SKeyur.Desai@Sun.COM if (mtime != 0 && mtime != (uint32_t)-1) {
48210504SKeyur.Desai@Sun.COM attr.sa_vattr.va_mtime.tv_sec =
48310504SKeyur.Desai@Sun.COM smb_time_local_to_gmt(sr, mtime);
48410504SKeyur.Desai@Sun.COM attr.sa_mask |= SMB_AT_MTIME;
48510504SKeyur.Desai@Sun.COM }
48610504SKeyur.Desai@Sun.COM
48710504SKeyur.Desai@Sun.COM if (crtime != 0 && crtime != (uint32_t)-1) {
48810504SKeyur.Desai@Sun.COM attr.sa_crtime.tv_sec = smb_time_local_to_gmt(sr, crtime);
48910504SKeyur.Desai@Sun.COM attr.sa_mask |= SMB_AT_CRTIME;
49010504SKeyur.Desai@Sun.COM }
49110504SKeyur.Desai@Sun.COM
49210504SKeyur.Desai@Sun.COM if (atime != 0 && atime != (uint32_t)-1) {
49310504SKeyur.Desai@Sun.COM attr.sa_vattr.va_atime.tv_sec =
49410504SKeyur.Desai@Sun.COM smb_time_local_to_gmt(sr, atime);
49510504SKeyur.Desai@Sun.COM attr.sa_mask |= SMB_AT_ATIME;
49610504SKeyur.Desai@Sun.COM }
49710504SKeyur.Desai@Sun.COM
49810504SKeyur.Desai@Sun.COM rc = smb_node_setattr(sr, node, sr->user_cr, sr->fid_ofile, &attr);
49910504SKeyur.Desai@Sun.COM if (rc != 0) {
50010504SKeyur.Desai@Sun.COM smbsr_errno(sr, rc);
50110504SKeyur.Desai@Sun.COM return (-1);
50210504SKeyur.Desai@Sun.COM }
50310504SKeyur.Desai@Sun.COM
50410504SKeyur.Desai@Sun.COM return (0);
50510504SKeyur.Desai@Sun.COM }
50610504SKeyur.Desai@Sun.COM
50710504SKeyur.Desai@Sun.COM /*
50810504SKeyur.Desai@Sun.COM * smb_set_basic_info
50910504SKeyur.Desai@Sun.COM *
51010504SKeyur.Desai@Sun.COM * Sets basic file/path information.
51110504SKeyur.Desai@Sun.COM *
51210504SKeyur.Desai@Sun.COM * It is not valid to set FILE_ATTRIBUTE_DIRECTORY if the
51310504SKeyur.Desai@Sun.COM * target is not a directory.
51410504SKeyur.Desai@Sun.COM *
51510504SKeyur.Desai@Sun.COM * For compatibility with windows servers:
51610504SKeyur.Desai@Sun.COM * - if the specified attributes have ONLY FILE_ATTRIBUTE_NORMAL set
51710504SKeyur.Desai@Sun.COM * clear (0) the file's attributes.
51810504SKeyur.Desai@Sun.COM * - if the specified attributes are 0 do NOT change the file's attributes.
51910504SKeyur.Desai@Sun.COM */
52010504SKeyur.Desai@Sun.COM static int
smb_set_basic_info(smb_request_t * sr,smb_setinfo_t * sinfo)52110504SKeyur.Desai@Sun.COM smb_set_basic_info(smb_request_t *sr, smb_setinfo_t *sinfo)
52210504SKeyur.Desai@Sun.COM {
52310504SKeyur.Desai@Sun.COM int rc;
52410504SKeyur.Desai@Sun.COM uint64_t crtime, atime, mtime, ctime;
52510504SKeyur.Desai@Sun.COM uint16_t attributes;
52610504SKeyur.Desai@Sun.COM smb_attr_t attr;
52710504SKeyur.Desai@Sun.COM smb_node_t *node = sinfo->si_node;
52810504SKeyur.Desai@Sun.COM
52910504SKeyur.Desai@Sun.COM if (smb_mbc_decodef(&sinfo->si_xa->req_data_mb, "qqqqw",
53010504SKeyur.Desai@Sun.COM &crtime, &atime, &mtime, &ctime, &attributes) != 0) {
53110504SKeyur.Desai@Sun.COM return (-1);
53210504SKeyur.Desai@Sun.COM }
53310504SKeyur.Desai@Sun.COM
53410504SKeyur.Desai@Sun.COM if ((attributes & FILE_ATTRIBUTE_DIRECTORY) &&
53510504SKeyur.Desai@Sun.COM (!smb_node_is_dir(node))) {
53610504SKeyur.Desai@Sun.COM smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
53710504SKeyur.Desai@Sun.COM ERRDOS, ERROR_INVALID_PARAMETER);
53810504SKeyur.Desai@Sun.COM return (-1);
53910504SKeyur.Desai@Sun.COM }
54010504SKeyur.Desai@Sun.COM
54110504SKeyur.Desai@Sun.COM bzero(&attr, sizeof (smb_attr_t));
54210504SKeyur.Desai@Sun.COM if (ctime != 0 && ctime != (uint64_t)-1) {
54310504SKeyur.Desai@Sun.COM smb_time_nt_to_unix(ctime, &attr.sa_vattr.va_ctime);
54410504SKeyur.Desai@Sun.COM attr.sa_mask |= SMB_AT_CTIME;
54510504SKeyur.Desai@Sun.COM }
54610504SKeyur.Desai@Sun.COM
54710504SKeyur.Desai@Sun.COM if (crtime != 0 && crtime != (uint64_t)-1) {
54810504SKeyur.Desai@Sun.COM smb_time_nt_to_unix(crtime, &attr.sa_crtime);
54910504SKeyur.Desai@Sun.COM attr.sa_mask |= SMB_AT_CRTIME;
55010504SKeyur.Desai@Sun.COM }
55110504SKeyur.Desai@Sun.COM
55210504SKeyur.Desai@Sun.COM if (mtime != 0 && mtime != (uint64_t)-1) {
55310504SKeyur.Desai@Sun.COM smb_time_nt_to_unix(mtime, &attr.sa_vattr.va_mtime);
55410504SKeyur.Desai@Sun.COM attr.sa_mask |= SMB_AT_MTIME;
55510504SKeyur.Desai@Sun.COM }
55610504SKeyur.Desai@Sun.COM
55710504SKeyur.Desai@Sun.COM if (atime != 0 && atime != (uint64_t)-1) {
55810504SKeyur.Desai@Sun.COM smb_time_nt_to_unix(atime, &attr.sa_vattr.va_atime);
55910504SKeyur.Desai@Sun.COM attr.sa_mask |= SMB_AT_ATIME;
56010504SKeyur.Desai@Sun.COM }
56110504SKeyur.Desai@Sun.COM
56210504SKeyur.Desai@Sun.COM if (attributes != 0) {
56310504SKeyur.Desai@Sun.COM attr.sa_dosattr = attributes;
56410504SKeyur.Desai@Sun.COM attr.sa_mask |= SMB_AT_DOSATTR;
56510504SKeyur.Desai@Sun.COM }
56610504SKeyur.Desai@Sun.COM
56710504SKeyur.Desai@Sun.COM rc = smb_node_setattr(sr, node, sr->user_cr, sr->fid_ofile, &attr);
56810504SKeyur.Desai@Sun.COM if (rc != 0) {
56910504SKeyur.Desai@Sun.COM smbsr_errno(sr, rc);
57010504SKeyur.Desai@Sun.COM return (-1);
57110504SKeyur.Desai@Sun.COM }
57210504SKeyur.Desai@Sun.COM
57310504SKeyur.Desai@Sun.COM return (0);
57410504SKeyur.Desai@Sun.COM }
57510504SKeyur.Desai@Sun.COM
57610504SKeyur.Desai@Sun.COM /*
57710504SKeyur.Desai@Sun.COM * smb_set_eof_info
57810504SKeyur.Desai@Sun.COM */
57910504SKeyur.Desai@Sun.COM static int
smb_set_eof_info(smb_request_t * sr,smb_setinfo_t * sinfo)58010504SKeyur.Desai@Sun.COM smb_set_eof_info(smb_request_t *sr, smb_setinfo_t *sinfo)
58110504SKeyur.Desai@Sun.COM {
58210504SKeyur.Desai@Sun.COM int rc;
58310504SKeyur.Desai@Sun.COM smb_attr_t attr;
58410504SKeyur.Desai@Sun.COM uint64_t eof;
58510504SKeyur.Desai@Sun.COM smb_node_t *node = sinfo->si_node;
58610504SKeyur.Desai@Sun.COM
58710504SKeyur.Desai@Sun.COM if (smb_mbc_decodef(&sinfo->si_xa->req_data_mb, "q", &eof) != 0)
58810504SKeyur.Desai@Sun.COM return (-1);
58910504SKeyur.Desai@Sun.COM
59010504SKeyur.Desai@Sun.COM if (smb_node_is_dir(node)) {
59110504SKeyur.Desai@Sun.COM smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
59210504SKeyur.Desai@Sun.COM ERRDOS, ERROR_INVALID_PARAMETER);
59310504SKeyur.Desai@Sun.COM return (-1);
59410504SKeyur.Desai@Sun.COM }
59510504SKeyur.Desai@Sun.COM
596*12890SJoyce.McIntosh@Sun.COM /* If opened by path, break exclusive oplock */
597*12890SJoyce.McIntosh@Sun.COM if (sr->fid_ofile == NULL)
598*12890SJoyce.McIntosh@Sun.COM (void) smb_oplock_break(sr, node,
599*12890SJoyce.McIntosh@Sun.COM SMB_OPLOCK_BREAK_EXCLUSIVE | SMB_OPLOCK_BREAK_TO_NONE);
600*12890SJoyce.McIntosh@Sun.COM
60110504SKeyur.Desai@Sun.COM bzero(&attr, sizeof (smb_attr_t));
60210504SKeyur.Desai@Sun.COM attr.sa_mask = SMB_AT_SIZE;
60310504SKeyur.Desai@Sun.COM attr.sa_vattr.va_size = (u_offset_t)eof;
60410504SKeyur.Desai@Sun.COM rc = smb_node_setattr(sr, node, sr->user_cr, sr->fid_ofile, &attr);
60510504SKeyur.Desai@Sun.COM if (rc != 0) {
60610504SKeyur.Desai@Sun.COM smbsr_errno(sr, rc);
60710504SKeyur.Desai@Sun.COM return (-1);
60810504SKeyur.Desai@Sun.COM }
60910504SKeyur.Desai@Sun.COM
610*12890SJoyce.McIntosh@Sun.COM smb_oplock_break_levelII(node);
61110504SKeyur.Desai@Sun.COM return (0);
61210504SKeyur.Desai@Sun.COM }
61310504SKeyur.Desai@Sun.COM
61410504SKeyur.Desai@Sun.COM /*
61510504SKeyur.Desai@Sun.COM * smb_set_alloc_info
61610504SKeyur.Desai@Sun.COM */
61710504SKeyur.Desai@Sun.COM static int
smb_set_alloc_info(smb_request_t * sr,smb_setinfo_t * sinfo)61810504SKeyur.Desai@Sun.COM smb_set_alloc_info(smb_request_t *sr, smb_setinfo_t *sinfo)
61910504SKeyur.Desai@Sun.COM {
62010504SKeyur.Desai@Sun.COM int rc;
62110504SKeyur.Desai@Sun.COM smb_attr_t attr;
62210504SKeyur.Desai@Sun.COM uint64_t allocsz;
62310504SKeyur.Desai@Sun.COM smb_node_t *node = sinfo->si_node;
62410504SKeyur.Desai@Sun.COM
62510504SKeyur.Desai@Sun.COM if (smb_mbc_decodef(&sinfo->si_xa->req_data_mb, "q", &allocsz) != 0)
62610504SKeyur.Desai@Sun.COM return (-1);
62710504SKeyur.Desai@Sun.COM
62810504SKeyur.Desai@Sun.COM if (smb_node_is_dir(node)) {
62910504SKeyur.Desai@Sun.COM smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
63010504SKeyur.Desai@Sun.COM ERRDOS, ERROR_INVALID_PARAMETER);
63110504SKeyur.Desai@Sun.COM return (-1);
63210504SKeyur.Desai@Sun.COM }
63310504SKeyur.Desai@Sun.COM
634*12890SJoyce.McIntosh@Sun.COM /* If opened by path, break exclusive oplock */
635*12890SJoyce.McIntosh@Sun.COM if (sr->fid_ofile == NULL)
636*12890SJoyce.McIntosh@Sun.COM (void) smb_oplock_break(sr, node,
637*12890SJoyce.McIntosh@Sun.COM SMB_OPLOCK_BREAK_EXCLUSIVE | SMB_OPLOCK_BREAK_TO_NONE);
638*12890SJoyce.McIntosh@Sun.COM
63910504SKeyur.Desai@Sun.COM bzero(&attr, sizeof (smb_attr_t));
64010504SKeyur.Desai@Sun.COM attr.sa_mask = SMB_AT_ALLOCSZ;
64110504SKeyur.Desai@Sun.COM attr.sa_allocsz = (u_offset_t)allocsz;
64210504SKeyur.Desai@Sun.COM rc = smb_node_setattr(sr, node, sr->user_cr, sr->fid_ofile, &attr);
64310504SKeyur.Desai@Sun.COM if (rc != 0) {
64410504SKeyur.Desai@Sun.COM smbsr_errno(sr, rc);
64510504SKeyur.Desai@Sun.COM return (-1);
64610504SKeyur.Desai@Sun.COM }
64710504SKeyur.Desai@Sun.COM
648*12890SJoyce.McIntosh@Sun.COM smb_oplock_break_levelII(node);
64910504SKeyur.Desai@Sun.COM return (0);
65010504SKeyur.Desai@Sun.COM }
65110504SKeyur.Desai@Sun.COM
65210504SKeyur.Desai@Sun.COM /*
65310504SKeyur.Desai@Sun.COM * smb_set_disposition_info
65410504SKeyur.Desai@Sun.COM *
65510504SKeyur.Desai@Sun.COM * Set/Clear DELETE_ON_CLOSE flag for an open file.
65610504SKeyur.Desai@Sun.COM * File should have been opened with DELETE access otherwise
65710504SKeyur.Desai@Sun.COM * the operation is not permitted.
65810504SKeyur.Desai@Sun.COM *
65910504SKeyur.Desai@Sun.COM * NOTE: The node should be marked delete-on-close upon the receipt
66010504SKeyur.Desai@Sun.COM * of the Trans2SetFileInfo(SetDispositionInfo) if mark_delete is set.
66110504SKeyur.Desai@Sun.COM * It is different than both SmbNtCreateAndX and SmbNtTransact, which
66210504SKeyur.Desai@Sun.COM * set delete-on-close on the ofile and defer setting the flag on the
66310504SKeyur.Desai@Sun.COM * node until the file is closed.
66410504SKeyur.Desai@Sun.COM *
66510504SKeyur.Desai@Sun.COM * Observation of Windows 2000 indicates the following:
66610504SKeyur.Desai@Sun.COM *
66710504SKeyur.Desai@Sun.COM * 1) If a file is not opened with delete-on-close create options and
66810504SKeyur.Desai@Sun.COM * the delete-on-close is set via Trans2SetFileInfo(SetDispositionInfo)
66910504SKeyur.Desai@Sun.COM * using that open file handle, any subsequent open requests will fail
67010504SKeyur.Desai@Sun.COM * with DELETE_PENDING.
67110504SKeyur.Desai@Sun.COM *
67210504SKeyur.Desai@Sun.COM * 2) If a file is opened with delete-on-close create options and the
67310504SKeyur.Desai@Sun.COM * client attempts to unset delete-on-close via Trans2SetFileInfo
67410504SKeyur.Desai@Sun.COM * (SetDispositionInfo) prior to the file close, any subsequent open
67510504SKeyur.Desai@Sun.COM * requests will still fail with DELETE_PENDING after the file is closed.
67610504SKeyur.Desai@Sun.COM *
67710504SKeyur.Desai@Sun.COM * 3) If a file is opened with delete-on-close create options and that
67810504SKeyur.Desai@Sun.COM * file handle (not the last open handle and the only file handle
67910504SKeyur.Desai@Sun.COM * with delete-on-close set) is closed. Any subsequent open requests
68010504SKeyur.Desai@Sun.COM * will fail with DELETE_PENDING. Unsetting delete-on-close via
68110504SKeyur.Desai@Sun.COM * Trans2SetFileInfo(SetDispositionInfo) at this time will unset the
68210504SKeyur.Desai@Sun.COM * node delete-on-close flag, which will result in the file not being
68310504SKeyur.Desai@Sun.COM * removed even after the last file handle is closed.
68410504SKeyur.Desai@Sun.COM */
68510504SKeyur.Desai@Sun.COM static int
smb_set_disposition_info(smb_request_t * sr,smb_setinfo_t * sinfo)68610504SKeyur.Desai@Sun.COM smb_set_disposition_info(smb_request_t *sr, smb_setinfo_t *sinfo)
68710504SKeyur.Desai@Sun.COM {
68810504SKeyur.Desai@Sun.COM unsigned char mark_delete;
68910504SKeyur.Desai@Sun.COM uint32_t flags = 0;
69010504SKeyur.Desai@Sun.COM
69110504SKeyur.Desai@Sun.COM if (smb_mbc_decodef(&sinfo->si_xa->req_data_mb, "b", &mark_delete) != 0)
69210504SKeyur.Desai@Sun.COM return (-1);
69310504SKeyur.Desai@Sun.COM
69410504SKeyur.Desai@Sun.COM if ((sr->fid_ofile == NULL) ||
69510504SKeyur.Desai@Sun.COM !(smb_ofile_granted_access(sr->fid_ofile) & DELETE)) {
69610504SKeyur.Desai@Sun.COM smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
69710504SKeyur.Desai@Sun.COM ERRDOS, ERROR_ACCESS_DENIED);
69810504SKeyur.Desai@Sun.COM return (-1);
69910504SKeyur.Desai@Sun.COM }
70010504SKeyur.Desai@Sun.COM
70110504SKeyur.Desai@Sun.COM if (mark_delete) {
70210504SKeyur.Desai@Sun.COM if (SMB_TREE_SUPPORTS_CATIA(sr))
70310504SKeyur.Desai@Sun.COM flags |= SMB_CATIA;
70410504SKeyur.Desai@Sun.COM
70510504SKeyur.Desai@Sun.COM if (smb_node_set_delete_on_close(sinfo->si_node,
70610504SKeyur.Desai@Sun.COM sr->user_cr, flags)) {
70710504SKeyur.Desai@Sun.COM smbsr_error(sr, NT_STATUS_CANNOT_DELETE,
70810504SKeyur.Desai@Sun.COM ERRDOS, ERROR_ACCESS_DENIED);
70910504SKeyur.Desai@Sun.COM return (-1);
71010504SKeyur.Desai@Sun.COM }
71110504SKeyur.Desai@Sun.COM } else {
71210504SKeyur.Desai@Sun.COM smb_node_reset_delete_on_close(sinfo->si_node);
71310504SKeyur.Desai@Sun.COM }
71410504SKeyur.Desai@Sun.COM return (0);
71510504SKeyur.Desai@Sun.COM }
71610966SJordan.Brown@Sun.COM
71710966SJordan.Brown@Sun.COM /*
71810966SJordan.Brown@Sun.COM * smb_set_rename_info
71910966SJordan.Brown@Sun.COM *
720*12890SJoyce.McIntosh@Sun.COM * Explicitly specified parameter validation rules:
72110966SJordan.Brown@Sun.COM * - If rootdir is not NULL respond with NT_STATUS_INVALID_PARAMETER.
72210966SJordan.Brown@Sun.COM * - If the filename contains a separator character respond with
72310966SJordan.Brown@Sun.COM * NT_STATUS_INVALID_PARAMETER.
724*12890SJoyce.McIntosh@Sun.COM *
725*12890SJoyce.McIntosh@Sun.COM * Oplock break:
726*12890SJoyce.McIntosh@Sun.COM * Some Windows servers break BATCH oplocks prior to the rename.
727*12890SJoyce.McIntosh@Sun.COM * W2K3 does not. We behave as W2K3; we do not send an oplock break.
72810966SJordan.Brown@Sun.COM */
72910966SJordan.Brown@Sun.COM static int
smb_set_rename_info(smb_request_t * sr,smb_setinfo_t * sinfo)73010966SJordan.Brown@Sun.COM smb_set_rename_info(smb_request_t *sr, smb_setinfo_t *sinfo)
73110966SJordan.Brown@Sun.COM {
73210966SJordan.Brown@Sun.COM int rc;
73310966SJordan.Brown@Sun.COM uint32_t flags, rootdir, namelen;
73410966SJordan.Brown@Sun.COM char *fname;
73510966SJordan.Brown@Sun.COM
73610966SJordan.Brown@Sun.COM rc = smb_mbc_decodef(&sinfo->si_xa->req_data_mb, "lll",
73710966SJordan.Brown@Sun.COM &flags, &rootdir, &namelen);
73810966SJordan.Brown@Sun.COM if (rc == 0) {
73910966SJordan.Brown@Sun.COM rc = smb_mbc_decodef(&sinfo->si_xa->req_data_mb, "%#U",
74010966SJordan.Brown@Sun.COM sr, namelen, &fname);
74110966SJordan.Brown@Sun.COM }
74210966SJordan.Brown@Sun.COM if (rc != 0)
74310966SJordan.Brown@Sun.COM return (-1);
74410966SJordan.Brown@Sun.COM
74510966SJordan.Brown@Sun.COM if ((rootdir != 0) || (namelen == 0) || (namelen >= MAXNAMELEN)) {
74610966SJordan.Brown@Sun.COM smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
74710966SJordan.Brown@Sun.COM ERRDOS, ERROR_INVALID_PARAMETER);
74810966SJordan.Brown@Sun.COM return (-1);
74910966SJordan.Brown@Sun.COM }
75010966SJordan.Brown@Sun.COM
75110966SJordan.Brown@Sun.COM if (strchr(fname, '\\') != NULL) {
75210966SJordan.Brown@Sun.COM smbsr_error(sr, NT_STATUS_NOT_SUPPORTED,
75310966SJordan.Brown@Sun.COM ERRDOS, ERROR_NOT_SUPPORTED);
75410966SJordan.Brown@Sun.COM return (-1);
75510966SJordan.Brown@Sun.COM }
75610966SJordan.Brown@Sun.COM
75710966SJordan.Brown@Sun.COM rc = smb_trans2_rename(sr, sinfo->si_node, fname, flags);
75810966SJordan.Brown@Sun.COM
75910966SJordan.Brown@Sun.COM return ((rc == 0) ? 0 : -1);
76010966SJordan.Brown@Sun.COM }
761