LCOV - code coverage report
Current view: top level - source3/utils - smbcquotas.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 208 400 52.0 %
Date: 2021-09-23 10:06:22 Functions: 10 10 100.0 %

          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&QUOTAS_ENABLED)
     270           0 :                           ||(qt->qflags&QUOTAS_DENY_DISK))?"On":"Off");
     271           0 :                 d_printf(" Deny Disk:      %s\n",
     272           0 :                          (qt->qflags&QUOTAS_DENY_DISK)?"On":"Off");
     273           0 :                 d_printf(" Log Soft Limit: %s\n",
     274           0 :                          (qt->qflags&QUOTAS_LOG_THRESHOLD)?"On":"Off");
     275           0 :                 d_printf(" Log Hard Limit: %s\n",
     276           0 :                          (qt->qflags&QUOTAS_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, &quota_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             : }

Generated by: LCOV version 1.13