1a90cf9f2SGordon Ross /*
2a90cf9f2SGordon Ross  * This file and its contents are supplied under the terms of the
3a90cf9f2SGordon Ross  * Common Development and Distribution License ("CDDL"), version 1.0.
4a90cf9f2SGordon Ross  * You may only use this file in accordance with the terms of version
5a90cf9f2SGordon Ross  * 1.0 of the CDDL.
6a90cf9f2SGordon Ross  *
7a90cf9f2SGordon Ross  * A full copy of the text of the CDDL should have accompanied this
8a90cf9f2SGordon Ross  * source.  A copy of the CDDL is also available via the Internet at
9a90cf9f2SGordon Ross  * http://www.illumos.org/license/CDDL.
10a90cf9f2SGordon Ross  */
11a90cf9f2SGordon Ross 
12a90cf9f2SGordon Ross /*
13*93bc28dbSGordon Ross  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
14a90cf9f2SGordon Ross  */
15a90cf9f2SGordon Ross 
16a90cf9f2SGordon Ross /*
17a90cf9f2SGordon Ross  * Dispatch function for SMB2_SET_INFO
18a90cf9f2SGordon Ross  */
19a90cf9f2SGordon Ross 
20a90cf9f2SGordon Ross #include <smbsrv/smb2_kproto.h>
21a90cf9f2SGordon Ross #include <smbsrv/smb_fsops.h>
22a90cf9f2SGordon Ross #include <smbsrv/ntifs.h>
23a90cf9f2SGordon Ross 
24a90cf9f2SGordon Ross smb_sdrc_t
smb2_set_info(smb_request_t * sr)25a90cf9f2SGordon Ross smb2_set_info(smb_request_t *sr)
26a90cf9f2SGordon Ross {
27a90cf9f2SGordon Ross 	smb_setinfo_t sinfo;
28a90cf9f2SGordon Ross 	uint16_t StructSize;
29a90cf9f2SGordon Ross 	uint16_t iBufOffset;
30a90cf9f2SGordon Ross 	uint32_t iBufLength;
31a90cf9f2SGordon Ross 	uint32_t AddlInfo;
32a90cf9f2SGordon Ross 	smb2fid_t smb2fid;
33a90cf9f2SGordon Ross 	uint32_t status;
34a90cf9f2SGordon Ross 	uint8_t InfoType, InfoClass;
35a90cf9f2SGordon Ross 	int rc = 0;
36a90cf9f2SGordon Ross 
37a90cf9f2SGordon Ross 	bzero(&sinfo, sizeof (sinfo));
38a90cf9f2SGordon Ross 
39a90cf9f2SGordon Ross 	/*
40*93bc28dbSGordon Ross 	 * Decode SMB2 Set Info request
41a90cf9f2SGordon Ross 	 */
42a90cf9f2SGordon Ross 	rc = smb_mbc_decodef(
43a90cf9f2SGordon Ross 	    &sr->smb_data, "wbblw..lqq",
44a90cf9f2SGordon Ross 	    &StructSize,		/* w */
45a90cf9f2SGordon Ross 	    &InfoType,			/* b */
46a90cf9f2SGordon Ross 	    &InfoClass,			/* b */
47a90cf9f2SGordon Ross 	    &iBufLength,		/* l */
48a90cf9f2SGordon Ross 	    &iBufOffset,		/* w */
49a90cf9f2SGordon Ross 	    /* reserved			  .. */
50a90cf9f2SGordon Ross 	    &AddlInfo,			/* l */
51a90cf9f2SGordon Ross 	    &smb2fid.persistent,	/* q */
52a90cf9f2SGordon Ross 	    &smb2fid.temporal);		/* q */
53*93bc28dbSGordon Ross 	if (rc || StructSize != 33)
54*93bc28dbSGordon Ross 		return (SDRC_ERROR);
55a90cf9f2SGordon Ross 
56a90cf9f2SGordon Ross 	/*
57a90cf9f2SGordon Ross 	 * If there's an input buffer, setup a shadow.
58a90cf9f2SGordon Ross 	 */
59a90cf9f2SGordon Ross 	if (iBufLength) {
60a90cf9f2SGordon Ross 		rc = MBC_SHADOW_CHAIN(&sinfo.si_data, &sr->smb_data,
61a90cf9f2SGordon Ross 		    sr->smb2_cmd_hdr + iBufOffset, iBufLength);
62a90cf9f2SGordon Ross 		if (rc) {
63*93bc28dbSGordon Ross 			return (SDRC_ERROR);
64a90cf9f2SGordon Ross 		}
65a90cf9f2SGordon Ross 	}
66a90cf9f2SGordon Ross 
67a90cf9f2SGordon Ross 	/* No output data. */
68a90cf9f2SGordon Ross 	sr->raw_data.max_bytes = 0;
69a90cf9f2SGordon Ross 
70*93bc28dbSGordon Ross 	status = smb2sr_lookup_fid(sr, &smb2fid);
71*93bc28dbSGordon Ross 	DTRACE_SMB2_START(op__SetInfo, smb_request_t *, sr);
72*93bc28dbSGordon Ross 
73*93bc28dbSGordon Ross 	if (status)
74*93bc28dbSGordon Ross 		goto errout;
75*93bc28dbSGordon Ross 
76*93bc28dbSGordon Ross 	if (iBufLength > smb2_max_trans) {
77*93bc28dbSGordon Ross 		status = NT_STATUS_INVALID_PARAMETER;
78*93bc28dbSGordon Ross 		goto errout;
79*93bc28dbSGordon Ross 	}
80*93bc28dbSGordon Ross 
81*93bc28dbSGordon Ross 	sinfo.si_node = sr->fid_ofile->f_node;
82*93bc28dbSGordon Ross 	sr->user_cr = sr->fid_ofile->f_cr;
83*93bc28dbSGordon Ross 
84a90cf9f2SGordon Ross 	switch (InfoType) {
85a90cf9f2SGordon Ross 	case SMB2_0_INFO_FILE:
86a90cf9f2SGordon Ross 		status = smb2_setinfo_file(sr, &sinfo, InfoClass);
87a90cf9f2SGordon Ross 		break;
88a90cf9f2SGordon Ross 	case SMB2_0_INFO_FILESYSTEM:
89a90cf9f2SGordon Ross 		status = smb2_setinfo_fs(sr, &sinfo, InfoClass);
90a90cf9f2SGordon Ross 		break;
91a90cf9f2SGordon Ross 	case SMB2_0_INFO_SECURITY:
92a90cf9f2SGordon Ross 		status = smb2_setinfo_sec(sr, &sinfo, AddlInfo);
93a90cf9f2SGordon Ross 		break;
94a90cf9f2SGordon Ross 	case SMB2_0_INFO_QUOTA:
95a90cf9f2SGordon Ross 		status = smb2_setinfo_quota(sr, &sinfo);
96a90cf9f2SGordon Ross 		break;
97a90cf9f2SGordon Ross 	default:
98a90cf9f2SGordon Ross 		status = NT_STATUS_INVALID_PARAMETER;
99a90cf9f2SGordon Ross 		break;
100a90cf9f2SGordon Ross 	}
101a90cf9f2SGordon Ross 
102*93bc28dbSGordon Ross errout:
103*93bc28dbSGordon Ross 	sr->smb2_status = status;
104*93bc28dbSGordon Ross 	DTRACE_SMB2_DONE(op__SetInfo, smb_request_t *, sr);
105*93bc28dbSGordon Ross 
106a90cf9f2SGordon Ross 	if (status) {
107a90cf9f2SGordon Ross 		smb2sr_put_error(sr, status);
108*93bc28dbSGordon Ross 		return (SDRC_SUCCESS);
109a90cf9f2SGordon Ross 	}
110a90cf9f2SGordon Ross 
111a90cf9f2SGordon Ross 	/*
112a90cf9f2SGordon Ross 	 * SMB2 Query Info reply
113a90cf9f2SGordon Ross 	 */
114*93bc28dbSGordon Ross 	(void) smb_mbc_encodef(
115a90cf9f2SGordon Ross 	    &sr->reply, "w..",
116a90cf9f2SGordon Ross 	    2);	/* StructSize */	/* w */
117a90cf9f2SGordon Ross 
118*93bc28dbSGordon Ross 	return (SDRC_SUCCESS);
119a90cf9f2SGordon Ross }
120