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

Generated by: LCOV version 1.14