lib/sysquotas_4A.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    System QUOTA function wrappers for QUOTACTL_4A
00004    Copyright (C) Stefan (metze) Metzmacher      2003
00005    
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015    
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 */
00020 
00021 
00022 #include "includes.h"
00023 
00024 #undef DBGC_CLASS
00025 #define DBGC_CLASS DBGC_QUOTA
00026 
00027 #ifndef HAVE_SYS_QUOTAS
00028 #ifdef HAVE_QUOTACTL_4A
00029 #undef HAVE_QUOTACTL_4A
00030 #endif
00031 #endif
00032 
00033 #ifdef HAVE_QUOTACTL_4A
00034 /* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */
00035 /* this is used by: HPUX,IRIX */
00036 
00037 #ifdef HAVE_SYS_TYPES_H
00038 #include <sys/types.h>
00039 #endif
00040 
00041 #ifdef HAVE_ASM_TYPES_H
00042 #include <asm/types.h>
00043 #endif
00044 
00045 #ifdef HAVE_SYS_QUOTA_H
00046 #include <sys/quota.h>
00047 #endif
00048 
00049 #ifndef Q_SETQLIM
00050 #define Q_SETQLIM Q_SETQUOTA
00051 #endif
00052 
00053 #ifndef QCMD
00054 #define QCMD(x,y) x
00055 #endif
00056 
00057 #ifndef QCMD
00058 #define QCMD(x,y) x
00059 #endif
00060 
00061 #ifdef GRPQUOTA
00062 #define HAVE_GROUP_QUOTA
00063 #endif
00064 
00065 #ifndef QUOTABLOCK_SIZE
00066 #define QUOTABLOCK_SIZE DEV_BSIZE
00067 #endif
00068 
00069 #ifdef HAVE_DQB_FSOFTLIMIT
00070 #define dqb_isoftlimit  dqb_fsoftlimit
00071 #define dqb_ihardlimit  dqb_fhardlimit
00072 #define dqb_curinodes   dqb_curfiles
00073 #endif
00074 
00075 #ifdef INITQFNAMES
00076 #define USERQUOTAFILE_EXTENSION ".user"
00077 #else
00078 #define USERQUOTAFILE_EXTENSION ""
00079 #endif
00080 
00081 #if !defined(QUOTAFILENAME) && defined(QFILENAME)
00082 #define QUOTAFILENAME QFILENAME
00083 #endif
00084 
00085 /****************************************************************************
00086  Abstract out the quotactl_4A get calls.
00087 ****************************************************************************/
00088 int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
00089 {
00090         int ret = -1;
00091         uint32 qflags = 0;
00092         struct dqblk D;
00093         SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
00094 
00095         ZERO_STRUCT(D);
00096         ZERO_STRUCT(*dp);
00097         dp->qtype = qtype;
00098 
00099         switch (qtype) {
00100                 case SMB_USER_QUOTA_TYPE:
00101                         DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
00102                                 path, bdev, (unsigned)id.uid));
00103 
00104                         if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D))&&errno != EDQUOT) {
00105                                 return ret;
00106                         }
00107 
00108                         if ((D.dqb_curblocks==0)&&
00109                                 (D.dqb_bsoftlimit==0)&&
00110                                 (D.dqb_bhardlimit==0)) {
00111                                 /* the upper layer functions don't want empty quota records...*/
00112                                 return -1;
00113                         }
00114 
00115                         break;
00116 #ifdef HAVE_GROUP_QUOTA
00117                 case SMB_GROUP_QUOTA_TYPE:
00118                         DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
00119                                 path, bdev, (unsigned)id.gid));
00120 
00121                         if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D))&&errno != EDQUOT) {
00122                                 return ret;
00123                         }
00124 
00125                         if ((D.dqb_curblocks==0)&&
00126                                 (D.dqb_bsoftlimit==0)&&
00127                                 (D.dqb_bhardlimit==0)) {
00128                                 /* the upper layer functions don't want empty quota records...*/
00129                                 return -1;
00130                         }
00131 
00132                         break;
00133 #endif /* HAVE_GROUP_QUOTA */
00134                 case SMB_USER_FS_QUOTA_TYPE:
00135                         id.uid = getuid();
00136 
00137                         DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
00138                                 path, (caddr_t)bdev, (unsigned)id.uid));
00139 
00140                         if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D))==0) {
00141                                 qflags |= QUOTAS_DENY_DISK;
00142                         }
00143 
00144                         ret = 0;
00145                         break;
00146 #ifdef HAVE_GROUP_QUOTA
00147                 case SMB_GROUP_FS_QUOTA_TYPE:
00148                         id.gid = getgid();
00149 
00150                         DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
00151                                 path, bdev, (unsigned)id.gid));
00152 
00153                         if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D))==0) {
00154                                 qflags |= QUOTAS_DENY_DISK;
00155                         }
00156 
00157                         ret = 0;
00158                         break;
00159 #endif /* HAVE_GROUP_QUOTA */
00160                 default:
00161                         errno = ENOSYS;
00162                         return -1;
00163         }
00164 
00165         dp->bsize = bsize;
00166         dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
00167         dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
00168         dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
00169         dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
00170         dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
00171         dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks;
00172 
00173 
00174         dp->qflags = qflags;
00175 
00176         return ret;
00177 }
00178 
00179 /****************************************************************************
00180  Abstract out the quotactl_4A set calls.
00181 ****************************************************************************/
00182 int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
00183 {
00184         int ret = -1;
00185         uint32 qflags = 0;
00186         uint32 oldqflags = 0;
00187         struct dqblk D;
00188         SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
00189 
00190         ZERO_STRUCT(D);
00191 
00192         if (bsize == dp->bsize) {
00193                 D.dqb_bsoftlimit = dp->softlimit;
00194                 D.dqb_bhardlimit = dp->hardlimit;
00195                 D.dqb_ihardlimit = dp->ihardlimit;
00196                 D.dqb_isoftlimit = dp->isoftlimit;
00197         } else {
00198                 D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize;
00199                 D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize;
00200                 D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize;
00201                 D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize;
00202         }
00203 
00204         qflags = dp->qflags;
00205 
00206         switch (qtype) {
00207                 case SMB_USER_QUOTA_TYPE:
00208                         DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
00209                                 path, bdev, (unsigned)id.uid));
00210 
00211                         ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D);
00212                         break;
00213 #ifdef HAVE_GROUP_QUOTA
00214                 case SMB_GROUP_QUOTA_TYPE:
00215                         DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
00216                                 path, bdev, (unsigned)id.gid));
00217 
00218                         ret = quotactl(QCMD(Q_SETQLIM,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D);
00219                         break;
00220 #endif /* HAVE_GROUP_QUOTA */
00221                 case SMB_USER_FS_QUOTA_TYPE:
00222                         /* this stuff didn't work as it should:
00223                          * switching on/off quota via quotactl()
00224                          * didn't work!
00225                          * So we just return 0
00226                          * --metze
00227                          * 
00228                          * On HPUX we didn't have the mount path,
00229                          * we need to fix sys_path_to_bdev()
00230                          *
00231                          */
00232                         id.uid = getuid();
00233                         DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
00234                                 path, bdev, (unsigned)id.uid));
00235 
00236 #if 0
00237                         ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D);
00238 
00239                         if ((qflags&QUOTAS_DENY_DISK)||(qflags&QUOTAS_ENABLED)) {
00240                                 if (ret == 0) {
00241                                         char *quota_file = NULL;
00242                                         
00243                                         asprintf(&quota_file,"/%s/%s%s",path, QUOTAFILENAME,USERQUOTAFILE_EXTENSION);
00244                                         if (quota_file == NULL) {
00245                                                 DEBUG(0,("asprintf() failed!\n"));
00246                                                 errno = ENOMEM;
00247                                                 return -1;
00248                                         }
00249                                         
00250                                         ret = quotactl(QCMD(Q_QUOTAON,USRQUOTA), (caddr_t)bdev, -1,(void *)quota_file);
00251                                 } else {
00252                                         ret = 0;        
00253                                 }
00254                         } else {
00255                                 if (ret != 0) {
00256                                         /* turn off */
00257                                         ret = quotactl(QCMD(Q_QUOTAOFF,USRQUOTA), (caddr_t)bdev, -1, (void *)0);        
00258                                 } else {
00259                                         ret = 0;
00260                                 }               
00261                         }
00262 
00263                         DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
00264                                 ret,errno,strerror(errno),id.uid,bdev));
00265 #else
00266                         if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D))==0) {
00267                                 oldqflags |= QUOTAS_DENY_DISK;
00268                         }
00269 
00270                         if (oldqflags == qflags) {
00271                                 ret = 0;
00272                         } else {
00273                                 ret = -1;
00274                         }
00275 #endif
00276                         break;
00277 #ifdef HAVE_GROUP_QUOTA
00278                 case SMB_GROUP_FS_QUOTA_TYPE:
00279                         /* this stuff didn't work as it should:
00280                          * switching on/off quota via quotactl()
00281                          * didn't work!
00282                          * So we just return 0
00283                          * --metze
00284                          * 
00285                          * On HPUX we didn't have the mount path,
00286                          * we need to fix sys_path_to_bdev()
00287                          *
00288                          */
00289                         id.gid = getgid();
00290                         DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
00291                                 path, bdev, (unsigned)id.gid));
00292 
00293 #if 0
00294                         ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id, (void *)&D);
00295 
00296                         if ((qflags&QUOTAS_DENY_DISK)||(qflags&QUOTAS_ENABLED)) {
00297                                 if (ret == 0) {
00298                                         char *quota_file = NULL;
00299                                         
00300                                         asprintf(&quota_file,"/%s/%s%s",path, QUOTAFILENAME,GROUPQUOTAFILE_EXTENSION);
00301                                         if (quota_file == NULL) {
00302                                                 DEBUG(0,("asprintf() failed!\n"));
00303                                                 errno = ENOMEM;
00304                                                 return -1;
00305                                         }
00306                                         
00307                                         ret = quotactl(QCMD(Q_QUOTAON,GRPQUOTA), (caddr_t)bdev, -1,(void *)quota_file);
00308                                 } else {
00309                                         ret = 0;        
00310                                 }
00311                         } else {
00312                                 if (ret != 0) {
00313                                         /* turn off */
00314                                         ret = quotactl(QCMD(Q_QUOTAOFF,GRPQUOTA), (caddr_t)bdev, -1, (void *)0);        
00315                                 } else {
00316                                         ret = 0;
00317                                 }               
00318                         }
00319 
00320                         DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
00321                                 ret,errno,strerror(errno),id.gid,bdev));
00322 #else
00323                         if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D))==0) {
00324                                 oldqflags |= QUOTAS_DENY_DISK;
00325                         }
00326 
00327                         if (oldqflags == qflags) {
00328                                 ret = 0;
00329                         } else {
00330                                 ret = -1;
00331                         }
00332 #endif
00333                         break;
00334 #endif /* HAVE_GROUP_QUOTA */
00335                 default:
00336                         errno = ENOSYS;
00337                         return -1;
00338         }
00339 
00340         return ret;
00341 }
00342 
00343 #else /* HAVE_QUOTACTL_4A */
00344  void dummy_sysquotas_4A(void);
00345 
00346  void dummy_sysquotas_4A(void){}
00347 #endif /* HAVE_QUOTACTL_4A */

Sambaに対してSat Aug 29 21:22:59 2009に生成されました。  doxygen 1.4.7