00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "includes.h"
00026
00027 static pstring server;
00028
00029
00030
00031 static BOOL numeric;
00032 static BOOL verbose;
00033
00034 enum todo_values {NOOP_QUOTA=0,FS_QUOTA,USER_QUOTA,LIST_QUOTA,SET_QUOTA};
00035 enum exit_values {EXIT_OK, EXIT_FAILED, EXIT_PARSE_ERROR};
00036
00037 static struct cli_state *cli_ipc;
00038 static struct rpc_pipe_client *global_pipe_hnd;
00039 static POLICY_HND pol;
00040 static BOOL got_policy_hnd;
00041
00042 static struct cli_state *connect_one(const char *share);
00043
00044
00045
00046 static BOOL cli_open_policy_hnd(void)
00047 {
00048
00049
00050 if (!cli_ipc) {
00051 NTSTATUS ret;
00052 cli_ipc = connect_one("IPC$");
00053 global_pipe_hnd = cli_rpc_pipe_open_noauth(cli_ipc, PI_LSARPC, &ret);
00054 if (!global_pipe_hnd) {
00055 return False;
00056 }
00057 }
00058
00059
00060
00061 if (!got_policy_hnd) {
00062
00063
00064
00065
00066 if (!NT_STATUS_IS_OK(rpccli_lsa_open_policy(global_pipe_hnd, cli_ipc->mem_ctx, True,
00067 GENERIC_EXECUTE_ACCESS, &pol))) {
00068 return False;
00069 }
00070
00071 got_policy_hnd = True;
00072 }
00073
00074 return True;
00075 }
00076
00077
00078 static void SidToString(fstring str, DOM_SID *sid, BOOL _numeric)
00079 {
00080 char **domains = NULL;
00081 char **names = NULL;
00082 enum lsa_SidType *types = NULL;
00083
00084 sid_to_string(str, sid);
00085
00086 if (_numeric) return;
00087
00088
00089
00090 if (!cli_open_policy_hnd() ||
00091 !NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(global_pipe_hnd, cli_ipc->mem_ctx,
00092 &pol, 1, sid, &domains,
00093 &names, &types)) ||
00094 !domains || !domains[0] || !names || !names[0]) {
00095 return;
00096 }
00097
00098
00099
00100 slprintf(str, sizeof(fstring) - 1, "%s%s%s",
00101 domains[0], lp_winbind_separator(),
00102 names[0]);
00103
00104 }
00105
00106
00107 static BOOL StringToSid(DOM_SID *sid, const char *str)
00108 {
00109 enum lsa_SidType *types = NULL;
00110 DOM_SID *sids = NULL;
00111 BOOL result = True;
00112
00113 if (strncmp(str, "S-", 2) == 0) {
00114 return string_to_sid(sid, str);
00115 }
00116
00117 if (!cli_open_policy_hnd() ||
00118 !NT_STATUS_IS_OK(rpccli_lsa_lookup_names(global_pipe_hnd, cli_ipc->mem_ctx,
00119 &pol, 1, &str, NULL, &sids,
00120 &types))) {
00121 result = False;
00122 goto done;
00123 }
00124
00125 sid_copy(sid, &sids[0]);
00126 done:
00127
00128 return result;
00129 }
00130
00131 #define QUOTA_GET 1
00132 #define QUOTA_SETLIM 2
00133 #define QUOTA_SETFLAGS 3
00134 #define QUOTA_LIST 4
00135
00136 enum {PARSE_FLAGS,PARSE_LIM};
00137
00138 static int parse_quota_set(pstring set_str, pstring username_str, enum SMB_QUOTA_TYPE *qtype, int *cmd, SMB_NTQUOTA_STRUCT *pqt)
00139 {
00140 char *p = set_str,*p2;
00141 int todo;
00142 BOOL stop = False;
00143 BOOL enable = False;
00144 BOOL deny = False;
00145
00146 if (strnequal(set_str,"UQLIM:",6)) {
00147 p += 6;
00148 *qtype = SMB_USER_QUOTA_TYPE;
00149 *cmd = QUOTA_SETLIM;
00150 todo = PARSE_LIM;
00151 if ((p2=strstr(p,":"))==NULL) {
00152 return -1;
00153 }
00154
00155 *p2 = '\0';
00156 p2++;
00157
00158 fstrcpy(username_str,p);
00159 p = p2;
00160 } else if (strnequal(set_str,"FSQLIM:",7)) {
00161 p +=7;
00162 *qtype = SMB_USER_FS_QUOTA_TYPE;
00163 *cmd = QUOTA_SETLIM;
00164 todo = PARSE_LIM;
00165 } else if (strnequal(set_str,"FSQFLAGS:",9)) {
00166 p +=9;
00167 todo = PARSE_FLAGS;
00168 *qtype = SMB_USER_FS_QUOTA_TYPE;
00169 *cmd = QUOTA_SETFLAGS;
00170 } else {
00171 return -1;
00172 }
00173
00174 switch (todo) {
00175 case PARSE_LIM:
00176 #if defined(HAVE_LONGLONG)
00177 if (sscanf(p,"%llu/%llu",&pqt->softlim,&pqt->hardlim)!=2) {
00178 #else
00179 if (sscanf(p,"%lu/%lu",&pqt->softlim,&pqt->hardlim)!=2) {
00180 #endif
00181 return -1;
00182 }
00183
00184 break;
00185 case PARSE_FLAGS:
00186 while (!stop) {
00187
00188 if ((p2=strstr(p,"/"))==NULL) {
00189 stop = True;
00190 } else {
00191 *p2 = '\0';
00192 p2++;
00193 }
00194
00195 if (strnequal(p,"QUOTA_ENABLED",13)) {
00196 enable = True;
00197 } else if (strnequal(p,"DENY_DISK",9)) {
00198 deny = True;
00199 } else if (strnequal(p,"LOG_SOFTLIMIT",13)) {
00200 pqt->qflags |= QUOTAS_LOG_THRESHOLD;
00201 } else if (strnequal(p,"LOG_HARDLIMIT",13)) {
00202 pqt->qflags |= QUOTAS_LOG_LIMIT;
00203 } else {
00204 return -1;
00205 }
00206
00207 p=p2;
00208 }
00209
00210 if (deny) {
00211 pqt->qflags |= QUOTAS_DENY_DISK;
00212 } else if (enable) {
00213 pqt->qflags |= QUOTAS_ENABLED;
00214 }
00215
00216 break;
00217 }
00218
00219 return 0;
00220 }
00221
00222 static int do_quota(struct cli_state *cli, enum SMB_QUOTA_TYPE qtype, uint16 cmd, pstring username_str, SMB_NTQUOTA_STRUCT *pqt)
00223 {
00224 uint32 fs_attrs = 0;
00225 int quota_fnum = 0;
00226 SMB_NTQUOTA_LIST *qtl = NULL;
00227 SMB_NTQUOTA_STRUCT qt;
00228 ZERO_STRUCT(qt);
00229
00230 if (!cli_get_fs_attr_info(cli, &fs_attrs)) {
00231 d_printf("Failed to get the filesystem attributes %s.\n",
00232 cli_errstr(cli));
00233 return -1;
00234 }
00235
00236 if (!(fs_attrs & FILE_VOLUME_QUOTAS)) {
00237 d_printf("Quotas are not supported by the server.\n");
00238 return 0;
00239 }
00240
00241 if (!cli_get_quota_handle(cli, "a_fnum)) {
00242 d_printf("Quotas are not enabled on this share.\n");
00243 d_printf("Failed to open %s %s.\n",
00244 FAKE_FILE_NAME_QUOTA_WIN32,cli_errstr(cli));
00245 return -1;
00246 }
00247
00248 switch(qtype) {
00249 case SMB_USER_QUOTA_TYPE:
00250 if (!StringToSid(&qt.sid, username_str)) {
00251 d_printf("StringToSid() failed for [%s]\n",username_str);
00252 return -1;
00253 }
00254
00255 switch(cmd) {
00256 case QUOTA_GET:
00257 if (!cli_get_user_quota(cli, quota_fnum, &qt)) {
00258 d_printf("%s cli_get_user_quota %s\n",
00259 cli_errstr(cli),username_str);
00260 return -1;
00261 }
00262 dump_ntquota(&qt,verbose,numeric,SidToString);
00263 break;
00264 case QUOTA_SETLIM:
00265 pqt->sid = qt.sid;
00266 if (!cli_set_user_quota(cli, quota_fnum, pqt)) {
00267 d_printf("%s cli_set_user_quota %s\n",
00268 cli_errstr(cli),username_str);
00269 return -1;
00270 }
00271 if (!cli_get_user_quota(cli, quota_fnum, &qt)) {
00272 d_printf("%s cli_get_user_quota %s\n",
00273 cli_errstr(cli),username_str);
00274 return -1;
00275 }
00276 dump_ntquota(&qt,verbose,numeric,SidToString);
00277 break;
00278 case QUOTA_LIST:
00279 if (!cli_list_user_quota(cli, quota_fnum, &qtl)) {
00280 d_printf("%s cli_set_user_quota %s\n",
00281 cli_errstr(cli),username_str);
00282 return -1;
00283 }
00284 dump_ntquota_list(&qtl,verbose,numeric,SidToString);
00285 free_ntquota_list(&qtl);
00286 break;
00287 default:
00288 d_printf("Unknown Error\n");
00289 return -1;
00290 }
00291 break;
00292 case SMB_USER_FS_QUOTA_TYPE:
00293 switch(cmd) {
00294 case QUOTA_GET:
00295 if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
00296 d_printf("%s cli_get_fs_quota_info\n",
00297 cli_errstr(cli));
00298 return -1;
00299 }
00300 dump_ntquota(&qt,True,numeric,NULL);
00301 break;
00302 case QUOTA_SETLIM:
00303 if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
00304 d_printf("%s cli_get_fs_quota_info\n",
00305 cli_errstr(cli));
00306 return -1;
00307 }
00308 qt.softlim = pqt->softlim;
00309 qt.hardlim = pqt->hardlim;
00310 if (!cli_set_fs_quota_info(cli, quota_fnum, &qt)) {
00311 d_printf("%s cli_set_fs_quota_info\n",
00312 cli_errstr(cli));
00313 return -1;
00314 }
00315 if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
00316 d_printf("%s cli_get_fs_quota_info\n",
00317 cli_errstr(cli));
00318 return -1;
00319 }
00320 dump_ntquota(&qt,True,numeric,NULL);
00321 break;
00322 case QUOTA_SETFLAGS:
00323 if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
00324 d_printf("%s cli_get_fs_quota_info\n",
00325 cli_errstr(cli));
00326 return -1;
00327 }
00328 qt.qflags = pqt->qflags;
00329 if (!cli_set_fs_quota_info(cli, quota_fnum, &qt)) {
00330 d_printf("%s cli_set_fs_quota_info\n",
00331 cli_errstr(cli));
00332 return -1;
00333 }
00334 if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) {
00335 d_printf("%s cli_get_fs_quota_info\n",
00336 cli_errstr(cli));
00337 return -1;
00338 }
00339 dump_ntquota(&qt,True,numeric,NULL);
00340 break;
00341 default:
00342 d_printf("Unknown Error\n");
00343 return -1;
00344 }
00345 break;
00346 default:
00347 d_printf("Unknown Error\n");
00348 return -1;
00349 }
00350
00351 cli_close(cli, quota_fnum);
00352
00353 return 0;
00354 }
00355
00356
00357
00358
00359 static struct cli_state *connect_one(const char *share)
00360 {
00361 struct cli_state *c;
00362 struct in_addr ip;
00363 NTSTATUS nt_status;
00364 zero_ip(&ip);
00365
00366 if (!cmdline_auth_info.got_pass) {
00367 char *pass = getpass("Password: ");
00368 if (pass) {
00369 pstrcpy(cmdline_auth_info.password, pass);
00370 cmdline_auth_info.got_pass = True;
00371 }
00372 }
00373
00374 if (NT_STATUS_IS_OK(nt_status = cli_full_connection(&c, global_myname(), server,
00375 &ip, 0,
00376 share, "?????",
00377 cmdline_auth_info.username, lp_workgroup(),
00378 cmdline_auth_info.password, 0,
00379 cmdline_auth_info.signing_state, NULL))) {
00380 return c;
00381 } else {
00382 DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status)));
00383 return NULL;
00384 }
00385 }
00386
00387
00388
00389
00390 int main(int argc, const char *argv[])
00391 {
00392 char *share;
00393 int opt;
00394 int result;
00395 int todo = 0;
00396 pstring username_str = {0};
00397 pstring path = {0};
00398 pstring set_str = {0};
00399 enum SMB_QUOTA_TYPE qtype = SMB_INVALID_QUOTA_TYPE;
00400 int cmd = 0;
00401 static BOOL test_args = False;
00402 struct cli_state *cli;
00403 BOOL fix_user = False;
00404 SMB_NTQUOTA_STRUCT qt;
00405 poptContext pc;
00406 struct poptOption long_options[] = {
00407 POPT_AUTOHELP
00408 { "user", 'u', POPT_ARG_STRING, NULL, 'u', "Show quotas for user", "user" },
00409 { "list", 'L', POPT_ARG_NONE, NULL, 'L', "List user quotas" },
00410 { "fs", 'F', POPT_ARG_NONE, NULL, 'F', "Show filesystem quotas" },
00411 { "set", 'S', POPT_ARG_STRING, NULL, 'S', "Set acls\n\
00412 SETSTRING:\n\
00413 UQLIM:<username>/<softlimit>/<hardlimit> for user quotas\n\
00414 FSQLIM:<softlimit>/<hardlimit> for filesystem defaults\n\
00415 FSQFLAGS:QUOTA_ENABLED/DENY_DISK/LOG_SOFTLIMIT/LOG_HARD_LIMIT", "SETSTRING" },
00416 { "numeric", 'n', POPT_ARG_NONE, &numeric, True, "Don't resolve sids or limits to names" },
00417 { "verbose", 'v', POPT_ARG_NONE, &verbose, True, "be verbose" },
00418 { "test-args", 't', POPT_ARG_NONE, &test_args, True, "Test arguments"},
00419 POPT_COMMON_SAMBA
00420 POPT_COMMON_CREDENTIALS
00421 { NULL }
00422 };
00423
00424 load_case_tables();
00425
00426 ZERO_STRUCT(qt);
00427
00428
00429 setup_logging( "smbcquotas", True );
00430 DEBUGLEVEL_CLASS[DBGC_ALL] = 1;
00431 dbf = x_stderr;
00432 x_setbuf( x_stderr, NULL );
00433
00434 setlinebuf(stdout);
00435
00436 fault_setup(NULL);
00437
00438 lp_load(dyn_CONFIGFILE,True,False,False,True);
00439 load_interfaces();
00440
00441 pc = poptGetContext("smbcquotas", argc, argv, long_options, 0);
00442
00443 poptSetOtherOptionHelp(pc, "//server1/share1");
00444
00445 while ((opt = poptGetNextOpt(pc)) != -1) {
00446 switch (opt) {
00447 case 'L':
00448 if (todo != 0) {
00449 d_printf("Please specify only one option of <-L|-F|-S|-u>\n");
00450 exit(EXIT_PARSE_ERROR);
00451 }
00452 todo = LIST_QUOTA;
00453 break;
00454
00455 case 'F':
00456 if (todo != 0) {
00457 d_printf("Please specify only one option of <-L|-F|-S|-u>\n");
00458 exit(EXIT_PARSE_ERROR);
00459 }
00460 todo = FS_QUOTA;
00461 break;
00462
00463 case 'u':
00464 if (todo != 0) {
00465 d_printf("Please specify only one option of <-L|-F|-S|-u>\n");
00466 exit(EXIT_PARSE_ERROR);
00467 }
00468 pstrcpy(username_str,poptGetOptArg(pc));
00469 todo = USER_QUOTA;
00470 fix_user = True;
00471 break;
00472
00473 case 'S':
00474 if (todo != 0) {
00475 d_printf("Please specify only one option of <-L|-F|-S|-u>\n");
00476 exit(EXIT_PARSE_ERROR);
00477 }
00478 pstrcpy(set_str,poptGetOptArg(pc));
00479 todo = SET_QUOTA;
00480 break;
00481 }
00482 }
00483
00484 if (todo == 0)
00485 todo = USER_QUOTA;
00486
00487 if (!fix_user)
00488 pstrcpy(username_str,cmdline_auth_info.username);
00489
00490
00491 if(!poptPeekArg(pc)) {
00492 poptPrintUsage(pc, stderr, 0);
00493 exit(EXIT_PARSE_ERROR);
00494 }
00495
00496 pstrcpy(path, poptGetArg(pc));
00497
00498 all_string_sub(path,"/","\\",0);
00499
00500 pstrcpy(server,path+2);
00501 share = strchr_m(server,'\\');
00502 if (!share) {
00503 share = strchr_m(server,'/');
00504 if (!share) {
00505 printf("Invalid argument: %s\n", share);
00506 exit(EXIT_PARSE_ERROR);
00507 }
00508 }
00509
00510 *share = 0;
00511 share++;
00512
00513 if (todo == SET_QUOTA) {
00514 if (parse_quota_set(set_str, username_str, &qtype, &cmd, &qt)) {
00515 printf("Invalid argument: -S %s\n", set_str);
00516 exit(EXIT_PARSE_ERROR);
00517 }
00518 }
00519
00520 if (!test_args) {
00521 cli = connect_one(share);
00522 if (!cli) {
00523 exit(EXIT_FAILED);
00524 }
00525 } else {
00526 exit(EXIT_OK);
00527 }
00528
00529
00530
00531
00532 switch (todo) {
00533 case FS_QUOTA:
00534 result = do_quota(cli,SMB_USER_FS_QUOTA_TYPE, QUOTA_GET, username_str, NULL);
00535 break;
00536 case LIST_QUOTA:
00537 result = do_quota(cli,SMB_USER_QUOTA_TYPE, QUOTA_LIST, username_str, NULL);
00538 break;
00539 case USER_QUOTA:
00540 result = do_quota(cli,SMB_USER_QUOTA_TYPE, QUOTA_GET, username_str, NULL);
00541 break;
00542 case SET_QUOTA:
00543 result = do_quota(cli, qtype, cmd, username_str, &qt);
00544 break;
00545 default:
00546
00547 result = EXIT_FAILED;
00548 break;
00549 }
00550
00551 return result;
00552 }
00553