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_QUERY_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 
36*08f2ce59SGordon Ross /*
37*08f2ce59SGordon Ross  * MS-FSA 2.1.5.20 Server Requests Querying 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  *
43*08f2ce59SGordon Ross  * Similar to smb_nt_transact_query_quota()
44*08f2ce59SGordon Ross  */
45a90cf9f2SGordon Ross uint32_t
smb2_qinfo_quota(smb_request_t * sr,smb_queryinfo_t * qi)46a90cf9f2SGordon Ross smb2_qinfo_quota(smb_request_t *sr, smb_queryinfo_t *qi)
47a90cf9f2SGordon Ross {
48a90cf9f2SGordon Ross 	_NOTE(ARGUNUSED(qi))
49a90cf9f2SGordon Ross 	uint8_t		single, restart;
50a90cf9f2SGordon Ross 	uint32_t	sidlistlen, startsidlen, startsidoff;
51a90cf9f2SGordon Ross 	smb_node_t	*tnode;
52a90cf9f2SGordon Ross 	smb_ofile_t	*ofile = sr->fid_ofile;
53a90cf9f2SGordon Ross 	smb_quota_query_t request;
54a90cf9f2SGordon Ross 	smb_quota_response_t reply;
55a90cf9f2SGordon Ross 	uint32_t status = NT_STATUS_SUCCESS;
56a90cf9f2SGordon Ross 	int rc;
57a90cf9f2SGordon Ross 
58a90cf9f2SGordon Ross 	bzero(&request, sizeof (smb_quota_query_t));
59a90cf9f2SGordon Ross 	bzero(&reply, sizeof (smb_quota_response_t));
60a90cf9f2SGordon Ross 
61a90cf9f2SGordon Ross 	if (!smb_tree_has_feature(sr->tid_tree, SMB_TREE_QUOTA))
62*08f2ce59SGordon Ross 		return (NT_STATUS_INVALID_DEVICE_REQUEST);
63a90cf9f2SGordon Ross 
64a90cf9f2SGordon Ross 	if ((ofile->f_node == NULL) ||
65a90cf9f2SGordon Ross 	    (ofile->f_ftype != SMB_FTYPE_DISK))
66*08f2ce59SGordon Ross 		return (NT_STATUS_INVALID_DEVICE_REQUEST);
67a90cf9f2SGordon Ross 
68a90cf9f2SGordon Ross 	rc = smb_mbc_decodef(
69a90cf9f2SGordon Ross 	    &sr->smb_data, "bb..lll",
70a90cf9f2SGordon Ross 	    &single,		/* b */
71a90cf9f2SGordon Ross 	    &restart,		/* b */
72a90cf9f2SGordon Ross 	    /* reserved		  .. */
73a90cf9f2SGordon Ross 	    &sidlistlen,	/* l */
74a90cf9f2SGordon Ross 	    &startsidlen,	/* l */
75a90cf9f2SGordon Ross 	    &startsidoff);	/* l */
76a90cf9f2SGordon Ross 	if (rc)
77a90cf9f2SGordon Ross 		return (NT_STATUS_INVALID_PARAMETER);
78a90cf9f2SGordon Ross 
79a90cf9f2SGordon Ross 	if ((sidlistlen != 0) && (startsidlen != 0))
80a90cf9f2SGordon Ross 		return (NT_STATUS_INVALID_PARAMETER);
81a90cf9f2SGordon Ross 
82a90cf9f2SGordon Ross 
83a90cf9f2SGordon Ross 	tnode = sr->tid_tree->t_snode;
84a90cf9f2SGordon Ross 	request.qq_root_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
85a90cf9f2SGordon Ross 	if (smb_node_getmntpath(tnode, request.qq_root_path, MAXPATHLEN) != 0) {
86a90cf9f2SGordon Ross 		kmem_free(request.qq_root_path, MAXPATHLEN);
87a90cf9f2SGordon Ross 		return (NT_STATUS_INVALID_PARAMETER);
88a90cf9f2SGordon Ross 	}
89a90cf9f2SGordon Ross 
90a90cf9f2SGordon Ross 	if (sidlistlen != 0)
91a90cf9f2SGordon Ross 		request.qq_query_op = SMB_QUOTA_QUERY_SIDLIST;
92a90cf9f2SGordon Ross 	else if (startsidlen != 0)
93a90cf9f2SGordon Ross 		request.qq_query_op = SMB_QUOTA_QUERY_STARTSID;
94a90cf9f2SGordon Ross 	else
95a90cf9f2SGordon Ross 		request.qq_query_op = SMB_QUOTA_QUERY_ALL;
96a90cf9f2SGordon Ross 
97a90cf9f2SGordon Ross 	request.qq_single = single;
98a90cf9f2SGordon Ross 	request.qq_restart = restart;
99a90cf9f2SGordon Ross 	smb_quota_max_quota(&sr->raw_data, &request);
100a90cf9f2SGordon Ross 
101a90cf9f2SGordon Ross 	status = smb_quota_init_sids(&sr->smb_data, &request, ofile);
102a90cf9f2SGordon Ross 
103a90cf9f2SGordon Ross 	if (status == NT_STATUS_SUCCESS) {
104a90cf9f2SGordon Ross 		if (smb_quota_query(sr->sr_server, &request, &reply) != 0) {
105a90cf9f2SGordon Ross 			status = NT_STATUS_INTERNAL_ERROR;
106a90cf9f2SGordon Ross 		} else {
107a90cf9f2SGordon Ross 			status = reply.qr_status;
108a90cf9f2SGordon Ross 			if (status == NT_STATUS_SUCCESS) {
109a90cf9f2SGordon Ross 				status = smb_quota_encode_quotas(
110a90cf9f2SGordon Ross 				    &sr->raw_data,
111a90cf9f2SGordon Ross 				    &request, &reply, ofile);
112a90cf9f2SGordon Ross 			}
113a90cf9f2SGordon Ross 			xdr_free(smb_quota_response_xdr, (char *)&reply);
114a90cf9f2SGordon Ross 		}
115a90cf9f2SGordon Ross 	}
116a90cf9f2SGordon Ross 
117a90cf9f2SGordon Ross 	kmem_free(request.qq_root_path, MAXPATHLEN);
118a90cf9f2SGordon Ross 	smb_quota_free_sids(&request);
119a90cf9f2SGordon Ross 
120a90cf9f2SGordon Ross 	if (status != NT_STATUS_SUCCESS) {
121a90cf9f2SGordon Ross 		if (status == NT_STATUS_NO_MORE_ENTRIES) {
122a90cf9f2SGordon Ross 			smb_ofile_set_quota_resume(ofile, NULL);
123a90cf9f2SGordon Ross 			smbsr_warn(sr, status, 0, 0);
124a90cf9f2SGordon Ross 			status = NT_STATUS_SUCCESS;
125a90cf9f2SGordon Ross 		} else {
126a90cf9f2SGordon Ross 			smbsr_error(sr, status, 0, 0);
127a90cf9f2SGordon Ross 		}
128a90cf9f2SGordon Ross 	}
129a90cf9f2SGordon Ross 
130a90cf9f2SGordon Ross 	return (status);
131a90cf9f2SGordon Ross }
132