1a90cf9f2SGordon Ross /*
2a90cf9f2SGordon Ross  * CDDL HEADER START
3a90cf9f2SGordon Ross  *
4a90cf9f2SGordon Ross  * The contents of this file are subject to the terms of the
5a90cf9f2SGordon Ross  * Common Development and Distribution License (the "License").
6a90cf9f2SGordon Ross  * You may not use this file except in compliance with the License.
7a90cf9f2SGordon Ross  *
8a90cf9f2SGordon Ross  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9a90cf9f2SGordon Ross  * or http://www.opensolaris.org/os/licensing.
10a90cf9f2SGordon Ross  * See the License for the specific language governing permissions
11a90cf9f2SGordon Ross  * and limitations under the License.
12a90cf9f2SGordon Ross  *
13a90cf9f2SGordon Ross  * When distributing Covered Code, include this CDDL HEADER in each
14a90cf9f2SGordon Ross  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15a90cf9f2SGordon Ross  * If applicable, add the following below this CDDL HEADER, with the
16a90cf9f2SGordon Ross  * fields enclosed by brackets "[]" replaced with your own identifying
17a90cf9f2SGordon Ross  * information: Portions Copyright [yyyy] [name of copyright owner]
18a90cf9f2SGordon Ross  *
19a90cf9f2SGordon Ross  * CDDL HEADER END
20a90cf9f2SGordon Ross  */
21a90cf9f2SGordon Ross 
22a90cf9f2SGordon Ross /*
23a90cf9f2SGordon Ross  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24a90cf9f2SGordon Ross  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
25*08f2ce59SGordon Ross  * Copyright 2022 RackTop Systems, Inc.
26a90cf9f2SGordon Ross  */
27a90cf9f2SGordon Ross 
28a90cf9f2SGordon Ross /*
29a90cf9f2SGordon Ross  * Dispatch function for SMB2_SET_INFO
30a90cf9f2SGordon Ross  */
31a90cf9f2SGordon Ross 
32a90cf9f2SGordon Ross #include <smbsrv/smb2_kproto.h>
33a90cf9f2SGordon Ross #include <smbsrv/smb_fsops.h>
34a90cf9f2SGordon Ross #include <smbsrv/ntifs.h>
35a90cf9f2SGordon Ross 
36a90cf9f2SGordon Ross /*
37*08f2ce59SGordon Ross  * MS-FSA 2.1.5.21 Server Requests Setting Quota Information
38*08f2ce59SGordon Ross  *
39*08f2ce59SGordon Ross  * Support for this operation is optional. If the object store does not
40*08f2ce59SGordon Ross  * implement this functionality, the operation MUST be failed with
41*08f2ce59SGordon Ross  * STATUS_INVALID_DEVICE_REQUEST
42*08f2ce59SGordon Ross  *
43a90cf9f2SGordon Ross  * Similar to smb_nt_transact_set_quota()
44a90cf9f2SGordon Ross  */
45a90cf9f2SGordon Ross uint32_t
smb2_setinfo_quota(smb_request_t * sr,smb_setinfo_t * si)46a90cf9f2SGordon Ross smb2_setinfo_quota(smb_request_t *sr, smb_setinfo_t *si)
47a90cf9f2SGordon Ross {
48a90cf9f2SGordon Ross 	char		*root_path;
49a90cf9f2SGordon Ross 	uint32_t	status = NT_STATUS_SUCCESS;
50a90cf9f2SGordon Ross 	smb_ofile_t	*ofile = sr->fid_ofile;
51a90cf9f2SGordon Ross 	smb_node_t	*tnode;
52a90cf9f2SGordon Ross 	smb_quota_set_t request;
53a90cf9f2SGordon Ross 	uint32_t	reply;
54*08f2ce59SGordon Ross 	list_t		*quota_list;
55a90cf9f2SGordon Ross 
56a90cf9f2SGordon Ross 	bzero(&request, sizeof (smb_quota_set_t));
57a90cf9f2SGordon Ross 
58a90cf9f2SGordon Ross 	if (!smb_tree_has_feature(sr->tid_tree, SMB_TREE_QUOTA))
59*08f2ce59SGordon Ross 		return (NT_STATUS_INVALID_DEVICE_REQUEST);
60a90cf9f2SGordon Ross 
61a90cf9f2SGordon Ross 	if ((ofile->f_node == NULL) ||
62a90cf9f2SGordon Ross 	    (ofile->f_ftype != SMB_FTYPE_DISK))
63*08f2ce59SGordon Ross 		return (NT_STATUS_INVALID_DEVICE_REQUEST);
64*08f2ce59SGordon Ross 
65*08f2ce59SGordon Ross 	if (!smb_user_is_admin(sr->uid_user))
66a90cf9f2SGordon Ross 		return (NT_STATUS_ACCESS_DENIED);
67a90cf9f2SGordon Ross 
68a90cf9f2SGordon Ross 	tnode = sr->tid_tree->t_snode;
69a90cf9f2SGordon Ross 	root_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
70a90cf9f2SGordon Ross 	if (smb_node_getmntpath(tnode, root_path, MAXPATHLEN) != 0) {
71a90cf9f2SGordon Ross 		smbsr_release_file(sr);
72a90cf9f2SGordon Ross 		kmem_free(root_path, MAXPATHLEN);
73a90cf9f2SGordon Ross 		return (NT_STATUS_INVALID_PARAMETER);
74a90cf9f2SGordon Ross 	}
75a90cf9f2SGordon Ross 
76a90cf9f2SGordon Ross 	quota_list = &request.qs_quota_list;
77a90cf9f2SGordon Ross 	list_create(quota_list, sizeof (smb_quota_t),
78a90cf9f2SGordon Ross 	    offsetof(smb_quota_t, q_list_node));
79a90cf9f2SGordon Ross 
80a90cf9f2SGordon Ross 	status = smb_quota_decode_quotas(&si->si_data, quota_list);
81a90cf9f2SGordon Ross 	if (status == NT_STATUS_SUCCESS) {
82a90cf9f2SGordon Ross 		request.qs_root_path = root_path;
83a90cf9f2SGordon Ross 		if (smb_quota_set(sr->sr_server, &request, &reply) != 0) {
84a90cf9f2SGordon Ross 			status = NT_STATUS_INTERNAL_ERROR;
85a90cf9f2SGordon Ross 		} else {
86a90cf9f2SGordon Ross 			status = reply;
87a90cf9f2SGordon Ross 			xdr_free(xdr_uint32_t, (char *)&reply);
88a90cf9f2SGordon Ross 		}
89a90cf9f2SGordon Ross 	}
90a90cf9f2SGordon Ross 
91a90cf9f2SGordon Ross 	kmem_free(root_path, MAXPATHLEN);
92a90cf9f2SGordon Ross 	smb_quota_free_quotas(&request.qs_quota_list);
93a90cf9f2SGordon Ross 	smbsr_release_file(sr);
94a90cf9f2SGordon Ross 
95a90cf9f2SGordon Ross 	return (status);
96a90cf9f2SGordon Ross }
97