LCOV - code coverage report
Current view: top level - source3/lib - sysquotas_linux.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 30 97 30.9 %
Date: 2021-09-23 10:06:22 Functions: 1 2 50.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    System QUOTA function wrappers for LINUX
       4             :    Copyright (C) Stefan (metze) Metzmacher      2003
       5             :    
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             :    
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             :    
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : 
      21             : #include "includes.h"
      22             : 
      23             : #undef DBGC_CLASS
      24             : #define DBGC_CLASS DBGC_QUOTA
      25             : 
      26             : #ifndef HAVE_SYS_QUOTAS
      27             : #ifdef HAVE_QUOTACTL_LINUX
      28             : #undef HAVE_QUOTACTL_LINUX
      29             : #endif
      30             : #endif
      31             : 
      32             : #ifdef HAVE_QUOTACTL_LINUX
      33             : 
      34             : #include <sys/quota.h>
      35             : 
      36             : /****************************************************************************
      37             :  Linux quota get calls.
      38             : ****************************************************************************/
      39         706 : int sys_get_vfs_quota(const char *path, const char *bdev,
      40             :                       enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
      41             : {
      42         706 :         int ret = -1;
      43         706 :         uint32_t qflags = 0;
      44             :         struct dqblk D;
      45         706 :         uint64_t bsize = (uint64_t)QUOTABLOCK_SIZE;
      46             : 
      47         706 :         if (!path || !bdev || !dp) {
      48           0 :                 smb_panic("sys_get_vfs_quota: called with NULL pointer");
      49             :         }
      50             : 
      51         706 :         ZERO_STRUCT(*dp);
      52         706 :         dp->qtype = qtype;
      53             : 
      54         706 :         ZERO_STRUCT(D);
      55             : 
      56         706 :         switch (qtype) {
      57           0 :                 case SMB_USER_QUOTA_TYPE:
      58           0 :                         DEBUG(10, ("sys_get_vfs_quota: path[%s] bdev[%s] "
      59             :                                    "SMB_USER_QUOTA_TYPE uid[%u]\n",
      60             :                                    path, bdev, (unsigned)id.uid));
      61             : 
      62           0 :                         if ((ret = quotactl(QCMD(Q_GETQUOTA, USRQUOTA), bdev,
      63           0 :                                             id.uid, (caddr_t)&D))) {
      64           0 :                                 return ret;
      65             :                         }
      66             : 
      67           0 :                         break;
      68           0 :                 case SMB_GROUP_QUOTA_TYPE:
      69           0 :                         DEBUG(10, ("sys_get_vfs_quota: path[%s] bdev[%s] "
      70             :                                    "SMB_GROUP_QUOTA_TYPE gid[%u]\n",
      71             :                                    path, bdev, (unsigned)id.gid));
      72             : 
      73           0 :                         if ((ret = quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), bdev,
      74           0 :                                             id.gid, (caddr_t)&D))) {
      75           0 :                                 return ret;
      76             :                         }
      77             : 
      78           0 :                         break;
      79         353 :                 case SMB_USER_FS_QUOTA_TYPE:
      80         353 :                         DEBUG(10, ("sys_get_vfs_quota: path[%s] bdev[%s] "
      81             :                                    "SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
      82             :                                    path, bdev, (unsigned)geteuid()));
      83             : 
      84         353 :                         if ((ret = quotactl(QCMD(Q_GETQUOTA, USRQUOTA), bdev,
      85         353 :                                             geteuid(), (caddr_t)&D)) == 0) {
      86           0 :                                 qflags |= QUOTAS_DENY_DISK;
      87             :                         }
      88             : 
      89         353 :                         ret = 0;
      90             : 
      91         353 :                         break;
      92         353 :                 case SMB_GROUP_FS_QUOTA_TYPE:
      93         353 :                         DEBUG(10, ("sys_get_vfs_quota: path[%s] bdev[%s] "
      94             :                                    "SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
      95             :                                    path, bdev, (unsigned)getegid()));
      96             : 
      97         353 :                         if ((ret = quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), bdev,
      98         353 :                                             getegid(), (caddr_t)&D)) == 0) {
      99           0 :                                 qflags |= QUOTAS_DENY_DISK;
     100             :                         }
     101             : 
     102         353 :                         ret = 0;
     103         353 :                         break;
     104           0 :                 default:
     105           0 :                         errno = ENOSYS;
     106           0 :                         return -1;
     107             :         }
     108             : 
     109         706 :         dp->bsize = bsize;
     110         706 :         dp->softlimit = (uint64_t)D.dqb_bsoftlimit;
     111         706 :         dp->hardlimit = (uint64_t)D.dqb_bhardlimit;
     112         706 :         dp->ihardlimit = (uint64_t)D.dqb_ihardlimit;
     113         706 :         dp->isoftlimit = (uint64_t)D.dqb_isoftlimit;
     114         706 :         dp->curinodes = (uint64_t)D.dqb_curinodes;
     115         706 :         dp->curblocks = (uint64_t)D.dqb_curspace/bsize;
     116             : 
     117             : 
     118         706 :         dp->qflags = qflags;
     119             : 
     120         706 :         return ret;
     121             : }
     122             : 
     123             : /****************************************************************************
     124             :  Linux quota set calls.
     125             : ****************************************************************************/
     126           0 : int sys_set_vfs_quota(const char *path, const char *bdev,
     127             :                       enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
     128             : {
     129           0 :         int ret = -1;
     130             :         struct dqblk D;
     131           0 :         uint64_t bsize = (uint64_t)QUOTABLOCK_SIZE;
     132             :         bool cur_enf, new_enf;
     133             : 
     134           0 :         if (!path || !bdev || !dp) {
     135           0 :                 smb_panic("sys_set_vfs_quota: called with NULL pointer");
     136             :         }
     137             : 
     138           0 :         ZERO_STRUCT(D);
     139             : 
     140           0 :         if (bsize == dp->bsize) {
     141           0 :                 D.dqb_bsoftlimit = dp->softlimit;
     142           0 :                 D.dqb_bhardlimit = dp->hardlimit;
     143             :         } else {
     144           0 :                 D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize;
     145           0 :                 D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize;
     146             :         }
     147           0 :         D.dqb_ihardlimit = dp->ihardlimit;
     148           0 :         D.dqb_isoftlimit = dp->isoftlimit;
     149           0 :         D.dqb_valid = QIF_LIMITS;
     150             : 
     151           0 :         switch (qtype) {
     152           0 :                 case SMB_USER_QUOTA_TYPE:
     153           0 :                         DEBUG(10, ("sys_set_vfs_quota: path[%s] bdev[%s] "
     154             :                                    "SMB_USER_QUOTA_TYPE uid[%u]\n",
     155             :                                    path, bdev, (unsigned)id.uid));
     156             : 
     157           0 :                         ret = quotactl(QCMD(Q_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D);
     158           0 :                         break;
     159           0 :                 case SMB_GROUP_QUOTA_TYPE:
     160           0 :                         DEBUG(10, ("sys_set_vfs_quota: path[%s] bdev[%s] "
     161             :                                    "SMB_GROUP_QUOTA_TYPE gid[%u]\n",
     162             :                                    path, bdev, (unsigned)id.gid));
     163             : 
     164           0 :                         ret = quotactl(QCMD(Q_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D);
     165           0 :                         break;
     166           0 :                 case SMB_USER_FS_QUOTA_TYPE:
     167           0 :                         DEBUG(10, ("sys_set_vfs_quota: path[%s] bdev[%s] "
     168             :                                    "SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
     169             :                                    path, bdev, (unsigned)geteuid()));
     170             : 
     171           0 :                         ret = quotactl(QCMD(Q_GETQUOTA, USRQUOTA), bdev,
     172           0 :                                        geteuid(), (caddr_t)&D);
     173           0 :                         cur_enf = (ret == 0);
     174           0 :                         new_enf = ((dp->qflags & QUOTAS_DENY_DISK) != 0);
     175             :                         /* We're not changing quota enforcement, so return
     176             :                          * success
     177             :                          * IFF the wanted state is identical to the current
     178             :                          * state */
     179           0 :                         if (cur_enf == new_enf) {
     180           0 :                                 ret = 0;
     181             :                         } else {
     182           0 :                                 errno = EPERM;
     183           0 :                                 ret = -1;
     184             :                         }
     185             : 
     186           0 :                         break;
     187           0 :                 case SMB_GROUP_FS_QUOTA_TYPE:
     188           0 :                         DEBUG(10, ("sys_set_vfs_quota: path[%s] bdev[%s] "
     189             :                                    "SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
     190             :                                    path, bdev, (unsigned)getegid()));
     191             : 
     192           0 :                         ret = quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), bdev,
     193           0 :                                        getegid(), (caddr_t)&D);
     194           0 :                         cur_enf = (ret == 0);
     195           0 :                         new_enf = ((dp->qflags & QUOTAS_DENY_DISK) != 0);
     196             :                         /* We're not changing quota enforcement, so return
     197             :                          * success
     198             :                          * IFF the wanted state is identical to the current
     199             :                          * state */
     200           0 :                         if (cur_enf == new_enf) {
     201           0 :                                 ret = 0;
     202             :                         } else {
     203           0 :                                 errno = EPERM;
     204           0 :                                 ret = -1;
     205             :                         }
     206             : 
     207           0 :                         break;
     208           0 :                 default:
     209           0 :                         errno = ENOSYS;
     210           0 :                         return -1;
     211             :         }
     212             : 
     213           0 :         return ret;
     214             : }
     215             : 
     216             : #else /* HAVE_QUOTACTL_LINUX */
     217             :  void dummy_sysquotas_linux(void);
     218             : 
     219             :  void dummy_sysquotas_linux(void){}
     220             : #endif /* HAVE_QUOTACTL_LINUX */

Generated by: LCOV version 1.13