root/source3/lib/sysquotas_4A.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sys_get_vfs_quota
  2. sys_set_vfs_quota
  3. dummy_sysquotas_4A

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    System QUOTA function wrappers for QUOTACTL_4A
   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_4A
  28 #undef HAVE_QUOTACTL_4A
  29 #endif
  30 #endif
  31 
  32 #ifdef HAVE_QUOTACTL_4A
  33 /* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */
  34 /* this is used by: HPUX,IRIX */
  35 
  36 #ifdef HAVE_SYS_TYPES_H
  37 #include <sys/types.h>
  38 #endif
  39 
  40 #ifdef HAVE_ASM_TYPES_H
  41 #include <asm/types.h>
  42 #endif
  43 
  44 #ifdef HAVE_SYS_QUOTA_H
  45 #include <sys/quota.h>
  46 #endif
  47 
  48 #ifndef Q_SETQLIM
  49 #define Q_SETQLIM Q_SETQUOTA
  50 #endif
  51 
  52 #ifndef QCMD
  53 #define QCMD(x,y) x
  54 #endif
  55 
  56 #ifndef QCMD
  57 #define QCMD(x,y) x
  58 #endif
  59 
  60 #ifdef GRPQUOTA
  61 #define HAVE_GROUP_QUOTA
  62 #endif
  63 
  64 #ifndef QUOTABLOCK_SIZE
  65 #define QUOTABLOCK_SIZE DEV_BSIZE
  66 #endif
  67 
  68 #ifdef HAVE_DQB_FSOFTLIMIT
  69 #define dqb_isoftlimit  dqb_fsoftlimit
  70 #define dqb_ihardlimit  dqb_fhardlimit
  71 #define dqb_curinodes   dqb_curfiles
  72 #endif
  73 
  74 #ifdef INITQFNAMES
  75 #define USERQUOTAFILE_EXTENSION ".user"
  76 #else
  77 #define USERQUOTAFILE_EXTENSION ""
  78 #endif
  79 
  80 #if !defined(QUOTAFILENAME) && defined(QFILENAME)
  81 #define QUOTAFILENAME QFILENAME
  82 #endif
  83 
  84 /****************************************************************************
  85  Abstract out the quotactl_4A get calls.
  86 ****************************************************************************/
  87 int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
     /* [<][>][^][v][top][bottom][index][help] */
  88 {
  89         int ret = -1;
  90         uint32 qflags = 0;
  91         struct dqblk D;
  92         uint64_t bsize = (uint64_t)QUOTABLOCK_SIZE;
  93 
  94         ZERO_STRUCT(D);
  95         ZERO_STRUCT(*dp);
  96         dp->qtype = qtype;
  97 
  98         switch (qtype) {
  99                 case SMB_USER_QUOTA_TYPE:
 100                         DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
 101                                 path, bdev, (unsigned)id.uid));
 102 
 103                         if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D))&&errno != EDQUOT) {
 104                                 return ret;
 105                         }
 106 
 107                         if ((D.dqb_curblocks==0)&&
 108                                 (D.dqb_bsoftlimit==0)&&
 109                                 (D.dqb_bhardlimit==0)) {
 110                                 /* the upper layer functions don't want empty quota records...*/
 111                                 return -1;
 112                         }
 113 
 114                         break;
 115 #ifdef HAVE_GROUP_QUOTA
 116                 case SMB_GROUP_QUOTA_TYPE:
 117                         DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
 118                                 path, bdev, (unsigned)id.gid));
 119 
 120                         if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D))&&errno != EDQUOT) {
 121                                 return ret;
 122                         }
 123 
 124                         if ((D.dqb_curblocks==0)&&
 125                                 (D.dqb_bsoftlimit==0)&&
 126                                 (D.dqb_bhardlimit==0)) {
 127                                 /* the upper layer functions don't want empty quota records...*/
 128                                 return -1;
 129                         }
 130 
 131                         break;
 132 #endif /* HAVE_GROUP_QUOTA */
 133                 case SMB_USER_FS_QUOTA_TYPE:
 134                         id.uid = getuid();
 135 
 136                         DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
 137                                 path, (caddr_t)bdev, (unsigned)id.uid));
 138 
 139                         if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D))==0) {
 140                                 qflags |= QUOTAS_DENY_DISK;
 141                         }
 142 
 143                         ret = 0;
 144                         break;
 145 #ifdef HAVE_GROUP_QUOTA
 146                 case SMB_GROUP_FS_QUOTA_TYPE:
 147                         id.gid = getgid();
 148 
 149                         DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
 150                                 path, bdev, (unsigned)id.gid));
 151 
 152                         if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D))==0) {
 153                                 qflags |= QUOTAS_DENY_DISK;
 154                         }
 155 
 156                         ret = 0;
 157                         break;
 158 #endif /* HAVE_GROUP_QUOTA */
 159                 default:
 160                         errno = ENOSYS;
 161                         return -1;
 162         }
 163 
 164         dp->bsize = bsize;
 165         dp->softlimit = (uint64_t)D.dqb_bsoftlimit;
 166         dp->hardlimit = (uint64_t)D.dqb_bhardlimit;
 167         dp->ihardlimit = (uint64_t)D.dqb_ihardlimit;
 168         dp->isoftlimit = (uint64_t)D.dqb_isoftlimit;
 169         dp->curinodes = (uint64_t)D.dqb_curinodes;
 170         dp->curblocks = (uint64_t)D.dqb_curblocks;
 171 
 172 
 173         dp->qflags = qflags;
 174 
 175         return ret;
 176 }
 177 
 178 /****************************************************************************
 179  Abstract out the quotactl_4A set calls.
 180 ****************************************************************************/
 181 int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
     /* [<][>][^][v][top][bottom][index][help] */
 182 {
 183         int ret = -1;
 184         uint32 qflags = 0;
 185         uint32 oldqflags = 0;
 186         struct dqblk D;
 187         uint64_t bsize = (uint64_t)QUOTABLOCK_SIZE;
 188 
 189         ZERO_STRUCT(D);
 190 
 191         if (bsize == dp->bsize) {
 192                 D.dqb_bsoftlimit = dp->softlimit;
 193                 D.dqb_bhardlimit = dp->hardlimit;
 194                 D.dqb_ihardlimit = dp->ihardlimit;
 195                 D.dqb_isoftlimit = dp->isoftlimit;
 196         } else {
 197                 D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize;
 198                 D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize;
 199                 D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize;
 200                 D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize;
 201         }
 202 
 203         qflags = dp->qflags;
 204 
 205         switch (qtype) {
 206                 case SMB_USER_QUOTA_TYPE:
 207                         DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
 208                                 path, bdev, (unsigned)id.uid));
 209 
 210                         ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D);
 211                         break;
 212 #ifdef HAVE_GROUP_QUOTA
 213                 case SMB_GROUP_QUOTA_TYPE:
 214                         DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
 215                                 path, bdev, (unsigned)id.gid));
 216 
 217                         ret = quotactl(QCMD(Q_SETQLIM,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D);
 218                         break;
 219 #endif /* HAVE_GROUP_QUOTA */
 220                 case SMB_USER_FS_QUOTA_TYPE:
 221                         /* this stuff didn't work as it should:
 222                          * switching on/off quota via quotactl()
 223                          * didn't work!
 224                          * So we just return 0
 225                          * --metze
 226                          * 
 227                          * On HPUX we didn't have the mount path,
 228                          * we need to fix sys_path_to_bdev()
 229                          *
 230                          */
 231                         id.uid = getuid();
 232                         DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
 233                                 path, bdev, (unsigned)id.uid));
 234 
 235 #if 0
 236                         ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D);
 237 
 238                         if ((qflags&QUOTAS_DENY_DISK)||(qflags&QUOTAS_ENABLED)) {
 239                                 if (ret == 0) {
 240                                         char *quota_file = NULL;
 241                                         
 242                                         asprintf(&quota_file,"/%s/%s%s",path, QUOTAFILENAME,USERQUOTAFILE_EXTENSION);
 243                                         if (quota_file == NULL) {
 244                                                 DEBUG(0,("asprintf() failed!\n"));
 245                                                 errno = ENOMEM;
 246                                                 return -1;
 247                                         }
 248                                         
 249                                         ret = quotactl(QCMD(Q_QUOTAON,USRQUOTA), (caddr_t)bdev, -1,(void *)quota_file);
 250                                 } else {
 251                                         ret = 0;        
 252                                 }
 253                         } else {
 254                                 if (ret != 0) {
 255                                         /* turn off */
 256                                         ret = quotactl(QCMD(Q_QUOTAOFF,USRQUOTA), (caddr_t)bdev, -1, (void *)0);        
 257                                 } else {
 258                                         ret = 0;
 259                                 }               
 260                         }
 261 
 262                         DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
 263                                 ret,errno,strerror(errno),id.uid,bdev));
 264 #else
 265                         if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D))==0) {
 266                                 oldqflags |= QUOTAS_DENY_DISK;
 267                         }
 268 
 269                         if (oldqflags == qflags) {
 270                                 ret = 0;
 271                         } else {
 272                                 ret = -1;
 273                         }
 274 #endif
 275                         break;
 276 #ifdef HAVE_GROUP_QUOTA
 277                 case SMB_GROUP_FS_QUOTA_TYPE:
 278                         /* this stuff didn't work as it should:
 279                          * switching on/off quota via quotactl()
 280                          * didn't work!
 281                          * So we just return 0
 282                          * --metze
 283                          * 
 284                          * On HPUX we didn't have the mount path,
 285                          * we need to fix sys_path_to_bdev()
 286                          *
 287                          */
 288                         id.gid = getgid();
 289                         DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
 290                                 path, bdev, (unsigned)id.gid));
 291 
 292 #if 0
 293                         ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id, (void *)&D);
 294 
 295                         if ((qflags&QUOTAS_DENY_DISK)||(qflags&QUOTAS_ENABLED)) {
 296                                 if (ret == 0) {
 297                                         char *quota_file = NULL;
 298                                         
 299                                         asprintf(&quota_file,"/%s/%s%s",path, QUOTAFILENAME,GROUPQUOTAFILE_EXTENSION);
 300                                         if (quota_file == NULL) {
 301                                                 DEBUG(0,("asprintf() failed!\n"));
 302                                                 errno = ENOMEM;
 303                                                 return -1;
 304                                         }
 305                                         
 306                                         ret = quotactl(QCMD(Q_QUOTAON,GRPQUOTA), (caddr_t)bdev, -1,(void *)quota_file);
 307                                 } else {
 308                                         ret = 0;        
 309                                 }
 310                         } else {
 311                                 if (ret != 0) {
 312                                         /* turn off */
 313                                         ret = quotactl(QCMD(Q_QUOTAOFF,GRPQUOTA), (caddr_t)bdev, -1, (void *)0);        
 314                                 } else {
 315                                         ret = 0;
 316                                 }               
 317                         }
 318 
 319                         DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
 320                                 ret,errno,strerror(errno),id.gid,bdev));
 321 #else
 322                         if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D))==0) {
 323                                 oldqflags |= QUOTAS_DENY_DISK;
 324                         }
 325 
 326                         if (oldqflags == qflags) {
 327                                 ret = 0;
 328                         } else {
 329                                 ret = -1;
 330                         }
 331 #endif
 332                         break;
 333 #endif /* HAVE_GROUP_QUOTA */
 334                 default:
 335                         errno = ENOSYS;
 336                         return -1;
 337         }
 338 
 339         return ret;
 340 }
 341 
 342 #else /* HAVE_QUOTACTL_4A */
 343  void dummy_sysquotas_4A(void);
 344 
 345  void dummy_sysquotas_4A(void){}
     /* [<][>][^][v][top][bottom][index][help] */
 346 #endif /* HAVE_QUOTACTL_4A */

/* [<][>][^][v][top][bottom][index][help] */