1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2013 Nexenta Systems, Inc. All rights reserved. 25 */ 26 27 /* 28 * Dispatch function for SMB2_QUERY_INFO 29 */ 30 31 #include <smbsrv/smb2_kproto.h> 32 #include <smbsrv/smb_fsops.h> 33 #include <smbsrv/ntifs.h> 34 35 uint32_t 36 smb2_qinfo_quota(smb_request_t *sr, smb_queryinfo_t *qi) 37 { 38 _NOTE(ARGUNUSED(qi)) 39 uint8_t single, restart; 40 uint32_t sidlistlen, startsidlen, startsidoff; 41 smb_node_t *tnode; 42 smb_ofile_t *ofile = sr->fid_ofile; 43 smb_quota_query_t request; 44 smb_quota_response_t reply; 45 uint32_t status = NT_STATUS_SUCCESS; 46 int rc; 47 48 bzero(&request, sizeof (smb_quota_query_t)); 49 bzero(&reply, sizeof (smb_quota_response_t)); 50 51 if (!smb_tree_has_feature(sr->tid_tree, SMB_TREE_QUOTA)) 52 return (NT_STATUS_NOT_SUPPORTED); 53 54 if ((ofile->f_node == NULL) || 55 (ofile->f_ftype != SMB_FTYPE_DISK)) 56 return (NT_STATUS_NOT_SUPPORTED); 57 58 rc = smb_mbc_decodef( 59 &sr->smb_data, "bb..lll", 60 &single, /* b */ 61 &restart, /* b */ 62 /* reserved .. */ 63 &sidlistlen, /* l */ 64 &startsidlen, /* l */ 65 &startsidoff); /* l */ 66 if (rc) 67 return (NT_STATUS_INVALID_PARAMETER); 68 69 if ((sidlistlen != 0) && (startsidlen != 0)) 70 return (NT_STATUS_INVALID_PARAMETER); 71 72 73 tnode = sr->tid_tree->t_snode; 74 request.qq_root_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 75 if (smb_node_getmntpath(tnode, request.qq_root_path, MAXPATHLEN) != 0) { 76 kmem_free(request.qq_root_path, MAXPATHLEN); 77 return (NT_STATUS_INVALID_PARAMETER); 78 } 79 80 if (sidlistlen != 0) 81 request.qq_query_op = SMB_QUOTA_QUERY_SIDLIST; 82 else if (startsidlen != 0) 83 request.qq_query_op = SMB_QUOTA_QUERY_STARTSID; 84 else 85 request.qq_query_op = SMB_QUOTA_QUERY_ALL; 86 87 request.qq_single = single; 88 request.qq_restart = restart; 89 smb_quota_max_quota(&sr->raw_data, &request); 90 91 status = smb_quota_init_sids(&sr->smb_data, &request, ofile); 92 93 if (status == NT_STATUS_SUCCESS) { 94 if (smb_quota_query(sr->sr_server, &request, &reply) != 0) { 95 status = NT_STATUS_INTERNAL_ERROR; 96 } else { 97 status = reply.qr_status; 98 if (status == NT_STATUS_SUCCESS) { 99 status = smb_quota_encode_quotas( 100 &sr->raw_data, 101 &request, &reply, ofile); 102 } 103 xdr_free(smb_quota_response_xdr, (char *)&reply); 104 } 105 } 106 107 kmem_free(request.qq_root_path, MAXPATHLEN); 108 smb_quota_free_sids(&request); 109 110 if (status != NT_STATUS_SUCCESS) { 111 if (status == NT_STATUS_NO_MORE_ENTRIES) { 112 smb_ofile_set_quota_resume(ofile, NULL); 113 smbsr_warn(sr, status, 0, 0); 114 status = NT_STATUS_SUCCESS; 115 } else { 116 smbsr_error(sr, status, 0, 0); 117 } 118 } 119 120 return (status); 121 } 122