2
Unix SMB/CIFS implementation.
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 2 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, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
BOOL cli_get_quota_handle(struct cli_state *cli, int *quota_fnum)
25
*quota_fnum = cli_nt_create_full(cli, FAKE_FILE_NAME_QUOTA_WIN32,
26
0x00000016, DESIRED_ACCESS_PIPE,
27
0x00000000, FILE_SHARE_READ|FILE_SHARE_WRITE,
28
FILE_OPEN, 0x00000000, 0x03);
30
if (*quota_fnum == (-1)) {
37
void free_ntquota_list(SMB_NTQUOTA_LIST **qt_list)
42
if ((*qt_list)->mem_ctx)
43
talloc_destroy((*qt_list)->mem_ctx);
50
static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, unsigned int *offset, SMB_NTQUOTA_STRUCT *pqt)
53
SMB_NTQUOTA_STRUCT qt;
57
if (!rdata||!offset||!pqt)
58
smb_panic("parse_quota_record: called with NULL POINTER!\n");
60
if (rdata_count < 40) {
64
/* offset to next quota record.
65
* 4 bytes IVAL(rdata,0)
68
*offset = IVAL(rdata,0);
71
sid_len = IVAL(rdata,4);
73
if (rdata_count < 40+sid_len) {
77
/* unknown 8 bytes in pdata
78
* maybe its the change time in NTTIME
81
/* the used space 8 bytes (SMB_BIG_UINT)*/
82
qt.usedspace = (SMB_BIG_UINT)IVAL(rdata,16);
83
#ifdef LARGE_SMB_OFF_T
84
qt.usedspace |= (((SMB_BIG_UINT)IVAL(rdata,20)) << 32);
85
#else /* LARGE_SMB_OFF_T */
86
if ((IVAL(rdata,20) != 0)&&
87
((qt.usedspace != 0xFFFFFFFF)||
88
(IVAL(rdata,20)!=0xFFFFFFFF))) {
89
/* more than 32 bits? */
92
#endif /* LARGE_SMB_OFF_T */
94
/* the soft quotas 8 bytes (SMB_BIG_UINT)*/
95
qt.softlim = (SMB_BIG_UINT)IVAL(rdata,24);
96
#ifdef LARGE_SMB_OFF_T
97
qt.softlim |= (((SMB_BIG_UINT)IVAL(rdata,28)) << 32);
98
#else /* LARGE_SMB_OFF_T */
99
if ((IVAL(rdata,28) != 0)&&
100
((qt.softlim != 0xFFFFFFFF)||
101
(IVAL(rdata,28)!=0xFFFFFFFF))) {
102
/* more than 32 bits? */
105
#endif /* LARGE_SMB_OFF_T */
107
/* the hard quotas 8 bytes (SMB_BIG_UINT)*/
108
qt.hardlim = (SMB_BIG_UINT)IVAL(rdata,32);
109
#ifdef LARGE_SMB_OFF_T
110
qt.hardlim |= (((SMB_BIG_UINT)IVAL(rdata,36)) << 32);
111
#else /* LARGE_SMB_OFF_T */
112
if ((IVAL(rdata,36) != 0)&&
113
((qt.hardlim != 0xFFFFFFFF)||
114
(IVAL(rdata,36)!=0xFFFFFFFF))) {
115
/* more than 32 bits? */
118
#endif /* LARGE_SMB_OFF_T */
120
sid_parse(rdata+40,sid_len,&qt.sid);
122
qt.qtype = SMB_USER_QUOTA_TYPE;
129
BOOL cli_get_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt)
134
unsigned int data_len;
135
char data[SID_MAX_SIZE+8];
136
char *rparam=NULL, *rdata=NULL;
137
unsigned int rparam_count=0, rdata_count=0;
138
unsigned int sid_len;
142
smb_panic("cli_get_user_quota() called with NULL Pointer!");
144
setup = NT_TRANSACT_GET_USER_QUOTA;
146
SSVAL(params, 0,quota_fnum);
147
SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_FOR_SID);
148
SIVAL(params, 4,0x00000024);
149
SIVAL(params, 8,0x00000000);
150
SIVAL(params,12,0x00000024);
152
sid_len = sid_size(&pqt->sid);
153
data_len = sid_len+8;
154
SIVAL(data, 0, 0x00000000);
155
SIVAL(data, 4, sid_len);
156
sid_linearize(data+8, sid_len, &pqt->sid);
158
if (!cli_send_nt_trans(cli,
159
NT_TRANSACT_GET_USER_QUOTA,
163
data, data_len, 112)) {
164
DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n"));
169
if (!cli_receive_nt_trans(cli,
170
&rparam, &rparam_count,
171
&rdata, &rdata_count)) {
172
DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n"));
176
if (cli_is_error(cli)) {
183
if ((rparam&&rdata)&&(rparam_count>=4&&rdata_count>=8)) {
184
ret = parse_user_quota_record(rdata, rdata_count, &offset, pqt);
186
DEBUG(0,("Got INVALID NT_TRANSACT_GET_USER_QUOTA reply.\n"));
196
BOOL cli_set_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt)
202
char *rparam=NULL, *rdata=NULL;
203
unsigned int rparam_count=0, rdata_count=0;
204
unsigned int sid_len;
205
memset(data,'\0',112);
208
smb_panic("cli_set_user_quota() called with NULL Pointer!");
210
setup = NT_TRANSACT_SET_USER_QUOTA;
212
SSVAL(params,0,quota_fnum);
214
sid_len = sid_size(&pqt->sid);
216
SIVAL(data,4,sid_len);
217
SBIG_UINT(data, 8,(SMB_BIG_UINT)0);
218
SBIG_UINT(data,16,pqt->usedspace);
219
SBIG_UINT(data,24,pqt->softlim);
220
SBIG_UINT(data,32,pqt->hardlim);
221
sid_linearize(data+40, sid_len, &pqt->sid);
223
if (!cli_send_nt_trans(cli,
224
NT_TRANSACT_SET_USER_QUOTA,
229
DEBUG(1,("Failed to send NT_TRANSACT_SET_USER_QUOTA\n"));
234
if (!cli_receive_nt_trans(cli,
235
&rparam, &rparam_count,
236
&rdata, &rdata_count)) {
237
DEBUG(1,("NT_TRANSACT_SET_USER_QUOTA failed\n"));
241
if (cli_is_error(cli)) {
254
BOOL cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST **pqt_list)
259
char *rparam=NULL, *rdata=NULL;
260
unsigned int rparam_count=0, rdata_count=0;
262
const char *curdata = NULL;
263
unsigned int curdata_count = 0;
264
TALLOC_CTX *mem_ctx = NULL;
265
SMB_NTQUOTA_STRUCT qt;
266
SMB_NTQUOTA_LIST *tmp_list_ent;
269
smb_panic("cli_list_user_quota() called with NULL Pointer!");
271
setup = NT_TRANSACT_GET_USER_QUOTA;
273
SSVAL(params, 0,quota_fnum);
274
SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_START);
275
SIVAL(params, 4,0x00000000);
276
SIVAL(params, 8,0x00000000);
277
SIVAL(params,12,0x00000000);
279
if (!cli_send_nt_trans(cli,
280
NT_TRANSACT_GET_USER_QUOTA,
285
DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n"));
290
if (!cli_receive_nt_trans(cli,
291
&rparam, &rparam_count,
292
&rdata, &rdata_count)) {
293
DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n"));
297
if (cli_is_error(cli)) {
304
if (rdata_count == 0) {
309
if ((mem_ctx=talloc_init("SMB_USER_QUOTA_LIST"))==NULL) {
310
DEBUG(0,("talloc_init() failed\n"));
315
for (curdata=rdata,curdata_count=rdata_count;
316
((curdata)&&(curdata_count>=8)&&(offset>0));
317
curdata +=offset,curdata_count -= offset) {
319
if (!parse_user_quota_record(curdata, curdata_count, &offset, &qt)) {
320
DEBUG(1,("Failed to parse the quota record\n"));
324
if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) {
325
DEBUG(0,("talloc_zero() failed\n"));
329
if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) {
330
DEBUG(0,("talloc_zero() failed\n"));
334
memcpy(tmp_list_ent->quotas,&qt,sizeof(qt));
335
tmp_list_ent->mem_ctx = mem_ctx;
337
DLIST_ADD((*pqt_list),tmp_list_ent);
340
SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_CONTINUE);
342
if (!cli_send_nt_trans(cli,
343
NT_TRANSACT_GET_USER_QUOTA,
348
DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n"));
354
if (!cli_receive_nt_trans(cli,
355
&rparam, &rparam_count,
356
&rdata, &rdata_count)) {
357
DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n"));
361
if (cli_is_error(cli)) {
368
if (rdata_count == 0) {
373
for (curdata=rdata,curdata_count=rdata_count;
374
((curdata)&&(curdata_count>=8)&&(offset>0));
375
curdata +=offset,curdata_count -= offset) {
377
if (!parse_user_quota_record(curdata, curdata_count, &offset, &qt)) {
378
DEBUG(1,("Failed to parse the quota record\n"));
382
if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) {
383
DEBUG(0,("talloc_zero() failed\n"));
384
talloc_destroy(mem_ctx);
388
if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) {
389
DEBUG(0,("talloc_zero() failed\n"));
390
talloc_destroy(mem_ctx);
394
memcpy(tmp_list_ent->quotas,&qt,sizeof(qt));
395
tmp_list_ent->mem_ctx = mem_ctx;
397
DLIST_ADD((*pqt_list),tmp_list_ent);
410
BOOL cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt)
415
char *rparam=NULL, *rdata=NULL;
416
unsigned int rparam_count=0, rdata_count=0;
417
SMB_NTQUOTA_STRUCT qt;
421
smb_panic("cli_get_fs_quota_info() called with NULL Pointer!");
423
setup = TRANSACT2_QFSINFO;
425
SSVAL(param,0,SMB_FS_QUOTA_INFORMATION);
427
if (!cli_send_trans(cli, SMBtrans2,
436
if (!cli_receive_trans(cli, SMBtrans2,
437
&rparam, &rparam_count,
438
&rdata, &rdata_count)) {
442
if (cli_is_error(cli)) {
449
if (rdata_count < 48) {
453
/* unknown_1 24 NULL bytes in pdata*/
455
/* the soft quotas 8 bytes (SMB_BIG_UINT)*/
456
qt.softlim = (SMB_BIG_UINT)IVAL(rdata,24);
457
#ifdef LARGE_SMB_OFF_T
458
qt.softlim |= (((SMB_BIG_UINT)IVAL(rdata,28)) << 32);
459
#else /* LARGE_SMB_OFF_T */
460
if ((IVAL(rdata,28) != 0)&&
461
((qt.softlim != 0xFFFFFFFF)||
462
(IVAL(rdata,28)!=0xFFFFFFFF))) {
463
/* more than 32 bits? */
466
#endif /* LARGE_SMB_OFF_T */
468
/* the hard quotas 8 bytes (SMB_BIG_UINT)*/
469
qt.hardlim = (SMB_BIG_UINT)IVAL(rdata,32);
470
#ifdef LARGE_SMB_OFF_T
471
qt.hardlim |= (((SMB_BIG_UINT)IVAL(rdata,36)) << 32);
472
#else /* LARGE_SMB_OFF_T */
473
if ((IVAL(rdata,36) != 0)&&
474
((qt.hardlim != 0xFFFFFFFF)||
475
(IVAL(rdata,36)!=0xFFFFFFFF))) {
476
/* more than 32 bits? */
479
#endif /* LARGE_SMB_OFF_T */
481
/* quota_flags 2 bytes **/
482
qt.qflags = SVAL(rdata,40);
484
qt.qtype = SMB_USER_FS_QUOTA_TYPE;
496
BOOL cli_set_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt)
502
char *rparam=NULL, *rdata=NULL;
503
unsigned int rparam_count=0, rdata_count=0;
504
SMB_NTQUOTA_STRUCT qt;
506
memset(data,'\0',48);
509
smb_panic("cli_set_fs_quota_info() called with NULL Pointer!");
511
setup = TRANSACT2_SETFSINFO;
513
SSVAL(param,0,quota_fnum);
514
SSVAL(param,2,SMB_FS_QUOTA_INFORMATION);
516
/* Unknown1 24 NULL bytes*/
518
/* Default Soft Quota 8 bytes */
519
SBIG_UINT(data,24,pqt->softlim);
521
/* Default Hard Quota 8 bytes */
522
SBIG_UINT(data,32,pqt->hardlim);
524
/* Quota flag 2 bytes */
525
SSVAL(data,40,pqt->qflags);
527
/* Unknown3 6 NULL bytes */
529
if (!cli_send_trans(cli, SMBtrans2,
538
if (!cli_receive_trans(cli, SMBtrans2,
539
&rparam, &rparam_count,
540
&rdata, &rdata_count)) {
544
if (cli_is_error(cli)) {
558
static char *quota_str_static(SMB_BIG_UINT val, BOOL special, BOOL _numeric)
560
static fstring buffer;
562
memset(buffer,'\0',sizeof(buffer));
564
if (!_numeric&&special&&(val == SMB_NTQUOTAS_NO_LIMIT)) {
565
fstr_sprintf(buffer,"NO LIMIT");
568
#if defined(HAVE_LONGLONG)
569
fstr_sprintf(buffer,"%llu",val);
571
fstr_sprintf(buffer,"%lu",val);
576
void dump_ntquota(SMB_NTQUOTA_STRUCT *qt, BOOL _verbose, BOOL _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, BOOL _numeric))
579
smb_panic("dump_ntquota() called with NULL pointer");
582
case SMB_USER_FS_QUOTA_TYPE:
584
d_printf("File System QUOTAS:\n");
585
d_printf("Limits:\n");
586
d_printf(" Default Soft Limit: %15s\n",quota_str_static(qt->softlim,True,_numeric));
587
d_printf(" Default Hard Limit: %15s\n",quota_str_static(qt->hardlim,True,_numeric));
588
d_printf("Quota Flags:\n");
589
d_printf(" Quotas Enabled: %s\n",
590
((qt->qflags"AS_ENABLED)||(qt->qflags"AS_DENY_DISK))?"On":"Off");
591
d_printf(" Deny Disk: %s\n",(qt->qflags"AS_DENY_DISK)?"On":"Off");
592
d_printf(" Log Soft Limit: %s\n",(qt->qflags"AS_LOG_THRESHOLD)?"On":"Off");
593
d_printf(" Log Hard Limit: %s\n",(qt->qflags"AS_LOG_LIMIT)?"On":"Off");
596
case SMB_USER_QUOTA_TYPE:
598
fstring username_str = {0};
601
_sidtostring(username_str,&qt->sid,_numeric);
603
fstrcpy(username_str,sid_string_static(&qt->sid));
607
d_printf("Quotas for User: %s\n",username_str);
608
d_printf("Used Space: %15s\n",quota_str_static(qt->usedspace,False,_numeric));
609
d_printf("Soft Limit: %15s\n",quota_str_static(qt->softlim,True,_numeric));
610
d_printf("Hard Limit: %15s\n",quota_str_static(qt->hardlim,True,_numeric));
612
d_printf("%-30s: ",username_str);
613
d_printf("%15s/",quota_str_static(qt->usedspace,False,_numeric));
614
d_printf("%15s/",quota_str_static(qt->softlim,True,_numeric));
615
d_printf("%15s\n",quota_str_static(qt->hardlim,True,_numeric));
620
d_printf("dump_ntquota() invalid qtype(%d)\n",qt->qtype);
625
void dump_ntquota_list(SMB_NTQUOTA_LIST **qtl, BOOL _verbose, BOOL _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, BOOL _numeric))
627
SMB_NTQUOTA_LIST *cur;
629
for (cur = *qtl;cur;cur = cur->next) {
631
dump_ntquota(cur->quotas,_verbose,_numeric,_sidtostring);