quota: add supprt for gfs2
[samba.git] / source3 / lib / sysquotas.c
index 3223ecb580b06b76437aebf4726bb87351be4638..6682a807275354e7dcf1e32bd4fc8062615a2013 100644 (file)
@@ -5,7 +5,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 
 #include "includes.h"
 
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_QUOTA
+
 #ifdef HAVE_SYS_QUOTAS
 
 #if defined(HAVE_QUOTACTL_4A) 
-/* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */
-/* this is used by: linux,HPUX,IRIX */
-
-/****************************************************************************
- Abstract out the old and new Linux quota get calls.
-****************************************************************************/
-static int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
-       int ret = -1;
-       uint32 qflags = 0;
-       struct SYS_DQBLK D;
-       SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
-
-       if (!path||!bdev||!dp)
-               smb_panic("sys_get_vfs_quota: called with NULL pointer");
-
-       ZERO_STRUCT(D);
-       ZERO_STRUCT(*dp);
-       dp->qtype = qtype;
-
-       switch (qtype) {
-               case SMB_USER_QUOTA_TYPE:
-                       if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D))) {
-                               return ret;
-                       }
-
-                       if ((D.dqb_curblocks==0)&&
-                               (D.dqb_bsoftlimit==0)&&
-                               (D.dqb_bhardlimit==0)) {
-                               /* the upper layer functions don't want empty quota records...*/
-                               return -1;
-                       }
-
-                       break;
-#ifdef HAVE_GROUP_QUOTA
-               case SMB_GROUP_QUOTA_TYPE:
-                       if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (CADDR_T)&D))) {
-                               return ret;
-                       }
-
-                       if ((D.dqb_curblocks==0)&&
-                               (D.dqb_bsoftlimit==0)&&
-                               (D.dqb_bhardlimit==0)) {
-                               /* the upper layer functions don't want empty quota records...*/
-                               return -1;
-                       }
-
-                       break;
-#endif /* HAVE_GROUP_QUOTA */
-               case SMB_USER_FS_QUOTA_TYPE:
-                       id.uid = getuid();
-
-                       if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D))==0) {
-                               qflags |= QUOTAS_DENY_DISK;
-                       }
-
-                       ret = 0;
-                       break;
-#ifdef HAVE_GROUP_QUOTA
-               case SMB_GROUP_FS_QUOTA_TYPE:
-                       id.gid = getgid();
-
-                       if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (CADDR_T)&D))==0) {
-                               qflags |= QUOTAS_DENY_DISK;
-                       }
-
-                       ret = 0;
-                       break;
-#endif /* HAVE_GROUP_QUOTA */
-               default:
-                       errno = ENOSYS;
-                       return -1;
-       }
-
-       dp->bsize = bsize;
-       dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
-       dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
-       dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
-       dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
-       dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
-       dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks;
-
-
-       dp->qflags = qflags;
-
-       return ret;
-}
-
-/****************************************************************************
- Abstract out the old and new Linux quota set calls.
-****************************************************************************/
-
-static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
-       int ret = -1;
-       uint32 qflags = 0;
-       uint32 oldqflags = 0;
-       struct SYS_DQBLK D;
-       SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
-
-       if (!path||!bdev||!dp)
-               smb_panic("sys_set_vfs_quota: called with NULL pointer");
-
-       ZERO_STRUCT(D);
-
-       if (bsize == dp->bsize) {
-               D.dqb_bsoftlimit = dp->softlimit;
-               D.dqb_bhardlimit = dp->hardlimit;
-               D.dqb_ihardlimit = dp->ihardlimit;
-               D.dqb_isoftlimit = dp->isoftlimit;
-       } else {
-               D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize;
-               D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize;
-               D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize;
-               D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize;
-       }
-
-       qflags = dp->qflags;
-
-       switch (qtype) {
-               case SMB_USER_QUOTA_TYPE:
-                       ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), bdev, id.uid, (CADDR_T)&D);
-                       break;
-#ifdef HAVE_GROUP_QUOTA
-               case SMB_GROUP_QUOTA_TYPE:
-                       ret = quotactl(QCMD(Q_SETQLIM,GRPQUOTA), bdev, id.gid, (CADDR_T)&D);
-                       break;
-#endif /* HAVE_GROUP_QUOTA */
-               case SMB_USER_FS_QUOTA_TYPE:
-                       /* this stuff didn't work as it should:
-                        * switching on/off quota via quotactl()
-                        * didn't work!
-                        * So we just return 0
-                        * --metze
-                        * 
-                        * On HPUX we didn't have the mount path,
-                        * we need to fix sys_path_to_bdev()
-                        *
-                        */
-#if 0
-                       id.uid = getuid();
-
-                       ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D);
-
-                       if ((qflags&QUOTAS_DENY_DISK)||(qflags&QUOTAS_ENABLED)) {
-                               if (ret == 0) {
-                                       char *quota_file = NULL;
-                                       
-                                       asprintf(&quota_file,"/%s/%s%s",path, QUOTAFILENAME,USERQUOTAFILE_EXTENSION);
-                                       if (quota_file == NULL) {
-                                               DEBUG(0,("asprintf() failed!\n"));
-                                               errno = ENOMEM;
-                                               return -1;
-                                       }
-                                       
-                                       ret = quotactl(QCMD(Q_QUOTAON,USRQUOTA), bdev, -1,(CADDR_T)quota_file);
-                               } else {
-                                       ret = 0;        
-                               }
-                       } else {
-                               if (ret != 0) {
-                                       /* turn off */
-                                       ret = quotactl(QCMD(Q_QUOTAOFF,USRQUOTA), bdev, -1, (CADDR_T)0);        
-                               } else {
-                                       ret = 0;
-                               }               
-                       }
-
-                       DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
-                               ret,errno,strerror(errno),id.uid,bdev));
-#else
-                       id.uid = getuid();
-
-                       if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D))==0) {
-                               oldqflags |= QUOTAS_DENY_DISK;
-                       }
-
-                       if (oldqflags == qflags) {
-                               ret = 0;
-                       } else {
-                               ret = -1;
-                       }
-#endif
-                       break;
-#ifdef HAVE_GROUP_QUOTA
-               case SMB_GROUP_FS_QUOTA_TYPE:
-                       /* this stuff didn't work as it should:
-                        * switching on/off quota via quotactl()
-                        * didn't work!
-                        * So we just return 0
-                        * --metze
-                        * 
-                        * On HPUX we didn't have the mount path,
-                        * we need to fix sys_path_to_bdev()
-                        *
-                        */
-#if 0
-                       id.gid = getgid();
-
-                       ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id, (CADDR_T)&D);
-
-                       if ((qflags&QUOTAS_DENY_DISK)||(qflags&QUOTAS_ENABLED)) {
-                               if (ret == 0) {
-                                       char *quota_file = NULL;
-                                       
-                                       asprintf(&quota_file,"/%s/%s%s",path, QUOTAFILENAME,GROUPQUOTAFILE_EXTENSION);
-                                       if (quota_file == NULL) {
-                                               DEBUG(0,("asprintf() failed!\n"));
-                                               errno = ENOMEM;
-                                               return -1;
-                                       }
-                                       
-                                       ret = quotactl(QCMD(Q_QUOTAON,GRPQUOTA), bdev, -1,(CADDR_T)quota_file);
-                               } else {
-                                       ret = 0;        
-                               }
-                       } else {
-                               if (ret != 0) {
-                                       /* turn off */
-                                       ret = quotactl(QCMD(Q_QUOTAOFF,GRPQUOTA), bdev, -1, (CADDR_T)0);        
-                               } else {
-                                       ret = 0;
-                               }               
-                       }
-
-                       DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
-                               ret,errno,strerror(errno),id.gid,bdev));
-#else
-                       id.gid = getgid();
-
-                       if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (CADDR_T)&D))==0) {
-                               oldqflags |= QUOTAS_DENY_DISK;
-                       }
-
-                       if (oldqflags == qflags) {
-                               ret = 0;
-                       } else {
-                               ret = -1;
-                       }
-#endif
-                       break;
-#endif /* HAVE_GROUP_QUOTA */
-               default:
-                       errno = ENOSYS;
-                       return -1;
-       }
-
-       return ret;
-}
 
 /*#endif HAVE_QUOTACTL_4A */
 #elif defined(HAVE_QUOTACTL_4B)
