00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "includes.h"
00022
00023 BOOL cli_get_quota_handle(struct cli_state *cli, int *quota_fnum)
00024 {
00025 *quota_fnum = cli_nt_create_full(cli, FAKE_FILE_NAME_QUOTA_WIN32,
00026 0x00000016, DESIRED_ACCESS_PIPE,
00027 0x00000000, FILE_SHARE_READ|FILE_SHARE_WRITE,
00028 FILE_OPEN, 0x00000000, 0x03);
00029
00030 if (*quota_fnum == (-1)) {
00031 return False;
00032 }
00033
00034 return True;
00035 }
00036
00037 void free_ntquota_list(SMB_NTQUOTA_LIST **qt_list)
00038 {
00039 if (!qt_list)
00040 return;
00041
00042 if ((*qt_list)->mem_ctx)
00043 talloc_destroy((*qt_list)->mem_ctx);
00044
00045 (*qt_list) = NULL;
00046
00047 return;
00048 }
00049
00050 static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, unsigned int *offset, SMB_NTQUOTA_STRUCT *pqt)
00051 {
00052 int sid_len;
00053 SMB_NTQUOTA_STRUCT qt;
00054
00055 ZERO_STRUCT(qt);
00056
00057 if (!rdata||!offset||!pqt)
00058 smb_panic("parse_quota_record: called with NULL POINTER!\n");
00059
00060 if (rdata_count < 40) {
00061 return False;
00062 }
00063
00064
00065
00066
00067
00068 *offset = IVAL(rdata,0);
00069
00070
00071 sid_len = IVAL(rdata,4);
00072
00073 if (rdata_count < 40+sid_len) {
00074 return False;
00075 }
00076
00077
00078
00079
00080
00081
00082 qt.usedspace = (SMB_BIG_UINT)IVAL(rdata,16);
00083 #ifdef LARGE_SMB_OFF_T
00084 qt.usedspace |= (((SMB_BIG_UINT)IVAL(rdata,20)) << 32);
00085 #else
00086 if ((IVAL(rdata,20) != 0)&&
00087 ((qt.usedspace != 0xFFFFFFFF)||
00088 (IVAL(rdata,20)!=0xFFFFFFFF))) {
00089
00090 return False;
00091 }
00092 #endif
00093
00094
00095 qt.softlim = (SMB_BIG_UINT)IVAL(rdata,24);
00096 #ifdef LARGE_SMB_OFF_T
00097 qt.softlim |= (((SMB_BIG_UINT)IVAL(rdata,28)) << 32);
00098 #else
00099 if ((IVAL(rdata,28) != 0)&&
00100 ((qt.softlim != 0xFFFFFFFF)||
00101 (IVAL(rdata,28)!=0xFFFFFFFF))) {
00102
00103 return False;
00104 }
00105 #endif
00106
00107
00108 qt.hardlim = (SMB_BIG_UINT)IVAL(rdata,32);
00109 #ifdef LARGE_SMB_OFF_T
00110 qt.hardlim |= (((SMB_BIG_UINT)IVAL(rdata,36)) << 32);
00111 #else
00112 if ((IVAL(rdata,36) != 0)&&
00113 ((qt.hardlim != 0xFFFFFFFF)||
00114 (IVAL(rdata,36)!=0xFFFFFFFF))) {
00115
00116 return False;
00117 }
00118 #endif
00119
00120 sid_parse(rdata+40,sid_len,&qt.sid);
00121
00122 qt.qtype = SMB_USER_QUOTA_TYPE;
00123
00124 *pqt = qt;
00125
00126 return True;
00127 }
00128
00129 BOOL cli_get_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt)
00130 {
00131 BOOL ret = False;
00132 uint16 setup;
00133 char params[16];
00134 unsigned int data_len;
00135 char data[SID_MAX_SIZE+8];
00136 char *rparam=NULL, *rdata=NULL;
00137 unsigned int rparam_count=0, rdata_count=0;
00138 unsigned int sid_len;
00139 unsigned int offset;
00140
00141 if (!cli||!pqt)
00142 smb_panic("cli_get_user_quota() called with NULL Pointer!");
00143
00144 setup = NT_TRANSACT_GET_USER_QUOTA;
00145
00146 SSVAL(params, 0,quota_fnum);
00147 SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_FOR_SID);
00148 SIVAL(params, 4,0x00000024);
00149 SIVAL(params, 8,0x00000000);
00150 SIVAL(params,12,0x00000024);
00151
00152 sid_len = sid_size(&pqt->sid);
00153 data_len = sid_len+8;
00154 SIVAL(data, 0, 0x00000000);
00155 SIVAL(data, 4, sid_len);
00156 sid_linearize(data+8, sid_len, &pqt->sid);
00157
00158 if (!cli_send_nt_trans(cli,
00159 NT_TRANSACT_GET_USER_QUOTA,
00160 0,
00161 &setup, 1, 0,
00162 params, 16, 4,
00163 data, data_len, 112)) {
00164 DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n"));
00165 goto cleanup;
00166 }
00167
00168
00169 if (!cli_receive_nt_trans(cli,
00170 &rparam, &rparam_count,
00171 &rdata, &rdata_count)) {
00172 DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n"));
00173 goto cleanup;
00174 }
00175
00176 if (cli_is_error(cli)) {
00177 ret = False;
00178 goto cleanup;
00179 } else {
00180 ret = True;
00181 }
00182
00183 if ((rparam&&rdata)&&(rparam_count>=4&&rdata_count>=8)) {
00184 ret = parse_user_quota_record(rdata, rdata_count, &offset, pqt);
00185 } else {
00186 DEBUG(0,("Got INVALID NT_TRANSACT_GET_USER_QUOTA reply.\n"));
00187 ret = False;
00188 }
00189
00190 cleanup:
00191 SAFE_FREE(rparam);
00192 SAFE_FREE(rdata);
00193 return ret;
00194 }
00195
00196 BOOL cli_set_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt)
00197 {
00198 BOOL ret = False;
00199 uint16 setup;
00200 char params[2];
00201 char data[112];
00202 char *rparam=NULL, *rdata=NULL;
00203 unsigned int rparam_count=0, rdata_count=0;
00204 unsigned int sid_len;
00205 memset(data,'\0',112);
00206
00207 if (!cli||!pqt)
00208 smb_panic("cli_set_user_quota() called with NULL Pointer!");
00209
00210 setup = NT_TRANSACT_SET_USER_QUOTA;
00211
00212 SSVAL(params,0,quota_fnum);
00213
00214 sid_len = sid_size(&pqt->sid);
00215 SIVAL(data,0,0);
00216 SIVAL(data,4,sid_len);
00217 SBIG_UINT(data, 8,(SMB_BIG_UINT)0);
00218 SBIG_UINT(data,16,pqt->usedspace);
00219 SBIG_UINT(data,24,pqt->softlim);
00220 SBIG_UINT(data,32,pqt->hardlim);
00221 sid_linearize(data+40, sid_len, &pqt->sid);
00222
00223 if (!cli_send_nt_trans(cli,
00224 NT_TRANSACT_SET_USER_QUOTA,
00225 0,
00226 &setup, 1, 0,
00227 params, 2, 0,
00228 data, 112, 0)) {
00229 DEBUG(1,("Failed to send NT_TRANSACT_SET_USER_QUOTA\n"));
00230 goto cleanup;
00231 }
00232
00233
00234 if (!cli_receive_nt_trans(cli,
00235 &rparam, &rparam_count,
00236 &rdata, &rdata_count)) {
00237 DEBUG(1,("NT_TRANSACT_SET_USER_QUOTA failed\n"));
00238 goto cleanup;
00239 }
00240
00241 if (cli_is_error(cli)) {
00242 ret = False;
00243 goto cleanup;
00244 } else {
00245 ret = True;
00246 }
00247
00248 cleanup:
00249 SAFE_FREE(rparam);
00250 SAFE_FREE(rdata);
00251 return ret;
00252 }
00253
00254 BOOL cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST **pqt_list)
00255 {
00256 BOOL ret = False;
00257 uint16 setup;
00258 char params[16];
00259 char *rparam=NULL, *rdata=NULL;
00260 unsigned int rparam_count=0, rdata_count=0;
00261 unsigned int offset;
00262 const char *curdata = NULL;
00263 unsigned int curdata_count = 0;
00264 TALLOC_CTX *mem_ctx = NULL;
00265 SMB_NTQUOTA_STRUCT qt;
00266 SMB_NTQUOTA_LIST *tmp_list_ent;
00267
00268 if (!cli||!pqt_list)
00269 smb_panic("cli_list_user_quota() called with NULL Pointer!");
00270
00271 setup = NT_TRANSACT_GET_USER_QUOTA;
00272
00273 SSVAL(params, 0,quota_fnum);
00274 SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_START);
00275 SIVAL(params, 4,0x00000000);
00276 SIVAL(params, 8,0x00000000);
00277 SIVAL(params,12,0x00000000);
00278
00279 if (!cli_send_nt_trans(cli,
00280 NT_TRANSACT_GET_USER_QUOTA,
00281 0,
00282 &setup, 1, 0,
00283 params, 16, 4,
00284 NULL, 0, 2048)) {
00285 DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n"));
00286 goto cleanup;
00287 }
00288
00289
00290 if (!cli_receive_nt_trans(cli,
00291 &rparam, &rparam_count,
00292 &rdata, &rdata_count)) {
00293 DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n"));
00294 goto cleanup;
00295 }
00296
00297 if (cli_is_error(cli)) {
00298 ret = False;
00299 goto cleanup;
00300 } else {
00301 ret = True;
00302 }
00303
00304 if (rdata_count == 0) {
00305 *pqt_list = NULL;
00306 return True;
00307 }
00308
00309 if ((mem_ctx=talloc_init("SMB_USER_QUOTA_LIST"))==NULL) {
00310 DEBUG(0,("talloc_init() failed\n"));
00311 return (-1);
00312 }
00313
00314 offset = 1;
00315 for (curdata=rdata,curdata_count=rdata_count;
00316 ((curdata)&&(curdata_count>=8)&&(offset>0));
00317 curdata +=offset,curdata_count -= offset) {
00318 ZERO_STRUCT(qt);
00319 if (!parse_user_quota_record(curdata, curdata_count, &offset, &qt)) {
00320 DEBUG(1,("Failed to parse the quota record\n"));
00321 goto cleanup;
00322 }
00323
00324 if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) {
00325 DEBUG(0,("TALLOC_ZERO() failed\n"));
00326 talloc_destroy(mem_ctx);
00327 return (-1);
00328 }
00329
00330 if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) {
00331 DEBUG(0,("TALLOC_ZERO() failed\n"));
00332 talloc_destroy(mem_ctx);
00333 return (-1);
00334 }
00335
00336 memcpy(tmp_list_ent->quotas,&qt,sizeof(qt));
00337 tmp_list_ent->mem_ctx = mem_ctx;
00338
00339 DLIST_ADD((*pqt_list),tmp_list_ent);
00340 }
00341
00342 SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_CONTINUE);
00343 while(1) {
00344 if (!cli_send_nt_trans(cli,
00345 NT_TRANSACT_GET_USER_QUOTA,
00346 0,
00347 &setup, 1, 0,
00348 params, 16, 4,
00349 NULL, 0, 2048)) {
00350 DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n"));
00351 goto cleanup;
00352 }
00353
00354 SAFE_FREE(rparam);
00355 SAFE_FREE(rdata);
00356 if (!cli_receive_nt_trans(cli,
00357 &rparam, &rparam_count,
00358 &rdata, &rdata_count)) {
00359 DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n"));
00360 goto cleanup;
00361 }
00362
00363 if (cli_is_error(cli)) {
00364 ret = False;
00365 goto cleanup;
00366 } else {
00367 ret = True;
00368 }
00369
00370 if (rdata_count == 0) {
00371 break;
00372 }
00373
00374 offset = 1;
00375 for (curdata=rdata,curdata_count=rdata_count;
00376 ((curdata)&&(curdata_count>=8)&&(offset>0));
00377 curdata +=offset,curdata_count -= offset) {
00378 ZERO_STRUCT(qt);
00379 if (!parse_user_quota_record(curdata, curdata_count, &offset, &qt)) {
00380 DEBUG(1,("Failed to parse the quota record\n"));
00381 goto cleanup;
00382 }
00383
00384 if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) {
00385 DEBUG(0,("TALLOC_ZERO() failed\n"));
00386 talloc_destroy(mem_ctx);
00387 goto cleanup;
00388 }
00389
00390 if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) {
00391 DEBUG(0,("TALLOC_ZERO() failed\n"));
00392 talloc_destroy(mem_ctx);
00393 goto cleanup;
00394 }
00395
00396 memcpy(tmp_list_ent->quotas,&qt,sizeof(qt));
00397 tmp_list_ent->mem_ctx = mem_ctx;
00398
00399 DLIST_ADD((*pqt_list),tmp_list_ent);
00400 }
00401 }
00402
00403
00404 ret = True;
00405 cleanup:
00406 SAFE_FREE(rparam);
00407 SAFE_FREE(rdata);
00408
00409 return ret;
00410 }
00411
00412 BOOL cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt)
00413 {
00414 BOOL ret = False;
00415 uint16 setup;
00416 char param[2];
00417 char *rparam=NULL, *rdata=NULL;
00418 unsigned int rparam_count=0, rdata_count=0;
00419 SMB_NTQUOTA_STRUCT qt;
00420 ZERO_STRUCT(qt);
00421
00422 if (!cli||!pqt)
00423 smb_panic("cli_get_fs_quota_info() called with NULL Pointer!");
00424
00425 setup = TRANSACT2_QFSINFO;
00426
00427 SSVAL(param,0,SMB_FS_QUOTA_INFORMATION);
00428
00429 if (!cli_send_trans(cli, SMBtrans2,
00430 NULL,
00431 0, 0,
00432 &setup, 1, 0,
00433 param, 2, 0,
00434 NULL, 0, 560)) {
00435 goto cleanup;
00436 }
00437
00438 if (!cli_receive_trans(cli, SMBtrans2,
00439 &rparam, &rparam_count,
00440 &rdata, &rdata_count)) {
00441 goto cleanup;
00442 }
00443
00444 if (cli_is_error(cli)) {
00445 ret = False;
00446 goto cleanup;
00447 } else {
00448 ret = True;
00449 }
00450
00451 if (rdata_count < 48) {
00452 goto cleanup;
00453 }
00454
00455
00456
00457
00458 qt.softlim = (SMB_BIG_UINT)IVAL(rdata,24);
00459 #ifdef LARGE_SMB_OFF_T
00460 qt.softlim |= (((SMB_BIG_UINT)IVAL(rdata,28)) << 32);
00461 #else
00462 if ((IVAL(rdata,28) != 0)&&
00463 ((qt.softlim != 0xFFFFFFFF)||
00464 (IVAL(rdata,28)!=0xFFFFFFFF))) {
00465
00466 goto cleanup;
00467 }
00468 #endif
00469
00470
00471 qt.hardlim = (SMB_BIG_UINT)IVAL(rdata,32);
00472 #ifdef LARGE_SMB_OFF_T
00473 qt.hardlim |= (((SMB_BIG_UINT)IVAL(rdata,36)) << 32);
00474 #else
00475 if ((IVAL(rdata,36) != 0)&&
00476 ((qt.hardlim != 0xFFFFFFFF)||
00477 (IVAL(rdata,36)!=0xFFFFFFFF))) {
00478
00479 goto cleanup;
00480 }
00481 #endif
00482
00483
00484 qt.qflags = SVAL(rdata,40);
00485
00486 qt.qtype = SMB_USER_FS_QUOTA_TYPE;
00487
00488 *pqt = qt;
00489
00490 ret = True;
00491 cleanup:
00492 SAFE_FREE(rparam);
00493 SAFE_FREE(rdata);
00494
00495 return ret;
00496 }
00497
00498 BOOL cli_set_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt)
00499 {
00500 BOOL ret = False;
00501 uint16 setup;
00502 char param[4];
00503 char data[48];
00504 char *rparam=NULL, *rdata=NULL;
00505 unsigned int rparam_count=0, rdata_count=0;
00506 SMB_NTQUOTA_STRUCT qt;
00507 ZERO_STRUCT(qt);
00508 memset(data,'\0',48);
00509
00510 if (!cli||!pqt)
00511 smb_panic("cli_set_fs_quota_info() called with NULL Pointer!");
00512
00513 setup = TRANSACT2_SETFSINFO;
00514
00515 SSVAL(param,0,quota_fnum);
00516 SSVAL(param,2,SMB_FS_QUOTA_INFORMATION);
00517
00518
00519
00520
00521 SBIG_UINT(data,24,pqt->softlim);
00522
00523
00524 SBIG_UINT(data,32,pqt->hardlim);
00525
00526
00527 SSVAL(data,40,pqt->qflags);
00528
00529
00530
00531 if (!cli_send_trans(cli, SMBtrans2,
00532 NULL,
00533 0, 0,
00534 &setup, 1, 0,
00535 param, 4, 0,
00536 data, 48, 0)) {
00537 goto cleanup;
00538 }
00539
00540 if (!cli_receive_trans(cli, SMBtrans2,
00541 &rparam, &rparam_count,
00542 &rdata, &rdata_count)) {
00543 goto cleanup;
00544 }
00545
00546 if (cli_is_error(cli)) {
00547 ret = False;
00548 goto cleanup;
00549 } else {
00550 ret = True;
00551 }
00552
00553 cleanup:
00554 SAFE_FREE(rparam);
00555 SAFE_FREE(rdata);
00556
00557 return ret;
00558 }
00559
00560 static char *quota_str_static(SMB_BIG_UINT val, BOOL special, BOOL _numeric)
00561 {
00562 static fstring buffer;
00563
00564 memset(buffer,'\0',sizeof(buffer));
00565
00566 if (!_numeric&&special&&(val == SMB_NTQUOTAS_NO_LIMIT)) {
00567 fstr_sprintf(buffer,"NO LIMIT");
00568 return buffer;
00569 }
00570 #if defined(HAVE_LONGLONG)
00571 fstr_sprintf(buffer,"%llu",val);
00572 #else
00573 fstr_sprintf(buffer,"%lu",val);
00574 #endif
00575 return buffer;
00576 }
00577
00578 void dump_ntquota(SMB_NTQUOTA_STRUCT *qt, BOOL _verbose, BOOL _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, BOOL _numeric))
00579 {
00580 if (!qt)
00581 smb_panic("dump_ntquota() called with NULL pointer");
00582
00583 switch (qt->qtype) {
00584 case SMB_USER_FS_QUOTA_TYPE:
00585 {
00586 d_printf("File System QUOTAS:\n");
00587 d_printf("Limits:\n");
00588 d_printf(" Default Soft Limit: %15s\n",quota_str_static(qt->softlim,True,_numeric));
00589 d_printf(" Default Hard Limit: %15s\n",quota_str_static(qt->hardlim,True,_numeric));
00590 d_printf("Quota Flags:\n");
00591 d_printf(" Quotas Enabled: %s\n",
00592 ((qt->qflags"AS_ENABLED)||(qt->qflags"AS_DENY_DISK))?"On":"Off");
00593 d_printf(" Deny Disk: %s\n",(qt->qflags"AS_DENY_DISK)?"On":"Off");
00594 d_printf(" Log Soft Limit: %s\n",(qt->qflags"AS_LOG_THRESHOLD)?"On":"Off");
00595 d_printf(" Log Hard Limit: %s\n",(qt->qflags"AS_LOG_LIMIT)?"On":"Off");
00596 }
00597 break;
00598 case SMB_USER_QUOTA_TYPE:
00599 {
00600 fstring username_str = {0};
00601
00602 if (_sidtostring) {
00603 _sidtostring(username_str,&qt->sid,_numeric);
00604 } else {
00605 fstrcpy(username_str,sid_string_static(&qt->sid));
00606 }
00607
00608 if (_verbose) {
00609 d_printf("Quotas for User: %s\n",username_str);
00610 d_printf("Used Space: %15s\n",quota_str_static(qt->usedspace,False,_numeric));
00611 d_printf("Soft Limit: %15s\n",quota_str_static(qt->softlim,True,_numeric));
00612 d_printf("Hard Limit: %15s\n",quota_str_static(qt->hardlim,True,_numeric));
00613 } else {
00614 d_printf("%-30s: ",username_str);
00615 d_printf("%15s/",quota_str_static(qt->usedspace,False,_numeric));
00616 d_printf("%15s/",quota_str_static(qt->softlim,True,_numeric));
00617 d_printf("%15s\n",quota_str_static(qt->hardlim,True,_numeric));
00618 }
00619 }
00620 break;
00621 default:
00622 d_printf("dump_ntquota() invalid qtype(%d)\n",qt->qtype);
00623 return;
00624 }
00625 }
00626
00627 void dump_ntquota_list(SMB_NTQUOTA_LIST **qtl, BOOL _verbose, BOOL _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, BOOL _numeric))
00628 {
00629 SMB_NTQUOTA_LIST *cur;
00630
00631 for (cur = *qtl;cur;cur = cur->next) {
00632 if (cur->quotas)
00633 dump_ntquota(cur->quotas,_verbose,_numeric,_sidtostring);
00634 }
00635 }