Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : QUOTA get/set utility
4 :
5 : Copyright (C) Andrew Tridgell 2000
6 : Copyright (C) Tim Potter 2000
7 : Copyright (C) Jeremy Allison 2000
8 : Copyright (C) Stefan (metze) Metzmacher 2003
9 :
10 : This program is free software; you can redistribute it and/or modify
11 : it under the terms of the GNU General Public License as published by
12 : the Free Software Foundation; either version 3 of the License, or
13 : (at your option) any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program. If not, see <http://www.gnu.org/licenses/>.
22 : */
23 :
24 : #include "includes.h"
25 : #include "lib/cmdline/cmdline.h"
26 : #include "rpc_client/cli_pipe.h"
27 : #include "../librpc/gen_ndr/ndr_lsa.h"
28 : #include "rpc_client/cli_lsarpc.h"
29 : #include "fake_file.h"
30 : #include "../libcli/security/security.h"
31 : #include "libsmb/libsmb.h"
32 :
33 : static char *server;
34 :
35 : /* numeric is set when the user wants numeric SIDs and ACEs rather
36 : than going via LSA calls to resolve them */
37 : static bool numeric;
38 : static bool verbose;
39 :
40 : enum todo_values {NOOP_QUOTA=0,FS_QUOTA,USER_QUOTA,LIST_QUOTA,SET_QUOTA};
41 : enum exit_values {EXIT_OK, EXIT_FAILED, EXIT_PARSE_ERROR};
42 :
43 : static struct cli_state *cli_ipc;
44 : static struct rpc_pipe_client *global_pipe_hnd;
45 : static struct policy_handle pol;
46 : static bool got_policy_hnd;
47 :
48 : static struct cli_state *connect_one(const char *share);
49 :
50 : /* Open cli connection and policy handle */
51 :
52 84 : static bool cli_open_policy_hnd(void)
53 : {
54 : /* Initialise cli LSA connection */
55 :
56 84 : if (!cli_ipc) {
57 : NTSTATUS ret;
58 16 : cli_ipc = connect_one("IPC$");
59 16 : ret = cli_rpc_pipe_open_noauth(cli_ipc,
60 : &ndr_table_lsarpc,
61 : &global_pipe_hnd);
62 16 : if (!NT_STATUS_IS_OK(ret)) {
63 0 : return False;
64 : }
65 : }
66 :
67 : /* Open policy handle */
68 :
69 84 : if (!got_policy_hnd) {
70 :
71 : /* Some systems don't support SEC_FLAG_MAXIMUM_ALLOWED,
72 : but NT sends 0x2000000 so we might as well do it too. */
73 :
74 16 : if (!NT_STATUS_IS_OK(rpccli_lsa_open_policy(global_pipe_hnd, talloc_tos(), True,
75 : GENERIC_EXECUTE_ACCESS, &pol))) {
76 0 : return False;
77 : }
78 :
79 16 : got_policy_hnd = True;
80 : }
81 :
82 84 : return True;
83 : }
84 :
85 : /* convert a SID to a string, either numeric or username/group */
86 68 : static void SidToString(fstring str, struct dom_sid *sid, bool _numeric)
87 : {
88 68 : char **domains = NULL;
89 68 : char **names = NULL;
90 68 : enum lsa_SidType *types = NULL;
91 :
92 68 : sid_to_fstring(str, sid);
93 :
94 68 : if (_numeric) return;
95 :
96 : /* Ask LSA to convert the sid to a name */
97 :
98 136 : if (!cli_open_policy_hnd() ||
99 68 : !NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(global_pipe_hnd, talloc_tos(),
100 : &pol, 1, sid, &domains,
101 68 : &names, &types)) ||
102 136 : !domains || !domains[0] || !names || !names[0]) {
103 0 : return;
104 : }
105 :
106 : /* Converted OK */
107 :
108 68 : slprintf(str, sizeof(fstring) - 1, "%s%s%s",
109 : domains[0], lp_winbind_separator(),
110 : names[0]);
111 : }
112 :
113 : /* convert a string to a SID, either numeric or username/group */
114 16 : static bool StringToSid(struct dom_sid *sid, const char *str)
115 : {
116 16 : enum lsa_SidType *types = NULL;
117 16 : struct dom_sid *sids = NULL;
118 16 : bool result = True;
119 :
120 16 : if (string_to_sid(sid, str)) {
121 0 : return true;
122 : }
123 :
124 32 : if (!cli_open_policy_hnd() ||
125 16 : !NT_STATUS_IS_OK(rpccli_lsa_lookup_names(global_pipe_hnd, talloc_tos(),
126 : &pol, 1, &str, NULL, 1, &sids,
127 : &types))) {
128 0 : result = False;
129 0 : goto done;
130 : }
131 :
132 16 : sid_copy(sid, &sids[0]);
133 16 : done:
134 :
135 16 : return result;
136 : }
137 :
138 : #define QUOTA_GET 1
139 : #define QUOTA_SETLIM 2
140 : #define QUOTA_SETFLAGS 3
141 : #define QUOTA_LIST 4
142 :
143 : enum {PARSE_FLAGS,PARSE_LIM};
144 :
145 4 : static int parse_quota_set(TALLOC_CTX *ctx,
146 : char *set_str,
147 : char **pp_username_str,
148 : enum SMB_QUOTA_TYPE *qtype,
149 : int *cmd,
150 : SMB_NTQUOTA_STRUCT *pqt)
151 : {
152 4 : char *p = set_str,*p2;
153 : int todo;
154 4 : bool stop = False;
155 4 : bool enable = False;
156 4 : bool deny = False;
157 :
158 4 : *pp_username_str = NULL;
159 4 : if (strnequal(set_str,"UQLIM:",6)) {
160 4 : p += 6;
161 4 : *qtype = SMB_USER_QUOTA_TYPE;
162 4 : *cmd = QUOTA_SETLIM;
163 4 : todo = PARSE_LIM;
164 4 : if ((p2=strstr(p,":"))==NULL) {
165 0 : return -1;
166 : }
167 :
168 4 : *p2 = '\0';
169 4 : p2++;
170 :
171 4 : *pp_username_str = talloc_strdup(ctx, p);
172 4 : p = p2;
173 0 : } else if (strnequal(set_str,"FSQLIM:",7)) {
174 0 : p +=7;
175 0 : *qtype = SMB_USER_FS_QUOTA_TYPE;
176 0 : *cmd = QUOTA_SETLIM;
177 0 : todo = PARSE_LIM;
178 0 : } else if (strnequal(set_str,"FSQFLAGS:",9)) {
179 0 : p +=9;
180 0 : todo = PARSE_FLAGS;
181 0 : *qtype = SMB_USER_FS_QUOTA_TYPE;
182 0 : *cmd = QUOTA_SETFLAGS;
183 : } else {
184 0 : return -1;
185 : }
186 :
187 4 : switch (todo) {
188 4 : case PARSE_LIM:
189 4 : if (sscanf(p,"%"SCNu64"/%"SCNu64,&pqt->softlim,
190 : &pqt->hardlim) != 2)
191 : {
192 0 : return -1;
193 : }
194 :
195 4 : break;
196 0 : case PARSE_FLAGS:
197 0 : while (!stop) {
198 :
199 0 : if ((p2=strstr(p,"/"))==NULL) {
200 0 : stop = True;
201 : } else {
202 0 : *p2 = '\0';
203 0 : p2++;
204 : }
205 :
206 0 : if (strnequal(p,"QUOTA_ENABLED",13)) {
207 0 : enable = True;
208 0 : } else if (strnequal(p,"DENY_DISK",9)) {
209 0 : deny = True;
210 0 : } else if (strnequal(p,"LOG_SOFTLIMIT",13)) {
211 0 : pqt->qflags |= QUOTAS_LOG_THRESHOLD;
212 0 : } else if (strnequal(p,"LOG_HARDLIMIT",13)) {
213 0 : pqt->qflags |= QUOTAS_LOG_LIMIT;
214 : } else {
215 0 : return -1;
216 : }
217 :
218 0 : p=p2;
219 : }
220 :
221 0 : if (deny) {
222 0 : pqt->qflags |= QUOTAS_DENY_DISK;
223 0 : } else if (enable) {
224 0 : pqt->qflags |= QUOTAS_ENABLED;
225 : }
226 :
227 0 : break;
228 : }
229 :
230 4 : return 0;
231 : }
232 :
233 :
234 204 : static const char *quota_str_static(uint64_t val, bool special, bool _numeric)
235 : {
236 : const char *result;
237 :
238 204 : if (!_numeric && special && val == 0) {
239 0 : return "NO LIMIT";
240 : }
241 204 : result = talloc_asprintf(talloc_tos(), "%"PRIu64, val);
242 204 : SMB_ASSERT(result != NULL);
243 204 : return result;
244 : }
245 :
246 68 : static void dump_ntquota(SMB_NTQUOTA_STRUCT *qt, bool _verbose,
247 : bool _numeric,
248 : void (*_sidtostring)(fstring str,
249 : struct dom_sid *sid,
250 : bool _numeric))
251 : {
252 68 : TALLOC_CTX *frame = talloc_stackframe();
253 :
254 68 : if (!qt) {
255 0 : smb_panic("dump_ntquota() called with NULL pointer");
256 : }
257 :
258 68 : switch (qt->qtype) {
259 0 : case SMB_USER_FS_QUOTA_TYPE:
260 : {
261 0 : d_printf("File System QUOTAS:\n");
262 0 : d_printf("Limits:\n");
263 0 : d_printf(" Default Soft Limit: %15s\n",
264 : quota_str_static(qt->softlim,True,_numeric));
265 0 : d_printf(" Default Hard Limit: %15s\n",
266 : quota_str_static(qt->hardlim,True,_numeric));
267 0 : d_printf("Quota Flags:\n");
268 0 : d_printf(" Quotas Enabled: %s\n",
269 0 : ((qt->qflags"AS_ENABLED)
270 0 : ||(qt->qflags"AS_DENY_DISK))?"On":"Off");
271 0 : d_printf(" Deny Disk: %s\n",
272 0 : (qt->qflags"AS_DENY_DISK)?"On":"Off");
273 0 : d_printf(" Log Soft Limit: %s\n",
274 0 : (qt->qflags"AS_LOG_THRESHOLD)?"On":"Off");
275 0 : d_printf(" Log Hard Limit: %s\n",
276 0 : (qt->qflags"AS_LOG_LIMIT)?"On":"Off");
277 : }
278 0 : break;
279 68 : case SMB_USER_QUOTA_TYPE:
280 68 : {
281 68 : fstring username_str = {0};
282 :
283 68 : if (_sidtostring) {
284 68 : _sidtostring(username_str,&qt->sid,_numeric);
285 : } else {
286 0 : sid_to_fstring(username_str, &qt->sid);
287 : }
288 :
289 68 : if (_verbose) {
290 0 : d_printf("Quotas for User: %s\n",username_str);
291 0 : d_printf("Used Space: %15s\n",
292 : quota_str_static(qt->usedspace,False,
293 : _numeric));
294 0 : d_printf("Soft Limit: %15s\n",
295 : quota_str_static(qt->softlim,True,
296 : _numeric));
297 0 : d_printf("Hard Limit: %15s\n",
298 : quota_str_static(qt->hardlim,True,_numeric));
299 : } else {
300 68 : d_printf("%-30s: ",username_str);
301 68 : d_printf("%15s/",quota_str_static(
302 : qt->usedspace,False,_numeric));
303 68 : d_printf("%15s/",quota_str_static(
304 : qt->softlim,True,_numeric));
305 68 : d_printf("%15s\n",quota_str_static(
306 : qt->hardlim,True,_numeric));
307 : }
308 : }
309 68 : break;
310 0 : default:
311 0 : d_printf("dump_ntquota() invalid qtype(%d)\n",qt->qtype);
312 : }
313 68 : TALLOC_FREE(frame);
314 68 : return;
315 : }
316 :
317 4 : static void dump_ntquota_list(SMB_NTQUOTA_LIST **qtl, bool _verbose,
318 : bool _numeric,
319 : void (*_sidtostring)(fstring str,
320 : struct dom_sid *sid,
321 : bool _numeric))
322 : {
323 : SMB_NTQUOTA_LIST *cur;
324 :
325 60 : for (cur = *qtl;cur;cur = cur->next) {
326 56 : if (cur->quotas)
327 56 : dump_ntquota(cur->quotas,_verbose,_numeric,
328 : _sidtostring);
329 : }
330 4 : }
331 :
332 16 : static int do_quota(struct cli_state *cli,
333 : enum SMB_QUOTA_TYPE qtype,
334 : uint16_t cmd,
335 : const char *username_str,
336 : SMB_NTQUOTA_STRUCT *pqt)
337 : {
338 16 : uint32_t fs_attrs = 0;
339 16 : uint16_t quota_fnum = 0;
340 16 : SMB_NTQUOTA_LIST *qtl = NULL;
341 16 : TALLOC_CTX *qtl_ctx = NULL;
342 : SMB_NTQUOTA_STRUCT qt;
343 : NTSTATUS status;
344 :
345 16 : ZERO_STRUCT(qt);
346 :
347 16 : status = cli_get_fs_attr_info(cli, &fs_attrs);
348 16 : if (!NT_STATUS_IS_OK(status)) {
349 0 : d_printf("Failed to get the filesystem attributes %s.\n",
350 : nt_errstr(status));
351 0 : return -1;
352 : }
353 :
354 16 : if (!(fs_attrs & FILE_VOLUME_QUOTAS)) {
355 0 : d_printf("Quotas are not supported by the server.\n");
356 0 : return 0;
357 : }
358 :
359 16 : status = cli_get_quota_handle(cli, "a_fnum);
360 16 : if (!NT_STATUS_IS_OK(status)) {
361 0 : d_printf("Quotas are not enabled on this share.\n");
362 0 : d_printf("Failed to open %s %s.\n",
363 : FAKE_FILE_NAME_QUOTA_WIN32,
364 : nt_errstr(status));
365 0 : return -1;
366 : }
367 :
368 16 : switch(qtype) {
369 16 : case SMB_USER_QUOTA_TYPE:
370 16 : if (!StringToSid(&qt.sid, username_str)) {
371 0 : d_printf("StringToSid() failed for [%s]\n",username_str);
372 0 : return -1;
373 : }
374 :
375 16 : switch(cmd) {
376 8 : case QUOTA_GET:
377 8 : status = cli_get_user_quota(
378 : cli, quota_fnum, &qt);
379 8 : if (!NT_STATUS_IS_OK(status)) {
380 0 : d_printf("%s cli_get_user_quota %s\n",
381 : nt_errstr(status),
382 : username_str);
383 0 : return -1;
384 : }
385 8 : dump_ntquota(&qt,verbose,numeric,SidToString);
386 8 : break;
387 4 : case QUOTA_SETLIM:
388 4 : pqt->sid = qt.sid;
389 4 : if ((qtl_ctx = talloc_init(
390 : "SMB_USER_QUOTA_SET")) ==
391 : NULL) {
392 0 : return -1;
393 : }
394 :
395 4 : if (!add_record_to_ntquota_list(
396 : qtl_ctx, pqt, &qtl)) {
397 0 : TALLOC_FREE(qtl_ctx);
398 0 : return -1;
399 : }
400 :
401 4 : status = cli_set_user_quota(
402 : cli, quota_fnum, qtl);
403 4 : free_ntquota_list(&qtl);
404 4 : if (!NT_STATUS_IS_OK(status)) {
405 0 : d_printf("%s cli_set_user_quota %s\n",
406 : nt_errstr(status),
407 : username_str);
408 0 : return -1;
409 : }
410 4 : status = cli_get_user_quota(
411 : cli, quota_fnum, &qt);
412 4 : if (!NT_STATUS_IS_OK(status)) {
413 0 : d_printf("%s cli_get_user_quota %s\n",
414 : nt_errstr(status),
415 : username_str);
416 0 : return -1;
417 : }
418 4 : dump_ntquota(&qt,verbose,numeric,SidToString);
419 4 : break;
420 4 : case QUOTA_LIST:
421 4 : status = cli_list_user_quota(
422 : cli, quota_fnum, &qtl);
423 4 : if (!NT_STATUS_IS_OK(status)) {
424 0 : d_printf(
425 : "%s cli_list_user_quota\n",
426 : nt_errstr(status));
427 0 : return -1;
428 : }
429 4 : dump_ntquota_list(&qtl,verbose,numeric,SidToString);
430 4 : free_ntquota_list(&qtl);
431 4 : break;
432 0 : default:
433 0 : d_printf("Unknown Error\n");
434 0 : return -1;
435 : }
436 16 : break;
437 0 : case SMB_USER_FS_QUOTA_TYPE:
438 0 : switch(cmd) {
439 0 : case QUOTA_GET:
440 0 : status = cli_get_fs_quota_info(
441 : cli, quota_fnum, &qt);
442 0 : if (!NT_STATUS_IS_OK(status)) {
443 0 : d_printf("%s cli_get_fs_quota_info\n",
444 : nt_errstr(status));
445 0 : return -1;
446 : }
447 0 : dump_ntquota(&qt,True,numeric,NULL);
448 0 : break;
449 0 : case QUOTA_SETLIM:
450 0 : status = cli_get_fs_quota_info(
451 : cli, quota_fnum, &qt);
452 0 : if (!NT_STATUS_IS_OK(status)) {
453 0 : d_printf("%s cli_get_fs_quota_info\n",
454 : nt_errstr(status));
455 0 : return -1;
456 : }
457 0 : qt.softlim = pqt->softlim;
458 0 : qt.hardlim = pqt->hardlim;
459 0 : status = cli_set_fs_quota_info(
460 : cli, quota_fnum, &qt);
461 0 : if (!NT_STATUS_IS_OK(status)) {
462 0 : d_printf("%s cli_set_fs_quota_info\n",
463 : nt_errstr(status));
464 0 : return -1;
465 : }
466 0 : status = cli_get_fs_quota_info(
467 : cli, quota_fnum, &qt);
468 0 : if (!NT_STATUS_IS_OK(status)) {
469 0 : d_printf("%s cli_get_fs_quota_info\n",
470 : nt_errstr(status));
471 0 : return -1;
472 : }
473 0 : dump_ntquota(&qt,True,numeric,NULL);
474 0 : break;
475 0 : case QUOTA_SETFLAGS:
476 0 : status = cli_get_fs_quota_info(
477 : cli, quota_fnum, &qt);
478 0 : if (!NT_STATUS_IS_OK(status)) {
479 0 : d_printf("%s cli_get_fs_quota_info\n",
480 : nt_errstr(status));
481 0 : return -1;
482 : }
483 0 : qt.qflags = pqt->qflags;
484 0 : status = cli_set_fs_quota_info(
485 : cli, quota_fnum, &qt);
486 0 : if (!NT_STATUS_IS_OK(status)) {
487 0 : d_printf("%s cli_set_fs_quota_info\n",
488 : nt_errstr(status));
489 0 : return -1;
490 : }
491 0 : status = cli_get_fs_quota_info(
492 : cli, quota_fnum, &qt);
493 0 : if (!NT_STATUS_IS_OK(status)) {
494 0 : d_printf("%s cli_get_fs_quota_info\n",
495 : nt_errstr(status));
496 0 : return -1;
497 : }
498 0 : dump_ntquota(&qt,True,numeric,NULL);
499 0 : break;
500 0 : default:
501 0 : d_printf("Unknown Error\n");
502 0 : return -1;
503 : }
504 0 : break;
505 0 : default:
506 0 : d_printf("Unknown Error\n");
507 0 : return -1;
508 : }
509 :
510 16 : cli_close(cli, quota_fnum);
511 :
512 16 : return 0;
513 : }
514 :
515 : /*****************************************************
516 : Return a connection to a server.
517 : *******************************************************/
518 :
519 32 : static struct cli_state *connect_one(const char *share)
520 : {
521 : struct cli_state *c;
522 : NTSTATUS nt_status;
523 32 : uint32_t flags = 0;
524 :
525 32 : nt_status = cli_full_connection_creds(&c, lp_netbios_name(), server,
526 : NULL, 0,
527 : share, "?????",
528 : samba_cmdline_get_creds(),
529 : flags);
530 32 : if (!NT_STATUS_IS_OK(nt_status)) {
531 0 : DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status)));
532 0 : return NULL;
533 : }
534 :
535 32 : return c;
536 : }
537 :
538 : /****************************************************************************
539 : main program
540 : ****************************************************************************/
541 16 : int main(int argc, char *argv[])
542 : {
543 16 : const char **argv_const = discard_const_p(const char *, argv);
544 : char *share;
545 : int opt;
546 : int result;
547 16 : int todo = 0;
548 16 : char *username_str = NULL;
549 16 : char *path = NULL;
550 16 : char *set_str = NULL;
551 16 : enum SMB_QUOTA_TYPE qtype = SMB_INVALID_QUOTA_TYPE;
552 16 : int cmd = 0;
553 : static bool test_args = False;
554 : struct cli_state *cli;
555 16 : bool fix_user = False;
556 : SMB_NTQUOTA_STRUCT qt;
557 16 : TALLOC_CTX *frame = talloc_stackframe();
558 : poptContext pc;
559 16 : struct cli_credentials *creds = NULL;
560 : bool ok;
561 :
562 80 : struct poptOption long_options[] = {
563 : POPT_AUTOHELP
564 : {
565 : .longName = "quota-user",
566 : .shortName = 'u',
567 : .argInfo = POPT_ARG_STRING,
568 : .arg = NULL,
569 : .val = 'u',
570 : .descrip = "Show quotas for user",
571 : .argDescrip = "USER",
572 : },
573 : {
574 : .longName = "list",
575 : .shortName = 'L',
576 : .argInfo = POPT_ARG_NONE,
577 : .arg = NULL,
578 : .val = 'L',
579 : .descrip = "List user quotas",
580 : },
581 : {
582 : .longName = "fs",
583 : .shortName = 'F',
584 : .argInfo = POPT_ARG_NONE,
585 : .arg = NULL,
586 : .val = 'F',
587 : .descrip = "Show filesystem quotas",
588 : },
589 : {
590 : .longName = "set",
591 : .shortName = 'S',
592 : .argInfo = POPT_ARG_STRING,
593 : .arg = NULL,
594 : .val = 'S',
595 : .descrip = "Set acls\n"
596 : "SETSTRING:\n"
597 : "UQLIM:<username>/<softlimit>/<hardlimit> for user quotas\n"
598 : "FSQLIM:<softlimit>/<hardlimit> for filesystem defaults\n"
599 : "FSQFLAGS:QUOTA_ENABLED/DENY_DISK/LOG_SOFTLIMIT/LOG_HARD_LIMIT",
600 : .argDescrip = "SETSTRING",
601 : },
602 : {
603 : .longName = "numeric",
604 : .shortName = 'n',
605 : .argInfo = POPT_ARG_NONE,
606 : .arg = NULL,
607 : .val = 'n',
608 : .descrip = "Don't resolve sids or limits to names",
609 : },
610 : {
611 : .longName = "verbose",
612 : .shortName = 'v',
613 : .argInfo = POPT_ARG_NONE,
614 : .arg = NULL,
615 : .val = 'v',
616 : .descrip = "be verbose",
617 : },
618 : {
619 : .longName = "test-args",
620 : .shortName = 't',
621 : .argInfo = POPT_ARG_NONE,
622 : .arg = NULL,
623 : .val = 't',
624 : .descrip = "Test arguments"
625 : },
626 : {
627 : .longName = "max-protocol",
628 : .shortName = 'm',
629 : .argInfo = POPT_ARG_STRING,
630 : .arg = NULL,
631 : .val = 'm',
632 : .descrip = "Set the max protocol level",
633 : .argDescrip = "LEVEL"
634 : },
635 16 : POPT_COMMON_SAMBA
636 16 : POPT_COMMON_CREDENTIALS
637 16 : POPT_LEGACY_S3
638 16 : POPT_COMMON_VERSION
639 : POPT_TABLEEND
640 : };
641 :
642 16 : smb_init_locale();
643 :
644 16 : ZERO_STRUCT(qt);
645 :
646 16 : ok = samba_cmdline_init(frame,
647 : SAMBA_CMDLINE_CONFIG_CLIENT,
648 : false /* require_smbconf */);
649 16 : if (!ok) {
650 0 : DBG_ERR("Failed to init cmdline parser!\n");
651 0 : TALLOC_FREE(frame);
652 0 : exit(1);
653 : }
654 : /* set default debug level to 1 regardless of what smb.conf sets */
655 16 : lp_set_cmdline("log level", "1");
656 :
657 16 : setlinebuf(stdout);
658 :
659 16 : pc = samba_popt_get_context(getprogname(),
660 : argc,
661 : argv_const,
662 : long_options, 0);
663 16 : if (pc == NULL) {
664 0 : DBG_ERR("Failed to setup popt context!\n");
665 0 : TALLOC_FREE(frame);
666 0 : exit(1);
667 : }
668 :
669 16 : poptSetOtherOptionHelp(pc, "//server1/share1");
670 :
671 16 : while ((opt = poptGetNextOpt(pc)) != -1) {
672 16 : switch (opt) {
673 0 : case 'n':
674 0 : numeric = true;
675 0 : break;
676 0 : case 'v':
677 0 : verbose = true;
678 0 : break;
679 0 : case 't':
680 0 : test_args = true;
681 0 : break;
682 4 : case 'L':
683 4 : if (todo != 0) {
684 0 : d_printf("Please specify only one option of <-L|-F|-S|-u>\n");
685 0 : exit(EXIT_PARSE_ERROR);
686 : }
687 4 : todo = LIST_QUOTA;
688 4 : break;
689 :
690 0 : case 'F':
691 0 : if (todo != 0) {
692 0 : d_printf("Please specify only one option of <-L|-F|-S|-u>\n");
693 0 : exit(EXIT_PARSE_ERROR);
694 : }
695 0 : todo = FS_QUOTA;
696 0 : break;
697 :
698 4 : case 'u':
699 4 : if (todo != 0) {
700 0 : d_printf("Please specify only one option of <-L|-F|-S|-u>\n");
701 0 : exit(EXIT_PARSE_ERROR);
702 : }
703 4 : username_str = talloc_strdup(frame, poptGetOptArg(pc));
704 4 : if (!username_str) {
705 0 : exit(EXIT_PARSE_ERROR);
706 : }
707 4 : todo = USER_QUOTA;
708 4 : fix_user = True;
709 4 : break;
710 :
711 4 : case 'S':
712 4 : if (todo != 0) {
713 0 : d_printf("Please specify only one option of <-L|-F|-S|-u>\n");
714 0 : exit(EXIT_PARSE_ERROR);
715 : }
716 4 : set_str = talloc_strdup(frame, poptGetOptArg(pc));
717 4 : if (!set_str) {
718 0 : exit(EXIT_PARSE_ERROR);
719 : }
720 4 : todo = SET_QUOTA;
721 4 : break;
722 4 : case 'm':
723 4 : lp_set_cmdline("client max protocol",
724 4 : poptGetOptArg(pc));
725 4 : break;
726 0 : case POPT_ERROR_BADOPT:
727 0 : fprintf(stderr, "\nInvalid option %s: %s\n\n",
728 : poptBadOption(pc, 0), poptStrerror(opt));
729 0 : poptPrintUsage(pc, stderr, 0);
730 0 : exit(1);
731 : }
732 : }
733 :
734 16 : creds = samba_cmdline_get_creds();
735 :
736 16 : if (todo == 0)
737 4 : todo = USER_QUOTA;
738 :
739 16 : if (!fix_user) {
740 12 : const char *user = cli_credentials_get_username(creds);
741 12 : if (user == NULL) {
742 0 : exit(EXIT_PARSE_ERROR);
743 : }
744 :
745 12 : username_str = talloc_strdup(frame, user);
746 12 : if (!username_str) {
747 0 : exit(EXIT_PARSE_ERROR);
748 : }
749 : }
750 :
751 : /* Make connection to server */
752 16 : if(!poptPeekArg(pc)) {
753 0 : poptPrintUsage(pc, stderr, 0);
754 0 : exit(EXIT_PARSE_ERROR);
755 : }
756 :
757 16 : path = talloc_strdup(frame, poptGetArg(pc));
758 16 : if (!path) {
759 0 : printf("Out of memory\n");
760 0 : exit(EXIT_PARSE_ERROR);
761 : }
762 :
763 16 : poptFreeContext(pc);
764 16 : samba_cmdline_burn(argc, argv);
765 :
766 16 : string_replace(path, '/', '\\');
767 :
768 16 : server = SMB_STRDUP(path+2);
769 16 : if (!server) {
770 0 : printf("Out of memory\n");
771 0 : exit(EXIT_PARSE_ERROR);
772 : }
773 16 : share = strchr_m(server,'\\');
774 16 : if (share == NULL) {
775 0 : printf("Invalid argument\n");
776 0 : exit(EXIT_PARSE_ERROR);
777 : }
778 :
779 16 : *share = 0;
780 16 : share++;
781 :
782 16 : if (todo == SET_QUOTA) {
783 4 : if (parse_quota_set(talloc_tos(), set_str, &username_str, &qtype, &cmd, &qt)) {
784 0 : printf("Invalid argument: -S %s\n", set_str);
785 0 : exit(EXIT_PARSE_ERROR);
786 : }
787 : }
788 :
789 16 : if (!test_args) {
790 16 : cli = connect_one(share);
791 16 : if (!cli) {
792 0 : exit(EXIT_FAILED);
793 : }
794 : } else {
795 0 : exit(EXIT_OK);
796 : }
797 :
798 :
799 : /* Perform requested action */
800 :
801 16 : switch (todo) {
802 0 : case FS_QUOTA:
803 0 : result = do_quota(cli,SMB_USER_FS_QUOTA_TYPE, QUOTA_GET, username_str, NULL);
804 0 : break;
805 4 : case LIST_QUOTA:
806 4 : result = do_quota(cli,SMB_USER_QUOTA_TYPE, QUOTA_LIST, username_str, NULL);
807 4 : break;
808 8 : case USER_QUOTA:
809 8 : result = do_quota(cli,SMB_USER_QUOTA_TYPE, QUOTA_GET, username_str, NULL);
810 8 : break;
811 4 : case SET_QUOTA:
812 4 : result = do_quota(cli, qtype, cmd, username_str, &qt);
813 4 : break;
814 0 : default:
815 0 : result = EXIT_FAILED;
816 0 : break;
817 : }
818 :
819 16 : talloc_free(frame);
820 :
821 16 : return result;
822 : }
|