@@ -287,30 +40,6 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
 /* #endif  HAVE_QUOTACTL_3 */
 #else /* NO_QUOTACTL_USED */
 
-static int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
-       int ret = -1;
-
-       if (!path||!bdev||!dp)
-               smb_panic("sys_get_vfs_quota: called with NULL pointer");
-               
-       errno = ENOSYS;
-
-       return ret;
-}
-
-static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
-       int ret = -1;
-
-       if (!path||!bdev||!dp)
-               smb_panic("sys_set_vfs_quota: called with NULL pointer");
-
-       errno = ENOSYS;
-
-       return ret;
-}
-
 #endif /* NO_QUOTACTL_USED */
 
 #ifdef HAVE_MNTENT
@@ -331,21 +60,24 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char
        (*bdev) = NULL;
        (*fs) = NULL;
        
-       if ( sys_stat(path, &S) == -1 )
+       if ( sys_stat(path, &S, false) == -1 )
                return (-1);
 
-       devno = S.st_dev ;
+       devno = S.st_ex_dev ;
 
        fp = setmntent(MOUNTED,"r");
+       if (fp == NULL) {
+               return -1;
+       }
   
        while ((mnt = getmntent(fp))) {
-               if ( sys_stat(mnt->mnt_dir,&S) == -1 )
+               if ( sys_stat(mnt->mnt_dir, &S, false) == -1 )
                        continue ;
 
-               if (S.st_dev == devno) {
-                       (*mntpath) = strdup(mnt->mnt_dir);
-                       (*bdev) = strdup(mnt->mnt_fsname);
-                       (*fs)   = strdup(mnt->mnt_type);
+               if (S.st_ex_dev == devno) {
+                       (*mntpath) = SMB_STRDUP(mnt->mnt_dir);
+                       (*bdev) = SMB_STRDUP(mnt->mnt_fsname);
+                       (*fs)   = SMB_STRDUP(mnt->mnt_type);
                        if ((*mntpath)&&(*bdev)&&(*fs)) {
                                ret = 0;
                        } else {
@@ -382,11 +114,11 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char
        
        /* find the block device file */
 
-       if ((ret=sys_stat(path, &S))!=0) {
+       if ((ret=sys_stat(path, &S, false))!=0) {
                return ret;
        }
        
-       if ((ret=devnm(S_IFBLK, S.st_dev, dev_disk, 256, 1))!=0) {
+       if ((ret=devnm(S_IFBLK, S.st_ex_dev, dev_disk, 256, 1))!=0) {
                return ret;     
        }
 
@@ -394,8 +126,8 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char
         * but I don't know how
         * --metze
         */
-       (*mntpath) = strdup(path);
-       (*bdev) = strdup(dev_disk);
+       (*mntpath) = SMB_STRDUP(path);
+       (*bdev) = SMB_STRDUP(dev_disk);
        if ((*mntpath)&&(*bdev)) {
                ret = 0;
        } else {
@@ -422,7 +154,7 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char
        (*bdev) = NULL;
        (*fs) = NULL;
        
-       (*mntpath) = strdup(path);
+       (*mntpath) = SMB_STRDUP(path);
        if (*mntpath) {
                ret = 0;
        } else {
@@ -434,262 +166,6 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char
 }
 #endif
 
-
-/*********************************************************
- if we have XFS QUOTAS we should use them
- *********************************************************/
-#ifdef HAVE_XFS_QUOTA
-/****************************************************************************
- Abstract out the XFS Quota Manager quota get call.
-****************************************************************************/
-static int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
-       int ret = -1;
-       uint32 qflags = 0;
-       SMB_BIG_UINT bsize = (SMB_BIG_UINT)BBSIZE;
-       struct fs_disk_quota D;
-       struct fs_quota_stat F;
-       ZERO_STRUCT(D);
-       ZERO_STRUCT(F);
-
-       if (!bdev||!dp)
-               smb_panic("sys_get_xfs_quota: called with NULL pointer");
-               
-       ZERO_STRUCT(*dp);
-       dp->qtype = qtype;
-               
-       switch (qtype) {
-               case SMB_USER_QUOTA_TYPE:
-                       if ((ret=quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D)))
-                               return ret;
-                       break;
-#ifdef HAVE_GROUP_QUOTA
-               case SMB_GROUP_QUOTA_TYPE:
-                       if ((ret=quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), bdev, id.gid, (CADDR_T)&D)))
-                               return ret;
-                       break;
-#endif /* HAVE_GROUP_QUOTA */
-               case SMB_USER_FS_QUOTA_TYPE:    
-                       quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (CADDR_T)&F);
-
-                       if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) {
-                               qflags |= QUOTAS_DENY_DISK;
-                       }
-                       else if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) {
-                               qflags |= QUOTAS_ENABLED;
-                       }
-
-                       ret = 0;
-
-                       break;
-#ifdef HAVE_GROUP_QUOTA
-               case SMB_GROUP_FS_QUOTA_TYPE:   
-                       quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (CADDR_T)&F);
-
-                       if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) {
-                               qflags |= QUOTAS_DENY_DISK;
-                       }
-                       else if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) {
-                               qflags |= QUOTAS_ENABLED;
-                       }
-
-                       ret = 0;
-
-                       break;
-#endif /* HAVE_GROUP_QUOTA */
-               default:
-                       errno = ENOSYS;
-                       return -1;
-       }
-
-       dp->bsize = bsize;
-       dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit;
-       dp->hardlimit = (SMB_BIG_UINT)D.d_blk_hardlimit;
-       dp->ihardlimit = (SMB_BIG_UINT)D.d_ino_hardlimit;
-       dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit;
-       dp->curinodes = (SMB_BIG_UINT)D.d_icount;
-       dp->curblocks = (SMB_BIG_UINT)D.d_bcount;
-       dp->qflags = qflags;
-
-       return ret;
-}
-
-/****************************************************************************
- Abstract out the XFS Quota Manager quota set call.
-****************************************************************************/
-static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
-{
-       int ret = -1;
-       uint32 qflags = 0;
-       SMB_BIG_UINT bsize = (SMB_BIG_UINT)BBSIZE;
-       struct fs_disk_quota D;
-       struct fs_quota_stat F;
-       int q_on = 0;
-       int q_off = 0;
-       ZERO_STRUCT(D);
-       ZERO_STRUCT(F);
-
-       if (!bdev||!dp)
-               smb_panic("sys_set_xfs_quota: called with NULL pointer");
-       
-       if (bsize == dp->bsize) {
-               D.d_blk_softlimit = dp->softlimit;
-               D.d_blk_hardlimit = dp->hardlimit;
-               D.d_ino_hardlimit = dp->ihardlimit;
-               D.d_ino_softlimit = dp->isoftlimit;
-       } else {
-               D.d_blk_softlimit = (dp->softlimit*dp->bsize)/bsize;
-               D.d_blk_hardlimit = (dp->hardlimit*dp->bsize)/bsize;
-               D.d_ino_hardlimit = (dp->ihardlimit*dp->bsize)/bsize;
-               D.d_ino_softlimit = (dp->isoftlimit*dp->bsize)/bsize;           
-       }
-
-       qflags = dp->qflags;
-
-       switch (qtype) {
-               case SMB_USER_QUOTA_TYPE:
-                       D.d_fieldmask |= FS_DQ_LIMIT_MASK;
-                       ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, id.uid, (CADDR_T)&D);
-                       break;
-#ifdef HAVE_GROUP_QUOTA
-               case SMB_GROUP_QUOTA_TYPE:
-                       D.d_fieldmask |= FS_DQ_LIMIT_MASK;
-                       ret = quotactl(QCMD(Q_XSETQLIM,GRPQUOTA), bdev, id.gid, (CADDR_T)&D);
-                       break;
-#endif /* HAVE_GROUP_QUOTA */
-               case SMB_USER_FS_QUOTA_TYPE:
-                       quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (CADDR_T)&F);
-                       
-                       if (qflags & QUOTAS_DENY_DISK) {
-                               if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD))
-                                       q_on |= XFS_QUOTA_UDQ_ENFD;
-                               if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
-                                       q_on |= XFS_QUOTA_UDQ_ACCT;
-                               
-                               if (q_on != 0) {
-                                       ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (CADDR_T)&q_on);
-                               } else {
-                                       ret = 0;
-                               }
-
-                       } else if (qflags & QUOTAS_ENABLED) {
-                               if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
-                                       q_off |= XFS_QUOTA_UDQ_ENFD;
-
-                               if (q_off != 0) {
-                                       ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (CADDR_T)&q_off);
-                               } else {
-                                       ret = 0;
-                               }
-
-                               if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
-                                       q_on |= XFS_QUOTA_UDQ_ACCT;
-
-                               if (q_on != 0) {
-                                       ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (CADDR_T)&q_on);
-                               } else {
-                                       ret = 0;
-                               }
-                       } else {
-#if 0
-                       /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
-                        * only swittching off XFS_QUOTA_UDQ_ACCT work
-                        */
-                               if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
-                                       q_off |= XFS_QUOTA_UDQ_ENFD;
-                               if (F.qs_flags & XFS_QUOTA_UDQ_ACCT)
-                                       q_off |= XFS_QUOTA_UDQ_ACCT;
-
-                               if (q_off !=0) {
-                                       ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (CADDR_T)&q_off);
-                               } else {
-                                       ret = 0;
-                               }
-#else
-                               ret = -1;
-#endif
-                       }
-
-                       break;
-#ifdef HAVE_GROUP_QUOTA
-               case SMB_GROUP_FS_QUOTA_TYPE:
-                       quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (CADDR_T)&F);
-                       
-                       if (qflags & QUOTAS_DENY_DISK) {
-                               if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD))
-                                       q_on |= XFS_QUOTA_UDQ_ENFD;
-                               if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
-                                       q_on |= XFS_QUOTA_UDQ_ACCT;
-                               
-                               if (q_on != 0) {
-                                       ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (CADDR_T)&q_on);
-                               } else {
-                                       ret = 0;
-                               }
-
-                       } else if (qflags & QUOTAS_ENABLED) {
-                               if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
-                                       q_off |= XFS_QUOTA_UDQ_ENFD;
-
-                               if (q_off != 0) {
-                                       ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (CADDR_T)&q_off);
-                               } else {
-                                       ret = 0;
-                               }
-
-                               if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
-                                       q_on |= XFS_QUOTA_UDQ_ACCT;
-
-                               if (q_on != 0) {
-                                       ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (CADDR_T)&q_on);
-                               } else {
-                                       ret = 0;
-                               }
-                       } else {
-#if 0
-                       /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
-                        * only swittching off XFS_QUOTA_UDQ_ACCT work
-                        */
-                               if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
-                                       q_off |= XFS_QUOTA_UDQ_ENFD;
-                               if (F.qs_flags & XFS_QUOTA_UDQ_ACCT)
-                                       q_off |= XFS_QUOTA_UDQ_ACCT;
-
-                               if (q_off !=0) {
-                                       ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (CADDR_T)&q_off);
-                               } else {
-                                       ret = 0;
-                               }
-#else
-                               ret = -1;
-#endif
-                       }
-
-                       break;
-#endif /* HAVE_GROUP_QUOTA */
-               default:
-                       errno = ENOSYS;
-                       return -1;
-       }
-
-       return ret;
-}
-#endif /* HAVE_XFS_QUOTA */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 /*********************************************************************
  Now the list of all filesystem specific quota systems we have found
 **********************************************************************/
