LCOV - code coverage report
Current view: top level - source3/utils - smbcquotas.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 211 405 52.1 %
Date: 2024-02-28 12: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             : #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         148 : static bool cli_open_policy_hnd(void)
      54             : {
      55             :         /* Initialise cli LSA connection */
      56             : 
      57         148 :         if (!cli_ipc) {
      58             :                 NTSTATUS ret;
      59          23 :                 cli_ipc = connect_one("IPC$");
      60          23 :                 ret = cli_rpc_pipe_open_noauth(cli_ipc,
      61             :                                                &ndr_table_lsarpc,
      62             :                                                &global_pipe_hnd);
      63          23 :                 if (!NT_STATUS_IS_OK(ret)) {
      64           0 :                                 return False;
      65             :                 }
      66             :         }
      67             : 
      68             :         /* Open policy handle */
      69             : 
      70         148 :         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          23 :                 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          23 :                 got_policy_hnd = True;
      81             :         }
      82             : 
      83         148 :         return True;
      84             : }
      85             : 
      86             : /* convert a SID to a string, either numeric or username/group */
      87         125 : static void SidToString(fstring str, struct dom_sid *sid, bool _numeric)
      88             : {
      89         125 :         char **domains = NULL;
      90         125 :         char **names = NULL;
      91         125 :         enum lsa_SidType *types = NULL;
      92             : 
      93         125 :         sid_to_fstring(str, sid);
      94             : 
      95         125 :         if (_numeric) return;
      96             : 
      97             :         /* Ask LSA to convert the sid to a name */
      98             : 
      99         125 :         if (!cli_open_policy_hnd() ||
     100         125 :             !NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(global_pipe_hnd, talloc_tos(),
     101             :                                                  &pol, 1, sid, &domains,
     102         125 :                                                  &names, &types)) ||
     103         125 :             !domains || !domains[0] || !names || !names[0]) {
     104           0 :                 return;
     105             :         }
     106             : 
     107             :         /* Converted OK */
     108             : 
     109         125 :         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          23 : static bool StringToSid(struct dom_sid *sid, const char *str)
     116             : {
     117          23 :         enum lsa_SidType *types = NULL;
     118          23 :         struct dom_sid *sids = NULL;
     119          23 :         bool result = True;
     120             : 
     121          23 :         if (string_to_sid(sid, str)) {
     122           0 :                 return true;
     123             :         }
     124             : 
     125          23 :         if (!cli_open_policy_hnd() ||
     126          23 :             !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          23 :         sid_copy(sid, &sids[0]);
     134          23 :  done:
     135             : 
     136          23 :         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           6 : 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           6 :         char *p = set_str,*p2;
     154             :         int todo;
     155           6 :         bool stop = False;
     156           6 :         bool enable = False;
     157           6 :         bool deny = False;
     158             : 
     159           6 :         *pp_username_str = NULL;
     160           6 :         if (strnequal(set_str,"UQLIM:",6)) {
     161           6 :                 p += 6;
     162           6 :                 *qtype = SMB_USER_QUOTA_TYPE;
     163           6 :                 *cmd = QUOTA_SETLIM;
     164           6 :                 todo = PARSE_LIM;
     165           6 :                 if ((p2=strstr(p,":"))==NULL) {
     166           0 :                         return -1;
     167             :                 }
     168             : 
     169           6 :                 *p2 = '\0';
     170           6 :                 p2++;
     171             : 
     172           6 :                 *pp_username_str = talloc_strdup(ctx, p);
     173           6 :                 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           6 :         switch (todo) {
     189           6 :                 case PARSE_LIM:
     190           6 :                         if (sscanf(p,"%"SCNu64"/%"SCNu64,&pqt->softlim,
     191             :                             &pqt->hardlim) != 2)
     192             :                         {
     193           0 :                                 return -1;
     194             :                         }
     195             : 
     196           6 :                         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           6 :         return 0;
     232             : }
     233             : 
     234             : 
     235         375 : static const char *quota_str_static(uint64_t val, bool special, bool _numeric)
     236             : {
     237             :         const char *result;
     238             : 
     239         375 :         if (!_numeric && special && val == 0) {
     240           0 :                 return "NO LIMIT";
     241             :         }
     242         375 :         result = talloc_asprintf(talloc_tos(), "%"PRIu64, val);
     243         375 :         SMB_ASSERT(result != NULL);
     244         375 :         return result;
     245             : }
     246             : 
     247         125 : 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         125 :         TALLOC_CTX *frame = talloc_stackframe();
     254             : 
     255         125 :         if (!qt) {
     256           0 :                 smb_panic("dump_ntquota() called with NULL pointer");
     257             :         }
     258             : 
     259         125 :         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&QUOTAS_ENABLED)
     271           0 :                           ||(qt->qflags&QUOTAS_DENY_DISK))?"On":"Off");
     272           0 :                 d_printf(" Deny Disk:      %s\n",
     273           0 :                          (qt->qflags&QUOTAS_DENY_DISK)?"On":"Off");
     274           0 :                 d_printf(" Log Soft Limit: %s\n",
     275           0 :                          (qt->qflags&QUOTAS_LOG_THRESHOLD)?"On":"Off");
     276           0 :                 d_printf(" Log Hard Limit: %s\n",
     277           0 :                          (qt->qflags&QUOTAS_LOG_LIMIT)?"On":"Off");
     278             :         }
     279           0 :         break;
     280         125 :         case SMB_USER_QUOTA_TYPE:
     281             :         {
     282         125 :                 fstring username_str = {0};
     283             : 
     284         125 :                 if (_sidtostring) {
     285         125 :                         _sidtostring(username_str,&qt->sid,_numeric);
     286             :                 } else {
     287           0 :                         sid_to_fstring(username_str, &qt->sid);
     288             :                 }
     289             : 
     290         125 :                 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         125 :                         d_printf("%-30s: ",username_str);
     302         125 :                         d_printf("%15s/",quota_str_static(
     303             :                                          qt->usedspace,False,_numeric));
     304         125 :                         d_printf("%15s/",quota_str_static(
     305             :                                          qt->softlim,True,_numeric));
     306         125 :                         d_printf("%15s\n",quota_str_static(
     307             :                                          qt->hardlim,True,_numeric));
     308             :                 }
     309             :         }
     310         125 :         break;
     311           0 :         default:
     312           0 :                 d_printf("dump_ntquota() invalid qtype(%d)\n",qt->qtype);
     313             :         }
     314         125 :         TALLOC_FREE(frame);
     315         125 :         return;
     316             : }
     317             : 
     318           6 : 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         114 :         for (cur = *qtl;cur;cur = cur->next) {
     327         108 :                 if (cur->quotas)
     328         108 :                         dump_ntquota(cur->quotas,_verbose,_numeric,
     329             :                                      _sidtostring);
     330             :         }
     331           6 : }
     332             : 
     333          23 : 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          23 :         uint32_t fs_attrs = 0;
     340          23 :         uint16_t quota_fnum = 0;
     341          23 :         SMB_NTQUOTA_LIST *qtl = NULL;
     342          23 :         TALLOC_CTX *qtl_ctx = NULL;
     343             :         SMB_NTQUOTA_STRUCT qt;
     344             :         NTSTATUS status;
     345             : 
     346          23 :         ZERO_STRUCT(qt);
     347             : 
     348          23 :         status = cli_get_fs_attr_info(cli, &fs_attrs);
     349          23 :         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          23 :         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          23 :         status = cli_get_quota_handle(cli, &quota_fnum);
     361          23 :         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          23 :         switch(qtype) {
     370          23 :                 case SMB_USER_QUOTA_TYPE:
     371          23 :                         if (!StringToSid(&qt.sid, username_str)) {
     372           0 :                                 d_printf("StringToSid() failed for [%s]\n",username_str);
     373           0 :                                 return -1;
     374             :                         }
     375             : 
     376          23 :                         switch(cmd) {
     377          11 :                                 case QUOTA_GET:
     378          11 :                                         status = cli_get_user_quota(
     379             :                                                 cli, quota_fnum, &qt);
     380          11 :                                         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          11 :                                         dump_ntquota(&qt,verbose,numeric,SidToString);
     387          11 :                                         break;
     388           6 :                                 case QUOTA_SETLIM:
     389           6 :                                         pqt->sid = qt.sid;
     390           6 :                                         if ((qtl_ctx = talloc_init(
     391             :                                                  "SMB_USER_QUOTA_SET")) ==
     392             :                                             NULL) {
     393           0 :                                                 return -1;
     394             :                                         }
     395             : 
     396           6 :                                         if (!add_record_to_ntquota_list(
     397             :                                                 qtl_ctx, pqt, &qtl)) {
     398           0 :                                                 TALLOC_FREE(qtl_ctx);
     399           0 :                                                 return -1;
     400             :                                         }
     401             : 
     402           6 :                                         status = cli_set_user_quota(
     403             :                                             cli, quota_fnum, qtl);
     404           6 :                                         free_ntquota_list(&qtl);
     405           6 :                                         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           6 :                                         status = cli_get_user_quota(
     412             :                                                 cli, quota_fnum, &qt);
     413           6 :                                         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           6 :                                         dump_ntquota(&qt,verbose,numeric,SidToString);
     420           6 :                                         break;
     421           6 :                                 case QUOTA_LIST:
     422           6 :                                         status = cli_list_user_quota(
     423             :                                                 cli, quota_fnum, &qtl);
     424           6 :                                         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           6 :                                         dump_ntquota_list(&qtl,verbose,numeric,SidToString);
     431           6 :                                         free_ntquota_list(&qtl);
     432           6 :                                         break;
     433           0 :                                 default:
     434           0 :                                         d_printf("Unknown Error\n");
     435           0 :                                         return -1;
     436             :                         }
     437          23 :                         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          23 :         cli_close(cli, quota_fnum);
     512             : 
     513          23 :         return 0;
     514             : }
     515             : 
     516             : /*****************************************************
     517             :  Return a connection to a server.
     518             : *******************************************************/
     519             : 
     520          46 : static struct cli_state *connect_one(const char *share)
     521             : {
     522             :         struct cli_state *c;
     523             :         NTSTATUS nt_status;
     524          46 :         uint32_t flags = 0;
     525             : 
     526          46 :         nt_status = cli_full_connection_creds(&c, lp_netbios_name(), server,
     527             :                                             NULL, 0,
     528             :                                             share, "?????",
     529             :                                             samba_cmdline_get_creds(),
     530             :                                             flags);
     531          46 :         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          46 :         return c;
     537             : }
     538             : 
     539             : /****************************************************************************
     540             :   main program
     541             : ****************************************************************************/
     542          23 : int main(int argc, char *argv[])
     543             : {
     544          23 :         const char **argv_const = discard_const_p(const char *, argv);
     545             :         char *share;
     546             :         int opt;
     547             :         int result;
     548          23 :         int todo = 0;
     549          23 :         char *username_str = NULL;
     550          23 :         char *path = NULL;
     551          23 :         char *set_str = NULL;
     552          23 :         enum SMB_QUOTA_TYPE qtype = SMB_INVALID_QUOTA_TYPE;
     553          23 :         int cmd = 0;
     554             :         static bool test_args = False;
     555             :         struct cli_state *cli;
     556          23 :         bool fix_user = False;
     557             :         SMB_NTQUOTA_STRUCT qt;
     558          23 :         TALLOC_CTX *frame = talloc_stackframe();
     559             :         poptContext pc;
     560          23 :         struct cli_credentials *creds = NULL;
     561             :         bool ok;
     562          23 :         struct loadparm_context *lp_ctx = NULL;
     563             : 
     564         115 :         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          23 :                 POPT_COMMON_SAMBA
     638          23 :                 POPT_COMMON_CREDENTIALS
     639          23 :                 POPT_LEGACY_S3
     640          23 :                 POPT_COMMON_VERSION
     641             :                 POPT_TABLEEND
     642             :         };
     643             : 
     644          23 :         smb_init_locale();
     645             : 
     646          23 :         ZERO_STRUCT(qt);
     647             : 
     648          23 :         ok = samba_cmdline_init(frame,
     649             :                                 SAMBA_CMDLINE_CONFIG_CLIENT,
     650             :                                 false /* require_smbconf */);
     651          23 :         if (!ok) {
     652           0 :                 DBG_ERR("Failed to init cmdline parser!\n");
     653           0 :                 TALLOC_FREE(frame);
     654           0 :                 exit(1);
     655             :         }
     656          23 :         lp_ctx = samba_cmdline_get_lp_ctx();
     657             :         /* set default debug level to 1 regardless of what smb.conf sets */
     658          23 :         lpcfg_set_cmdline(lp_ctx, "log level", "1");
     659             : 
     660          23 :         setlinebuf(stdout);
     661             : 
     662          23 :         pc = samba_popt_get_context(getprogname(),
     663             :                                     argc,
     664             :                                     argv_const,
     665             :                                     long_options, 0);
     666          23 :         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          23 :         poptSetOtherOptionHelp(pc, "//server1/share1");
     673             : 
     674          46 :         while ((opt = poptGetNextOpt(pc)) != -1) {
     675          23 :                 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           6 :                 case 'L':
     686           6 :                         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           6 :                         todo = LIST_QUOTA;
     691           6 :                         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           6 :                 case 'u':
     702           6 :                         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           6 :                         username_str = talloc_strdup(frame, poptGetOptArg(pc));
     707           6 :                         if (!username_str) {
     708           0 :                                 exit(EXIT_PARSE_ERROR);
     709             :                         }
     710           6 :                         todo = USER_QUOTA;
     711           6 :                         fix_user = True;
     712           6 :                         break;
     713             : 
     714           6 :                 case 'S':
     715           6 :                         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           6 :                         set_str = talloc_strdup(frame, poptGetOptArg(pc));
     720           6 :                         if (!set_str) {
     721           0 :                                 exit(EXIT_PARSE_ERROR);
     722             :                         }
     723           6 :                         todo = SET_QUOTA;
     724           6 :                         break;
     725           5 :                 case 'm':
     726           5 :                         lpcfg_set_cmdline(lp_ctx,
     727             :                                           "client max protocol",
     728           5 :                                           poptGetOptArg(pc));
     729           5 :                         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          23 :         creds = samba_cmdline_get_creds();
     739             : 
     740          23 :         if (todo == 0)
     741           5 :                 todo = USER_QUOTA;
     742             : 
     743          23 :         if (!fix_user) {
     744          17 :                 const char *user = cli_credentials_get_username(creds);
     745          17 :                 if (user == NULL) {
     746           0 :                         exit(EXIT_PARSE_ERROR);
     747             :                 }
     748             : 
     749          17 :                 username_str = talloc_strdup(frame, user);
     750          17 :                 if (!username_str) {
     751           0 :                         exit(EXIT_PARSE_ERROR);
     752             :                 }
     753             :         }
     754             : 
     755             :         /* Make connection to server */
     756          23 :         if(!poptPeekArg(pc)) {
     757           0 :                 poptPrintUsage(pc, stderr, 0);
     758           0 :                 exit(EXIT_PARSE_ERROR);
     759             :         }
     760             : 
     761          23 :         path = talloc_strdup(frame, poptGetArg(pc));
     762          23 :         if (!path) {
     763           0 :                 printf("Out of memory\n");
     764           0 :                 exit(EXIT_PARSE_ERROR);
     765             :         }
     766             : 
     767          23 :         if (strncmp(path, "\\\\", 2) && strncmp(path, "//", 2)) {
     768           0 :                 printf("Invalid argument: %s\n", path);
     769           0 :                 return -1;
     770             :         }
     771             : 
     772          23 :         poptFreeContext(pc);
     773          23 :         samba_cmdline_burn(argc, argv);
     774             : 
     775          23 :         string_replace(path, '/', '\\');
     776             : 
     777          23 :         server = SMB_STRDUP(path+2);
     778          23 :         if (!server) {
     779           0 :                 printf("Out of memory\n");
     780           0 :                 exit(EXIT_PARSE_ERROR);
     781             :         }
     782          23 :         share = strchr_m(server,'\\');
     783          23 :         if (share == NULL) {
     784           0 :                 printf("Invalid argument\n");
     785           0 :                 exit(EXIT_PARSE_ERROR);
     786             :         }
     787             : 
     788          23 :         *share = 0;
     789          23 :         share++;
     790             : 
     791          23 :         if (todo == SET_QUOTA) {
     792           6 :                 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          23 :         if (!test_args) {
     799          23 :                 cli = connect_one(share);
     800          23 :                 if (!cli) {
     801           0 :                         exit(EXIT_FAILED);
     802             :                 }
     803             :         } else {
     804           0 :                 exit(EXIT_OK);
     805             :         }
     806             : 
     807             : 
     808             :         /* Perform requested action */
     809             : 
     810          23 :         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           6 :                 case LIST_QUOTA:
     815           6 :                         result = do_quota(cli,SMB_USER_QUOTA_TYPE, QUOTA_LIST, username_str, NULL);
     816           6 :                         break;
     817          11 :                 case USER_QUOTA:
     818          11 :                         result = do_quota(cli,SMB_USER_QUOTA_TYPE, QUOTA_GET, username_str, NULL);
     819          11 :                         break;
     820           6 :                 case SET_QUOTA:
     821           6 :                         result = do_quota(cli, qtype, cmd, username_str, &qt);
     822           6 :                         break;
     823           0 :                 default:
     824           0 :                         result = EXIT_FAILED;
     825           0 :                         break;
     826             :         }
     827             : 
     828          23 :         gfree_all();
     829          23 :         talloc_free(frame);
     830             : 
     831          23 :         return result;
     832             : }

Generated by: LCOV version 1.14