00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00035
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
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
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
00129 return -1;
00130 }
00131
00132 break;
00133 #endif
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
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
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
00221 case SMB_USER_FS_QUOTA_TYPE:
00222
00223
00224
00225
00226
00227
00228
00229
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"AS_DENY_DISK)||(qflags"AS_ENABLED)) {
00240 if (ret == 0) {
00241 char *quota_file = NULL;
00242
00243 asprintf("a_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
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
00280
00281
00282
00283
00284
00285
00286
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"AS_DENY_DISK)||(qflags"AS_ENABLED)) {
00297 if (ret == 0) {
00298 char *quota_file = NULL;
00299
00300 asprintf("a_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
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
00335 default:
00336 errno = ENOSYS;
00337 return -1;
00338 }
00339
00340 return ret;
00341 }
00342
00343 #else
00344 void dummy_sysquotas_4A(void);
00345
00346 void dummy_sysquotas_4A(void){}
00347 #endif