@@ -698,22 +174,24 @@ static struct {
        int (*get_quota)(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp);
        int (*set_quota)(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp);
 } sys_quota_backends[] = {
-#ifdef HAVE_XFS_QUOTA
+#ifdef HAVE_XFS_QUOTAS
        {"xfs", sys_get_xfs_quota,      sys_set_xfs_quota},
-#endif /* HAVE_XFS_QUOTA */
-       {NULL,  NULL,                   NULL}   
+       {"gfs", sys_get_xfs_quota,      sys_set_xfs_quota},
+       {"gfs2", sys_get_xfs_quota,     sys_set_xfs_quota},
+#endif /* HAVE_XFS_QUOTAS */
+       {NULL,  NULL,                   NULL}
 };
 
 static int command_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
 {
        const char *get_quota_command;
-       
+       char **lines = NULL;
+
        get_quota_command = lp_get_quota_command();
        if (get_quota_command && *get_quota_command) {
                const char *p;
                char *p2;
-               char **lines;
-               pstring syscmd;
+               char *syscmd = NULL;
                int _id = -1;
 
                switch(qtype) {
@@ -730,13 +208,16 @@ static int command_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t
                                return -1;
                }
 
-               slprintf(syscmd, sizeof(syscmd)-1, 
-                       "%s \"%s\" %d %d", 
-                       get_quota_command, path, qtype, _id);
+               if (asprintf(&syscmd, "%s \"%s\" %d %d",
+                       get_quota_command, path, qtype, _id) < 0) {
+                       return -1;
+               }
 
                DEBUG (3, ("get_quota: Running command %s\n", syscmd));
 
                lines = file_lines_pload(syscmd, NULL);
+               SAFE_FREE(syscmd);
+
                if (lines) {
                        char *line = lines[0];
 
@@ -746,49 +227,79 @@ static int command_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t
 
                        dp->qflags = (enum SMB_QUOTA_TYPE)strtoul(line, &p2, 10);
                        p = p2;
-                       while (p && *p && isspace(*p))
+                       while (p && *p && isspace(*p)) {
                                p++;
-                       if (p && *p)
+                       }
+
+                       if (p && *p) {
                                dp->curblocks = STR_TO_SMB_BIG_UINT(p, &p);
-                       else 
+                       } else {
                                goto invalid_param;
-                       while (p && *p && isspace(*p))
+                       }
+
+                       while (p && *p && isspace(*p)) {
                                p++;
-                       if (p && *p)
+                       }
+
+                       if (p && *p) {
                                dp->softlimit = STR_TO_SMB_BIG_UINT(p, &p);
-                       else
+                       } else {
                                goto invalid_param;
-                       while (p && *p && isspace(*p))
+                       }
+
+                       while (p && *p && isspace(*p)) {
                                p++;
-                       if (p && *p)
+                       }
+
+                       if (p && *p) {
                                dp->hardlimit = STR_TO_SMB_BIG_UINT(p, &p);
-                       else 
+                       } else {
                                goto invalid_param;
-                       while (p && *p && isspace(*p))
+                       }
+
+                       while (p && *p && isspace(*p)) {
                                p++;
-                       if (p && *p)
+                       }
+
+                       if (p && *p) {
                                dp->curinodes = STR_TO_SMB_BIG_UINT(p, &p);
-                       else
+                       } else {
                                goto invalid_param;
-                       while (p && *p && isspace(*p))
+                       }
+
+                       while (p && *p && isspace(*p)) {
                                p++;
-                       if (p && *p)
+                       }
+
+                       if (p && *p) {
                                dp->isoftlimit = STR_TO_SMB_BIG_UINT(p, &p);
-                       else
+                       } else {
                                goto invalid_param;
-                       while (p && *p && isspace(*p))
+                       }
+
+                       while (p && *p && isspace(*p)) {
                                p++;
-                       if (p && *p)
+                       }
+
+                       if (p && *p) {
                                dp->ihardlimit = STR_TO_SMB_BIG_UINT(p, &p);
-                       else
+                       } else {
                                goto invalid_param;     
-                       while (p && *p && isspace(*p))
+                       }
+
+                       while (p && *p && isspace(*p)) {
                                p++;
-                       if (p && *p)
+                       }
+
+                       if (p && *p) {
                                dp->bsize = STR_TO_SMB_BIG_UINT(p, NULL);
-                       else
+                       } else {
                                dp->bsize = 1024;
-                       file_lines_free(lines);
+                       }
+
+                       TALLOC_FREE(lines);
+                       lines = NULL;
+
                        DEBUG (3, ("Parsed output of get_quota, ...\n"));
 
 #ifdef LARGE_SMB_OFF_T
@@ -819,8 +330,10 @@ static int command_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t
 
        errno = ENOSYS;
        return -1;
-       
+
 invalid_param:
+
+       TALLOC_FREE(lines);
        DEBUG(0,("The output of get_quota_command is invalid!\n"));
        return -1;
 }
@@ -828,11 +341,11 @@ invalid_param:
 static int command_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
 {
        const char *set_quota_command;
-       
+
        set_quota_command = lp_set_quota_command();
        if (set_quota_command && *set_quota_command) {
-               char **lines;
-               pstring syscmd;
+               char **lines = NULL;
+               char *syscmd = NULL;
                int _id = -1;
 
                switch(qtype) {
@@ -849,37 +362,40 @@ static int command_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t
                }
 
 #ifdef LARGE_SMB_OFF_T
-               slprintf(syscmd, sizeof(syscmd)-1, 
+               if (asprintf(&syscmd,
                        "%s \"%s\" %d %d "
                        "%u %llu %llu "
-                       "%llu %llu %llu ", 
+                       "%llu %llu %llu ",
                        set_quota_command, path, qtype, _id, dp->qflags,
                        (long long unsigned)dp->softlimit,(long long unsigned)dp->hardlimit,
                        (long long unsigned)dp->isoftlimit,(long long unsigned)dp->ihardlimit,
-                       (long long unsigned)dp->bsize);
+                       (long long unsigned)dp->bsize) < 0) {
+                       return -1;
+               }
 #else /* LARGE_SMB_OFF_T */
-               slprintf(syscmd, sizeof(syscmd)-1, 
+               if (asprintf(&syscmd,
                        "%s \"%s\" %d %d "
                        "%u %lu %lu "
-                       "%lu %lu %lu ", 
+                       "%lu %lu %lu ",
                        set_quota_command, path, qtype, _id, dp->qflags,
                        (long unsigned)dp->softlimit,(long unsigned)dp->hardlimit,
                        (long unsigned)dp->isoftlimit,(long unsigned)dp->ihardlimit,
-                       (long unsigned)dp->bsize);
+                       (long unsigned)dp->bsize) < 0) {
+                       return -1;
+               }
 #endif /* LARGE_SMB_OFF_T */
 
-
-
                DEBUG (3, ("get_quota: Running command %s\n", syscmd));
 
                lines = file_lines_pload(syscmd, NULL);
+               SAFE_FREE(syscmd);
                if (lines) {
                        char *line = lines[0];
 
                        DEBUG (3, ("Read output from set_quota, \"%s\"\n", line));
 
-                       file_lines_free(lines);
-                       
+                       TALLOC_FREE(lines);
+
                        return 0;
                }
                DEBUG (0, ("set_quota_command failed!\n"));
@@ -894,7 +410,7 @@ int sys_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI
 {
        int ret = -1;
        int i;
-       BOOL ready = False;
+       bool ready = False;
        char *mntpath = NULL;
        char *bdev = NULL;
        char *fs = NULL;
@@ -913,12 +429,18 @@ int sys_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI
                return ret;
        }
 
+       errno = 0;
+       DEBUG(10,("sys_get_quota() uid(%u, %u)\n", (unsigned)getuid(), (unsigned)geteuid()));
+
        for (i=0;(fs && sys_quota_backends[i].name && sys_quota_backends[i].get_quota);i++) {
                if (strcmp(fs,sys_quota_backends[i].name)==0) {
                        ret = sys_quota_backends[i].get_quota(mntpath, bdev, qtype, id, dp);
                        if (ret!=0) {
-                               DEBUG(10,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n",
-                                       fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret));
+                               DEBUG(3,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d]: %s.\n",
+                                       fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),strerror(errno)));
+                       } else {
+                               DEBUG(10,("sys_get_%s_quota() called for mntpath[%s] bdev[%s] qtype[%d] id[%d].\n",
+                                       fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid)));
                        }
                        ready = True;
                        break;  
@@ -929,8 +451,11 @@ int sys_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI
                /* use the default vfs quota functions */
                ret=sys_get_vfs_quota(mntpath, bdev, qtype, id, dp);
                if (ret!=0) {
-                       DEBUG(10,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n",
-                               "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret));
+                       DEBUG(3,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d]: %s\n",
+                               "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),strerror(errno)));
+               } else {
+                       DEBUG(10,("sys_get_%s_quota() called for mntpath[%s] bdev[%s] qtype[%d] id[%d].\n",
+                               "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid)));
                }
        }
 
@@ -939,6 +464,7 @@ int sys_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI
        SAFE_FREE(fs);
 
        if ((ret!=0)&& (errno == EDQUOT)) {
+               DEBUG(10,("sys_get_quota() warning over quota!\n"));
                return 0;
        }
 
@@ -949,7 +475,7 @@ int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI
 {
        int ret = -1;
        int i;
-       BOOL ready = False;
+       bool ready = False;
        char *mntpath = NULL;
        char *bdev = NULL;
        char *fs = NULL;
@@ -970,12 +496,18 @@ int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI
                return ret;
        }
 
+       errno = 0;
+       DEBUG(10,("sys_set_quota() uid(%u, %u)\n", (unsigned)getuid(), (unsigned)geteuid())); 
+
        for (i=0;(fs && sys_quota_backends[i].name && sys_quota_backends[i].set_quota);i++) {
                if (strcmp(fs,sys_quota_backends[i].name)==0) {
                        ret = sys_quota_backends[i].set_quota(mntpath, bdev, qtype, id, dp);
                        if (ret!=0) {
-                               DEBUG(10,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n",
-                                       fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret));
+                               DEBUG(3,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d]: %s.\n",
+                                       fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),strerror(errno)));
+                       } else {
+                               DEBUG(10,("sys_set_%s_quota() called for mntpath[%s] bdev[%s] qtype[%d] id[%d].\n",
+                                       fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid)));
                        }
                        ready = True;
                        break;
@@ -986,8 +518,11 @@ int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI
                /* use the default vfs quota functions */
                ret=sys_set_vfs_quota(mntpath, bdev, qtype, id, dp);
                if (ret!=0) {
-                       DEBUG(10,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n",
-                               "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret));
+                       DEBUG(3,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d]: %s.\n",
+                               "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),strerror(errno)));
+               } else {
+                       DEBUG(10,("sys_set_%s_quota() called for mntpath[%s] bdev[%s] qtype[%d] id[%d].\n",
+                               "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid)));
                }
        }
 
@@ -996,6 +531,7 @@ int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI
        SAFE_FREE(fs);
 
        if ((ret!=0)&& (errno == EDQUOT)) {
+               DEBUG(10,("sys_set_quota() warning over quota!\n"));
                return 0;
        }
 
@@ -1003,6 +539,8 @@ int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI
 }
 
 #else /* HAVE_SYS_QUOTAS */
+ void dummy_sysquotas_c(void);
+
  void dummy_sysquotas_c(void)
 {
        return;