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