More const fixes for compiler warnings from the waf build.
[Samba.git] / source3 / libsmb / cliquota.c
blob94694e4530e1bdebe5417e19b102d758fb1eae5d
1 /*
2 Unix SMB/CIFS implementation.
3 client quota functions
4 Copyright (C) Stefan (metze) Metzmacher 2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "../librpc/gen_ndr/ndr_security.h"
22 #include "fake_file.h"
23 #include "../libcli/security/security.h"
24 #include "trans2.h"
26 NTSTATUS cli_get_quota_handle(struct cli_state *cli, uint16_t *quota_fnum)
28 return cli_ntcreate(cli, FAKE_FILE_NAME_QUOTA_WIN32,
29 0x00000016, DESIRED_ACCESS_PIPE,
30 0x00000000, FILE_SHARE_READ|FILE_SHARE_WRITE,
31 FILE_OPEN, 0x00000000, 0x03, quota_fnum);
34 void free_ntquota_list(SMB_NTQUOTA_LIST **qt_list)
36 if (!qt_list)
37 return;
39 if ((*qt_list)->mem_ctx)
40 talloc_destroy((*qt_list)->mem_ctx);
42 (*qt_list) = NULL;
44 return;
47 static bool parse_user_quota_record(const uint8_t *rdata,
48 unsigned int rdata_count,
49 unsigned int *offset,
50 SMB_NTQUOTA_STRUCT *pqt)
52 int sid_len;
53 SMB_NTQUOTA_STRUCT qt;
55 ZERO_STRUCT(qt);
57 if (!rdata||!offset||!pqt) {
58 smb_panic("parse_quota_record: called with NULL POINTER!");
61 if (rdata_count < 40) {
62 return False;
65 /* offset to next quota record.
66 * 4 bytes IVAL(rdata,0)
67 * unused here...
69 *offset = IVAL(rdata,0);
71 /* sid len */
72 sid_len = IVAL(rdata,4);
74 if (rdata_count < 40+sid_len) {
75 return False;
78 /* unknown 8 bytes in pdata
79 * maybe its the change time in NTTIME
82 /* the used space 8 bytes (uint64_t)*/
83 qt.usedspace = BVAL(rdata,16);
85 /* the soft quotas 8 bytes (uint64_t)*/
86 qt.softlim = BVAL(rdata,24);
88 /* the hard quotas 8 bytes (uint64_t)*/
89 qt.hardlim = BVAL(rdata,32);
91 if (!sid_parse((const char *)rdata+40,sid_len,&qt.sid)) {
92 return false;
95 qt.qtype = SMB_USER_QUOTA_TYPE;
97 *pqt = qt;
99 return True;
102 NTSTATUS cli_get_user_quota(struct cli_state *cli, int quota_fnum,
103 SMB_NTQUOTA_STRUCT *pqt)
105 uint16_t setup[1];
106 uint8_t params[16];
107 unsigned int data_len;
108 uint8_t data[SID_MAX_SIZE+8];
109 uint8_t *rparam, *rdata;
110 uint32_t rparam_count, rdata_count;
111 unsigned int sid_len;
112 unsigned int offset;
113 NTSTATUS status;
115 if (!cli||!pqt) {
116 smb_panic("cli_get_user_quota() called with NULL Pointer!");
119 SSVAL(setup + 0, 0, NT_TRANSACT_GET_USER_QUOTA);
121 SSVAL(params, 0,quota_fnum);
122 SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_FOR_SID);
123 SIVAL(params, 4,0x00000024);
124 SIVAL(params, 8,0x00000000);
125 SIVAL(params,12,0x00000024);
127 sid_len = ndr_size_dom_sid(&pqt->sid, 0);
128 data_len = sid_len+8;
129 SIVAL(data, 0, 0x00000000);
130 SIVAL(data, 4, sid_len);
131 sid_linearize((char *)data+8, sid_len, &pqt->sid);
133 status = cli_trans(talloc_tos(), cli, SMBnttrans,
134 NULL, -1, /* name, fid */
135 NT_TRANSACT_GET_USER_QUOTA, 0,
136 setup, 1, 0, /* setup */
137 params, 16, 4, /* params */
138 data, data_len, 112, /* data */
139 NULL, /* recv_flags2 */
140 NULL, 0, NULL, /* rsetup */
141 &rparam, 4, &rparam_count,
142 &rdata, 8, &rdata_count);
143 if (!NT_STATUS_IS_OK(status)) {
144 DEBUG(1, ("NT_TRANSACT_GET_USER_QUOTA failed: %s\n",
145 nt_errstr(status)));
146 return status;
149 if (!parse_user_quota_record(rdata, rdata_count, &offset, pqt)) {
150 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
151 DEBUG(0,("Got INVALID NT_TRANSACT_GET_USER_QUOTA reply.\n"));
154 TALLOC_FREE(rparam);
155 TALLOC_FREE(rdata);
156 return status;
159 NTSTATUS cli_set_user_quota(struct cli_state *cli, int quota_fnum,
160 SMB_NTQUOTA_STRUCT *pqt)
162 uint16_t setup[1];
163 uint8_t params[2];
164 uint8_t data[112];
165 unsigned int sid_len;
166 NTSTATUS status;
168 memset(data,'\0',112);
170 if (!cli||!pqt) {
171 smb_panic("cli_set_user_quota() called with NULL Pointer!");
174 SSVAL(setup + 0, 0, NT_TRANSACT_SET_USER_QUOTA);
176 SSVAL(params,0,quota_fnum);
178 sid_len = ndr_size_dom_sid(&pqt->sid, 0);
179 SIVAL(data,0,0);
180 SIVAL(data,4,sid_len);
181 SBIG_UINT(data, 8,(uint64_t)0);
182 SBIG_UINT(data,16,pqt->usedspace);
183 SBIG_UINT(data,24,pqt->softlim);
184 SBIG_UINT(data,32,pqt->hardlim);
185 sid_linearize((char *)data+40, sid_len, &pqt->sid);
187 status = cli_trans(talloc_tos(), cli, SMBnttrans,
188 NULL, -1, /* name, fid */
189 NT_TRANSACT_SET_USER_QUOTA, 0,
190 setup, 1, 0, /* setup */
191 params, 2, 0, /* params */
192 data, 112, 0, /* data */
193 NULL, /* recv_flags2 */
194 NULL, 0, NULL, /* rsetup */
195 NULL, 0, NULL, /* rparams */
196 NULL, 0, NULL); /* rdata */
198 if (!NT_STATUS_IS_OK(status)) {
199 DEBUG(1, ("NT_TRANSACT_SET_USER_QUOTA failed: %s\n",
200 nt_errstr(status)));
203 return status;
206 NTSTATUS cli_list_user_quota(struct cli_state *cli, int quota_fnum,
207 SMB_NTQUOTA_LIST **pqt_list)
209 uint16_t setup[1];
210 uint8_t params[16];
211 uint8_t *rparam=NULL, *rdata=NULL;
212 uint32_t rparam_count=0, rdata_count=0;
213 unsigned int offset;
214 const uint8_t *curdata = NULL;
215 unsigned int curdata_count = 0;
216 TALLOC_CTX *mem_ctx = NULL;
217 SMB_NTQUOTA_STRUCT qt;
218 SMB_NTQUOTA_LIST *tmp_list_ent;
219 NTSTATUS status;
221 if (!cli||!pqt_list) {
222 smb_panic("cli_list_user_quota() called with NULL Pointer!");
225 SSVAL(setup + 0, 0, NT_TRANSACT_GET_USER_QUOTA);
227 SSVAL(params, 0,quota_fnum);
228 SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_START);
229 SIVAL(params, 4,0x00000000);
230 SIVAL(params, 8,0x00000000);
231 SIVAL(params,12,0x00000000);
233 status = cli_trans(talloc_tos(), cli, SMBnttrans,
234 NULL, -1, /* name, fid */
235 NT_TRANSACT_GET_USER_QUOTA, 0,
236 setup, 1, 0, /* setup */
237 params, 16, 4, /* params */
238 NULL, 0, 2048, /* data */
239 NULL, /* recv_flags2 */
240 NULL, 0, NULL, /* rsetup */
241 &rparam, 0, &rparam_count,
242 &rdata, 0, &rdata_count);
244 if (!NT_STATUS_IS_OK(status)) {
245 DEBUG(1, ("NT_TRANSACT_GET_USER_QUOTA failed: %s\n",
246 nt_errstr(status)));
247 goto cleanup;
250 if (rdata_count == 0) {
251 *pqt_list = NULL;
252 return NT_STATUS_OK;
255 if ((mem_ctx=talloc_init("SMB_USER_QUOTA_LIST"))==NULL) {
256 DEBUG(0,("talloc_init() failed\n"));
257 return NT_STATUS_NO_MEMORY;
260 offset = 1;
261 for (curdata=rdata,curdata_count=rdata_count;
262 ((curdata)&&(curdata_count>=8)&&(offset>0));
263 curdata +=offset,curdata_count -= offset) {
264 ZERO_STRUCT(qt);
265 if (!parse_user_quota_record((const uint8_t *)curdata, curdata_count,
266 &offset, &qt)) {
267 DEBUG(1,("Failed to parse the quota record\n"));
268 goto cleanup;
271 if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) {
272 DEBUG(0,("TALLOC_ZERO() failed\n"));
273 talloc_destroy(mem_ctx);
274 return NT_STATUS_NO_MEMORY;
277 if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) {
278 DEBUG(0,("TALLOC_ZERO() failed\n"));
279 talloc_destroy(mem_ctx);
280 return NT_STATUS_NO_MEMORY;
283 memcpy(tmp_list_ent->quotas,&qt,sizeof(qt));
284 tmp_list_ent->mem_ctx = mem_ctx;
286 DLIST_ADD((*pqt_list),tmp_list_ent);
289 SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_CONTINUE);
290 while(1) {
292 TALLOC_FREE(rparam);
293 TALLOC_FREE(rdata);
295 status = cli_trans(talloc_tos(), cli, SMBnttrans,
296 NULL, -1, /* name, fid */
297 NT_TRANSACT_GET_USER_QUOTA, 0,
298 setup, 1, 0, /* setup */
299 params, 16, 4, /* params */
300 NULL, 0, 2048, /* data */
301 NULL, /* recv_flags2 */
302 NULL, 0, NULL, /* rsetup */
303 &rparam, 0, &rparam_count,
304 &rdata, 0, &rdata_count);
306 if (!NT_STATUS_IS_OK(status)) {
307 DEBUG(1, ("NT_TRANSACT_GET_USER_QUOTA failed: %s\n",
308 nt_errstr(status)));
309 goto cleanup;
312 if (rdata_count == 0) {
313 break;
316 offset = 1;
317 for (curdata=rdata,curdata_count=rdata_count;
318 ((curdata)&&(curdata_count>=8)&&(offset>0));
319 curdata +=offset,curdata_count -= offset) {
320 ZERO_STRUCT(qt);
321 if (!parse_user_quota_record((const uint8_t *)curdata,
322 curdata_count, &offset,
323 &qt)) {
324 DEBUG(1,("Failed to parse the quota record\n"));
325 goto cleanup;
328 if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) {
329 DEBUG(0,("TALLOC_ZERO() failed\n"));
330 talloc_destroy(mem_ctx);
331 goto cleanup;
334 if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) {
335 DEBUG(0,("TALLOC_ZERO() failed\n"));
336 talloc_destroy(mem_ctx);
337 goto cleanup;
340 memcpy(tmp_list_ent->quotas,&qt,sizeof(qt));
341 tmp_list_ent->mem_ctx = mem_ctx;
343 DLIST_ADD((*pqt_list),tmp_list_ent);
347 cleanup:
348 TALLOC_FREE(rparam);
349 TALLOC_FREE(rdata);
351 return status;
354 NTSTATUS cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum,
355 SMB_NTQUOTA_STRUCT *pqt)
357 uint16_t setup[1];
358 uint8_t param[2];
359 uint8_t *rdata=NULL;
360 uint32_t rdata_count=0;
361 SMB_NTQUOTA_STRUCT qt;
362 NTSTATUS status;
364 ZERO_STRUCT(qt);
366 if (!cli||!pqt) {
367 smb_panic("cli_get_fs_quota_info() called with NULL Pointer!");
370 SSVAL(setup + 0, 0, TRANSACT2_QFSINFO);
372 SSVAL(param,0,SMB_FS_QUOTA_INFORMATION);
374 status = cli_trans(talloc_tos(), cli, SMBtrans2,
375 NULL, -1, /* name, fid */
376 0, 0, /* function, flags */
377 setup, 1, 0, /* setup */
378 param, 2, 0, /* param */
379 NULL, 0, 560, /* data */
380 NULL, /* recv_flags2 */
381 NULL, 0, NULL, /* rsetup */
382 NULL, 0, NULL, /* rparam */
383 &rdata, 48, &rdata_count);
385 if (!NT_STATUS_IS_OK(status)) {
386 DEBUG(1, ("SMB_FS_QUOTA_INFORMATION failed: %s\n",
387 nt_errstr(status)));
388 return status;
391 /* unknown_1 24 NULL bytes in pdata*/
393 /* the soft quotas 8 bytes (uint64_t)*/
394 qt.softlim = BVAL(rdata,24);
396 /* the hard quotas 8 bytes (uint64_t)*/
397 qt.hardlim = BVAL(rdata,32);
399 /* quota_flags 2 bytes **/
400 qt.qflags = SVAL(rdata,40);
402 qt.qtype = SMB_USER_FS_QUOTA_TYPE;
404 *pqt = qt;
406 TALLOC_FREE(rdata);
407 return status;
410 NTSTATUS cli_set_fs_quota_info(struct cli_state *cli, int quota_fnum,
411 SMB_NTQUOTA_STRUCT *pqt)
413 uint16_t setup[1];
414 uint8_t param[4];
415 uint8_t data[48];
416 SMB_NTQUOTA_STRUCT qt;
417 NTSTATUS status;
418 ZERO_STRUCT(qt);
419 memset(data,'\0',48);
421 if (!cli||!pqt) {
422 smb_panic("cli_set_fs_quota_info() called with NULL Pointer!");
425 SSVAL(setup + 0, 0,TRANSACT2_SETFSINFO);
427 SSVAL(param,0,quota_fnum);
428 SSVAL(param,2,SMB_FS_QUOTA_INFORMATION);
430 /* Unknown1 24 NULL bytes*/
432 /* Default Soft Quota 8 bytes */
433 SBIG_UINT(data,24,pqt->softlim);
435 /* Default Hard Quota 8 bytes */
436 SBIG_UINT(data,32,pqt->hardlim);
438 /* Quota flag 2 bytes */
439 SSVAL(data,40,pqt->qflags);
441 /* Unknown3 6 NULL bytes */
443 status = cli_trans(talloc_tos(), cli, SMBtrans2,
444 NULL, -1, /* name, fid */
445 0, 0, /* function, flags */
446 setup, 1, 0, /* setup */
447 param, 8, 0, /* param */
448 data, 48, 0, /* data */
449 NULL, /* recv_flags2 */
450 NULL, 0, NULL, /* rsetup */
451 NULL, 0, NULL, /* rparam */
452 NULL, 0, NULL); /* rdata */
454 if (!NT_STATUS_IS_OK(status)) {
455 DEBUG(1, ("SMB_FS_QUOTA_INFORMATION failed: %s\n",
456 nt_errstr(status)));
459 return status;