1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-23 09:57:40 +03:00

Patch from Stefan (metze) Metzmacher <metze at metzemix.de> to revert to 2.2.x quota methods.

:-).

"here's a patch which ports the samba 2.2 samba_linux_quota.h stuff to 3_0.

This is needed because of so many broken quota files outthere.

Please, test this with old, new kernels
(strucr dqblk, struct mem_dqblk, and struct if_dqblk)
, quota.user, aquota.user formats

what is when a user is over soft quota and over hard quotas..."

Jeremy.
This commit is contained in:
Jeremy Allison -
parent 84d34e32be
commit 4350aa6ce6
5 changed files with 137 additions and 780 deletions

View File

@ -351,8 +351,9 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/vfs.o smbd/vfs-wrap.o smbd/statcache.o \ smbd/vfs.o smbd/vfs-wrap.o smbd/statcache.o \
smbd/posix_acls.o lib/sysacls.o lib/server_mutex.o \ smbd/posix_acls.o lib/sysacls.o lib/server_mutex.o \
smbd/process.o smbd/service.o smbd/error.o \ smbd/process.o smbd/service.o smbd/error.o \
printing/printfsp.o \ printing/printfsp.o lib/sysquotas.o lib/sysquotas_linux.o \
lib/sysquotas.o smbd/change_trust_pw.o smbd/fake_file.o \ lib/sysquotas_xfs.o \
smbd/change_trust_pw.o smbd/fake_file.o \
smbd/quotas.o smbd/ntquotas.o lib/afs.o \ smbd/quotas.o smbd/ntquotas.o lib/afs.o \
$(MANGLE_OBJ) @VFS_STATIC@ $(MANGLE_OBJ) @VFS_STATIC@

View File

@ -3009,6 +3009,7 @@ samba_cv_TRY_QUOTAS=no
samba_cv_RUN_QUOTA_TESTS=auto samba_cv_RUN_QUOTA_TESTS=auto
samba_cv_WITH_SYS_QUOTAS=auto samba_cv_WITH_SYS_QUOTAS=auto
samba_cv_TRY_SYS_QUOTAS=no samba_cv_TRY_SYS_QUOTAS=no
samba_cv_SYSQUOTA_FOUND=no;
AC_MSG_CHECKING(whether to try disk-quotas support) AC_MSG_CHECKING(whether to try disk-quotas support)
AC_ARG_WITH(quotas, AC_ARG_WITH(quotas,
@ -3078,6 +3079,10 @@ AC_MSG_CHECKING(whether to try the lib/sysquotas.c interface on ${host_os})
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
samba_cv_TRY_SYS_QUOTAS=yes samba_cv_TRY_SYS_QUOTAS=yes
samba_cv_RUN_QUOTA_TESTS=yes samba_cv_RUN_QUOTA_TESTS=yes
samba_cv_SYSQUOTA_FOUND=yes
AC_DEFINE(HAVE_QUOTACTL_LINUX,1,[Whether Linux quota support is available])
AC_DEFINE(HAVE_LINUX_XFS_QUOTAS,1,[Whether Linux xfs quota support is available])
samba_cv_sysquotas_file="lib/sysquotas_linux.c"
;; ;;
*) *)
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
@ -3090,21 +3095,21 @@ fi
# only check for quota stuff if --with-quotas # only check for quota stuff if --with-quotas
if test x"$samba_cv_RUN_QUOTA_TESTS" != x"no"; then if test x"$samba_cv_RUN_QUOTA_TESTS" != x"no"; then
# some broken header files need this
AC_CHECK_HEADER(asm/types.h,[
AC_DEFINE(HAVE_ASM_TYPES_H,1,[check for <asm/types.h>])
AC_ADD_INCLUDE(<asm/types.h>)
])
# For quotas on Veritas VxFS filesystems # For quotas on Veritas VxFS filesystems
AC_CHECK_HEADERS(sys/fs/vx_quota.h) AC_CHECK_HEADERS(sys/fs/vx_quota.h)
# For sys/quota.h and linux/quota.h # For sys/quota.h and linux/quota.h
AC_CHECK_HEADERS(sys/quota.h) AC_CHECK_HEADERS(sys/quota.h)
AC_CHECK_HEADERS(asm/types.h linux/quota.h)
# For quotas on Linux XFS filesystems if test x"$samba_cv_found_xfs_header" = x"no"; then
AC_CHECK_HEADERS(linux/xqm.h linux/xfs_fs.h) # if we have xfs quota support <sys/quota.h> (IRIX) we should use it
AC_CHECK_HEADERS(xfs/libxfs.h xfs/xqm.h xfs/xfs_fs.h) AC_CACHE_CHECK([for XFS QUOTA in <sys/quota.h>],samba_cv_HAVE_SYS_QUOTA_XFS, [
# For linux > 2.5.56
AC_CHECK_HEADERS(linux/dqblk_xfs.h)
# if we have struct if_dqblk in <linux/quota.h> we should use it
AC_CACHE_CHECK([for struct if_dqblk in <linux/quota.h>],samba_cv_HAVE_STRUCT_IF_DQBLK, [
AC_TRY_COMPILE([ AC_TRY_COMPILE([
#include "confdefs.h" #include "confdefs.h"
#ifdef HAVE_SYS_TYPES_H #ifdef HAVE_SYS_TYPES_H
@ -3113,29 +3118,14 @@ AC_TRY_COMPILE([
#ifdef HAVE_ASM_TYPES_H #ifdef HAVE_ASM_TYPES_H
#include <asm/types.h> #include <asm/types.h>
#endif #endif
#include <linux/quota.h> #include <sys/quota.h>
],[struct if_dqblk D;], ],[int i = Q_XGETQUOTA;],
samba_cv_HAVE_STRUCT_IF_DQBLK=yes,samba_cv_HAVE_STRUCT_IF_DQBLK=no)]) samba_cv_HAVE_SYS_QUOTA_XFS=yes,samba_cv_HAVE_SYS_QUOTA_XFS=no)])
if test "$samba_cv_HAVE_STRUCT_IF_DQBLK"x = "yes"x; then if test "$samba_cv_HAVE_SYS_QUOTA_XFS"x = "yes"x; then
AC_DEFINE(HAVE_STRUCT_IF_DQBLK,1,[struct if_dqblk]) AC_DEFINE(HAVE_IRIX_XFS_QUOTAS,1,[Whether IRIX xfs quota support is available])
fi
fi fi
# if we have struct mem_dqblk in <linux/quota.h> we should use it
AC_CACHE_CHECK([for struct mem_dqblk in <linux/quota.h>],samba_cv_HAVE_STRUCT_MEM_DQBLK, [
AC_TRY_COMPILE([
#include "confdefs.h"
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_ASM_TYPES_H
#include <asm/types.h>
#endif
#include <linux/quota.h>
],[struct mem_dqblk D;],
samba_cv_HAVE_STRUCT_MEM_DQBLK=yes,samba_cv_HAVE_STRUCT_MEM_DQBLK=no)])
if test "$samba_cv_HAVE_STRUCT_MEM_DQBLK"x = "yes"x; then
AC_DEFINE(HAVE_STRUCT_MEM_DQBLK,1,[struct mem_dqblk])
fi
# if we have struct dqblk .dqb_fsoftlimit instead of .dqb_isoftlimit on IRIX # if we have struct dqblk .dqb_fsoftlimit instead of .dqb_isoftlimit on IRIX
AC_CACHE_CHECK([if struct dqblk has .dqb_fsoftlimit],samba_cv_HAVE_DQB_FSOFTLIMIT, [ AC_CACHE_CHECK([if struct dqblk has .dqb_fsoftlimit],samba_cv_HAVE_DQB_FSOFTLIMIT, [
@ -3154,7 +3144,6 @@ fi
################## ##################
# look for a working quota system # look for a working quota system
samba_cv_SYSQUOTA_FOUND=no;
if test x"$samba_cv_SYSQUOTA_FOUND" != x"yes"; then if test x"$samba_cv_SYSQUOTA_FOUND" != x"yes"; then
AC_CACHE_CHECK([for long quotactl(int cmd, char *special, qid_t id, caddr_t addr)],samba_cv_HAVE_QUOTACTL_4A,[ AC_CACHE_CHECK([for long quotactl(int cmd, char *special, qid_t id, caddr_t addr)],samba_cv_HAVE_QUOTACTL_4A,[
@ -3165,7 +3154,9 @@ AC_TRY_RUN_STRICT([
#include "${srcdir-.}/tests/sysquotas.c"],[$Werror_FLAGS],[$CPPFLAGS],[$LDFLAGS], #include "${srcdir-.}/tests/sysquotas.c"],[$Werror_FLAGS],[$CPPFLAGS],[$LDFLAGS],
samba_cv_HAVE_QUOTACTL_4A=yes,samba_cv_HAVE_QUOTACTL_4A=no,samba_cv_HAVE_QUOTACTL_4A=cross)]) samba_cv_HAVE_QUOTACTL_4A=yes,samba_cv_HAVE_QUOTACTL_4A=no,samba_cv_HAVE_QUOTACTL_4A=cross)])
if test x"$samba_cv_HAVE_QUOTACTL_4A" = x"yes"; then if test x"$samba_cv_HAVE_QUOTACTL_4A" = x"yes"; then
samba_cv_SYSQUOTA_FOUND=yes;AC_DEFINE(HAVE_QUOTACTL_4A,1,[Whether long quotactl(int cmd, char *special, qid_t id, caddr_t addr) is available]) samba_cv_SYSQUOTA_FOUND=yes;
AC_DEFINE(HAVE_QUOTACTL_4A,1,[Whether long quotactl(int cmd, char *special, qid_t id, caddr_t addr) is available])
samba_cv_sysquotas_file="lib/sysquotas_4A.c"
fi fi
fi fi
@ -3179,7 +3170,9 @@ AC_TRY_RUN_STRICT([
samba_cv_HAVE_QUOTACTL_4B=yes,samba_cv_HAVE_QUOTACTL_4B=no,samba_cv_HAVE_QUOTACTL_4B=cross)]) samba_cv_HAVE_QUOTACTL_4B=yes,samba_cv_HAVE_QUOTACTL_4B=no,samba_cv_HAVE_QUOTACTL_4B=cross)])
if test x"$samba_cv_HAVE_QUOTACTL_4B" = x"yes"; then if test x"$samba_cv_HAVE_QUOTACTL_4B" = x"yes"; then
echo "int quotactl(const char *path, int cmd, int id, char *addr) is not reworked for the new sys_quota api" echo "int quotactl(const char *path, int cmd, int id, char *addr) is not reworked for the new sys_quota api"
# samba_cv_SYSQUOTA_FOUND=yes;AC_DEFINE(HAVE_QUOTACTL_4B,1,[Whether int quotactl(const char *path, int cmd, int id, char *addr) is available]) samba_cv_SYSQUOTA_FOUND=yes;
AC_DEFINE(HAVE_QUOTACTL_4B,1,[Whether int quotactl(const char *path, int cmd, int id, char *addr) is available])
samba_cv_sysquotas_file="lib/sysquotas_4B.c"
fi fi
fi fi
@ -3193,7 +3186,9 @@ AC_TRY_RUN_STRICT([
samba_cv_HAVE_QUOTACTL_3=yes,samba_cv_HAVE_QUOTACTL_3=no,samba_cv_HAVE_QUOTACTL_3=cross)]) samba_cv_HAVE_QUOTACTL_3=yes,samba_cv_HAVE_QUOTACTL_3=no,samba_cv_HAVE_QUOTACTL_3=cross)])
if test x"$samba_cv_HAVE_QUOTACTL_3" = x"yes"; then if test x"$samba_cv_HAVE_QUOTACTL_3" = x"yes"; then
echo "CRAY int quotactl (char *spec, int request, char *arg) is NOT reworked for the sys_quota api" echo "CRAY int quotactl (char *spec, int request, char *arg) is NOT reworked for the sys_quota api"
# samba_cv_SYSQUOTA_FOUND=yes;AC_DEFINE(HAVE_QUOTACTL_3,1,[Whether CRAY int quotactl (char *spec, int request, char *arg); is available]) samba_cv_SYSQUOTA_FOUND=yes;
AC_DEFINE(HAVE_QUOTACTL_3,1,[Whether CRAY int quotactl (char *spec, int request, char *arg); is available])
samba_cv_sysquotas_file="lib/sysquotas_3.c"
fi fi
fi fi
@ -3235,6 +3230,7 @@ AC_TRY_COMPILE([
#define NO_PROTO_H 1 #define NO_PROTO_H 1
#define NO_CONFIG_H 1 #define NO_CONFIG_H 1
#define HAVE_SYS_QUOTAS 1 #define HAVE_SYS_QUOTAS 1
#include "${srcdir-.}/${samba_cv_sysquotas_file}"
#include "${srcdir-.}/lib/sysquotas.c" #include "${srcdir-.}/lib/sysquotas.c"
],[],samba_cv_SYSQUOTA_WORKS=yes,samba_cv_SYSQUOTA_WORKS=no) ],[],samba_cv_SYSQUOTA_WORKS=yes,samba_cv_SYSQUOTA_WORKS=no)
CPPFLAGS="$SAVE_CPPFLAGS" CPPFLAGS="$SAVE_CPPFLAGS"

View File

@ -23,150 +23,6 @@
#ifdef HAVE_SYS_QUOTAS #ifdef HAVE_SYS_QUOTAS
/* Sometimes we need this on linux for linux/quota.h */
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_ASM_TYPES_H
#include <asm/types.h>
#endif
/*
* This shouldn't be neccessary - it should be /usr/include/sys/quota.h
* Unfortunately, RH7.1 ships with a different quota system using struct mem_dqblk
* rather than the struct dqblk defined in /usr/include/sys/quota.h.
* This means we must include linux/quota.h to have a hope of working on
* RH7.1 systems. And it also means this breaks if the kernel is upgraded
* to a Linus 2.4.x (where x > the minor number shipped with RH7.1) until
* Linus synchronises with the AC patches. Sometimes I *hate* Linux :-). JRA.
*/
#ifdef HAVE_LINUX_QUOTA_H
#include <linux/quota.h>
#elif defined(HAVE_SYS_QUOTA_H)
#include <sys/quota.h>
#endif
#if defined(HAVE_STRUCT_IF_DQBLK)
# define SYS_DQBLK if_dqblk
# define dqb_curblocks dqb_curspace/bsize
#elif defined(HAVE_STRUCT_MEM_DQBLK)
# define SYS_DQBLK mem_dqblk
# define dqb_curblocks dqb_curspace/bsize
#else /* STRUCT_DQBLK */
# define SYS_DQBLK dqblk
#endif
#ifndef Q_SETQLIM
#define Q_SETQLIM Q_SETQUOTA
#endif
/*********************************************
check for XFS QUOTA MANAGER
*********************************************/
/* on linux */
#ifdef HAVE_LINUX_XQM_H
# include <linux/xqm.h>
# define HAVE_XFS_QUOTA
#else
# ifdef HAVE_XFS_XQM_H
# include <xfs/xqm.h>
# define HAVE_XFS_QUOTA
# else
# ifdef HAVE_LINUX_DQBLK_XFS_H
# include <linux/dqblk_xfs.h>
# define HAVE_XFS_QUOTA
# endif
# endif
#endif
/* on IRIX */
#ifdef Q_XGETQUOTA
# ifndef HAVE_XFS_QUOTA
# define HAVE_XFS_QUOTA
# ifndef Q_XQUOTAON
# define Q_XQUOTAON Q_QUOTAON
# endif /* Q_XQUOTAON */
# ifndef Q_XQUOTAOFF
# define Q_XQUOTAOFF Q_QUOTAOFF
# endif /* Q_XQUOTAOFF */
# ifndef Q_XGETQSTAT
# define Q_XGETQSTAT Q_GETQSTAT
# endif /* Q_XGETQSTAT */
# endif /* HAVE_XFS_QUOTA */
#endif /* Q_XGETQUOTA */
#ifdef HAVE_XFS_QUOTA
/* Linux has BBSIZE in <linux/xfs_fs.h>
* or <xfs/xfs_fs.h>
* IRIX has BBSIZE in <sys/param.h>
*/
#ifdef HAVE_LINUX_XFS_FS_H
#include <linux/xfs_fs.h>
#elif defined(HAVE_XFS_XFS_FS_H)
#include <xfs/xfs_fs.h>
#endif /* *_XFS_FS_H */
#ifndef BBSHIFT
#define BBSHIFT 9
#endif /* BBSHIFT */
#ifndef BBSIZE
#define BBSIZE (1<<BBSHIFT)
#endif /* BBSIZE */
#endif /* HAVE_XFS_QUOTA */
#ifdef LINUX
# ifndef QUOTABLOCK_SIZE
# define QUOTABLOCK_SIZE 1024
# endif
/* end LINUX */
#elif defined(IRIX6)
# ifndef QUOTABLOCK_SIZE
# define QUOTABLOCK_SIZE BBSIZE
# endif
/* end IRIX6 */
#else /* HPUP,... */
# ifndef QUOTABLOCK_SIZE
# define QUOTABLOCK_SIZE DEV_BSIZE
# endif
#endif /* HPUP,... */
#if !defined(QUOTAFILENAME) && defined(QFILENAME)
#define QUOTAFILENAME QFILENAME
#endif
#ifdef INITQFNAMES
#define USERQUOTAFILE_EXTENSION ".user"
#else
#define USERQUOTAFILE_EXTENSION ""
#endif
/* this check should be before the QCMD fake! */
#if defined(QCMD)&&defined(GRPQUOTA)
#define HAVE_GROUP_QUOTA
#endif
/* on some systems we have to fake this up ...*/
#ifndef QCMD
#define QCMD(cmd,type) (cmd)
#endif /* QCMD */
#ifdef HAVE_DQB_FSOFTLIMIT
#define dqb_isoftlimit dqb_fsoftlimit
#define dqb_ihardlimit dqb_fhardlimit
#define dqb_curinodes dqb_curfiles
#endif
/* maybe we can add a configure test for HAVE_CADDR_T,
* but it's not needed
*/
#ifdef HAVE_CADDR_T
#define CADDR_T caddr_t
#else /* CADDR_T */
#define CADDR_T void*
#endif /* CADDR_T */
#if defined(HAVE_MNTENT_H)&&defined(HAVE_SETMNTENT)&&defined(HAVE_GETMNTENT)&&defined(HAVE_ENDMNTENT) #if defined(HAVE_MNTENT_H)&&defined(HAVE_SETMNTENT)&&defined(HAVE_GETMNTENT)&&defined(HAVE_ENDMNTENT)
#include <mntent.h> #include <mntent.h>
#define HAVE_MNTENT 1 #define HAVE_MNTENT 1
@ -178,10 +34,6 @@
#endif /* HAVE_SYS_QUOTAS */ #endif /* HAVE_SYS_QUOTAS */
#ifndef QUOTABLOCK_SIZE
#define QUOTABLOCK_SIZE 1024
#endif
/************************************************** /**************************************************
Some stuff for the sys_quota api. Some stuff for the sys_quota api.
**************************************************/ **************************************************/
@ -217,4 +69,8 @@ typedef struct _SMB_DISK_QUOTA {
uint32 qflags; uint32 qflags;
} SMB_DISK_QUOTA; } SMB_DISK_QUOTA;
#ifndef QUOTABLOCK_SIZE
#define QUOTABLOCK_SIZE 1024
#endif
#endif /*_SYSQUOTAS_H */ #endif /*_SYSQUOTAS_H */

View File

@ -24,255 +24,6 @@
#ifdef HAVE_SYS_QUOTAS #ifdef HAVE_SYS_QUOTAS
#if defined(HAVE_QUOTACTL_4A) #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 */ /*#endif HAVE_QUOTACTL_4A */
#elif defined(HAVE_QUOTACTL_4B) #elif defined(HAVE_QUOTACTL_4B)
@ -287,30 +38,6 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
/* #endif HAVE_QUOTACTL_3 */ /* #endif HAVE_QUOTACTL_3 */
#else /* NO_QUOTACTL_USED */ #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 */ #endif /* NO_QUOTACTL_USED */
#ifdef HAVE_MNTENT #ifdef HAVE_MNTENT
@ -434,262 +161,6 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char
} }
#endif #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 Now the list of all filesystem specific quota systems we have found
**********************************************************************/ **********************************************************************/

View File

@ -50,33 +50,16 @@ BOOL disk_quotas_vxfs(const pstring name, char *path, SMB_BIG_UINT *bsize, SMB_B
#ifdef LINUX #ifdef LINUX
#include <sys/types.h> #include <sys/types.h>
#include <asm/types.h> #include <mntent.h>
/* /*
* This shouldn't be neccessary - it should be /usr/include/sys/quota.h * This shouldn't be neccessary - it should be /usr/include/sys/quota.h
* Unfortunately, RH7.1 ships with a different quota system using struct mem_dqblk * So we include all the files has *should* be in the system into a large,
* rather than the struct dqblk defined in /usr/include/sys/quota.h. * grungy samba_linux_quoatas.h Sometimes I *hate* Linux :-). JRA.
* This means we must include linux/quota.h to have a hope of working on
* RH7.1 systems. And it also means this breaks if the kernel is upgraded
* to a Linus 2.4.x (where x > the minor number shipped with RH7.1) until
* Linus synchronises with the AC patches. Sometimes I *hate* Linux :-). JRA.
*/ */
#include <linux/quota.h> #include "samba_linux_quota.h"
#ifdef HAVE_LINUX_XQM_H #include "samba_xfs_quota.h"
#include <linux/xqm.h>
#else
#ifdef HAVE_XFS_XQM_H
#include <xfs/xqm.h>
#define HAVE_LINUX_XQM_H
#endif
#endif
#include <mntent.h>
#include <linux/unistd.h>
#define LINUX_QUOTAS_2
typedef struct _LINUX_SMB_DISK_QUOTA { typedef struct _LINUX_SMB_DISK_QUOTA {
SMB_BIG_UINT bsize; SMB_BIG_UINT bsize;
@ -92,22 +75,20 @@ typedef struct _LINUX_SMB_DISK_QUOTA {
Abstract out the XFS Quota Manager quota get call. Abstract out the XFS Quota Manager quota get call.
****************************************************************************/ ****************************************************************************/
static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp) static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp)
{ {
int ret = -1;
#ifdef HAVE_LINUX_XQM_H
struct fs_disk_quota D; struct fs_disk_quota D;
int ret;
ZERO_STRUCT(D); ZERO_STRUCT(D);
ret = quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D); ret = quotactl(QCMD(Q_XGETQUOTA,XFS_USER_QUOTA), path, euser_id, (caddr_t)&D);
/* As XFS has group quotas, if getting the user quota fails, try getting the group instead. */ if (ret)
if (ret) { ret = quotactl(QCMD(Q_XGETQUOTA,XFS_GROUP_QUOTA), path, egrp_id, (caddr_t)&D);
ret = quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), path, getegid(), (caddr_t)&D);
if (ret) if (ret)
return ret; return ret;
}
dp->bsize = (SMB_BIG_UINT)512; dp->bsize = (SMB_BIG_UINT)512;
dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit; dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit;
@ -116,7 +97,7 @@ static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QU
dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit; dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit;
dp->curinodes = (SMB_BIG_UINT)D.d_icount; dp->curinodes = (SMB_BIG_UINT)D.d_icount;
dp->curblocks = (SMB_BIG_UINT)D.d_bcount; dp->curblocks = (SMB_BIG_UINT)D.d_bcount;
#endif
return ret; return ret;
} }
@ -124,48 +105,90 @@ static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QU
Abstract out the old and new Linux quota get calls. Abstract out the old and new Linux quota get calls.
****************************************************************************/ ****************************************************************************/
static int get_smb_linux_vfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp) static int get_smb_linux_v1_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp)
{ {
int ret = 0; struct v1_kern_dqblk D;
#ifdef LINUX_QUOTAS_1 int ret;
struct dqblk D;
ZERO_STRUCT(D); ZERO_STRUCT(D);
dp->bsize = (SMB_BIG_UINT)1024;
#else /* LINUX_QUOTAS_2 */ ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
struct mem_dqblk D;
ZERO_STRUCT(D); if (ret && errno != EDQUOT)
#ifndef QUOTABLOCK_SIZE ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D);
#define QUOTABLOCK_SIZE 1024
#endif if (ret && errno != EDQUOT)
return ret;
dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
#endif
ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
/* Linux can have group quotas, if getting the user quota fails, try getting the group instead. */
if (ret) {
ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), path, getegid(), (caddr_t)&D);
if (ret)
return ret;
}
dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit; dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit; dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit; dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit; dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes; dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
#ifdef LINUX_QUOTAS_1
dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks; dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks;
#else /* LINUX_QUOTAS_2 */
dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace)/ dp->bsize; return ret;
#endif }
static int get_smb_linux_v2_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp)
{
struct v2_kern_dqblk D;
int ret;
ZERO_STRUCT(D);
ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
if (ret && errno != EDQUOT)
ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D);
if (ret && errno != EDQUOT)
return ret;
dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
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_curspace) / dp->bsize;
return ret; return ret;
} }
/**************************************************************************** /****************************************************************************
try to get the disk space from disk quotas (LINUX version) Brand-new generic quota interface.
****************************************************************************/
static int get_smb_linux_gen_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp)
{
struct if_dqblk D;
int ret;
ZERO_STRUCT(D);
ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
if (ret && errno != EDQUOT)
ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D);
if (ret && errno != EDQUOT)
return ret;
dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
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_curspace) / dp->bsize;
return ret;
}
/****************************************************************************
Try to get the disk space from disk quotas (LINUX version).
****************************************************************************/ ****************************************************************************/
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
@ -178,9 +201,11 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB
SMB_DEV_T devno; SMB_DEV_T devno;
int found; int found;
uid_t euser_id; uid_t euser_id;
gid_t egrp_id;
euser_id = geteuid(); euser_id = geteuid();
egrp_id = getegid();
/* find the block device file */ /* find the block device file */
if ( sys_stat(path, &S) == -1 ) if ( sys_stat(path, &S) == -1 )
@ -208,10 +233,18 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB
save_re_uid(); save_re_uid();
set_effective_uid(0); set_effective_uid(0);
if (strcmp(mnt->mnt_type, "xfs") == 0)
r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, &D); if (strcmp(mnt->mnt_type, "xfs")==0) {
else r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, egrp_id, &D);
r=get_smb_linux_vfs_quota(mnt->mnt_fsname, euser_id, &D); } else {
r=get_smb_linux_gen_quota(mnt->mnt_fsname, euser_id, egrp_id, &D);
if (r == -1 && errno != EDQUOT) {
r=get_smb_linux_v2_quota(mnt->mnt_fsname, euser_id, egrp_id, &D);
if (r == -1 && errno != EDQUOT)
r=get_smb_linux_v1_quota(mnt->mnt_fsname, euser_id, egrp_id, &D);
}
}
restore_re_uid(); restore_re_uid();
/* Use softlimit to determine disk space, except when it has been exceeded */ /* Use softlimit to determine disk space, except when it has been exceeded */
@ -920,8 +953,8 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB
if ((sys_stat(path, &S)<0) || (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 1)<0)) if ((sys_stat(path, &S)<0) || (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 1)<0))
#else #else
if ((sys_stat(path, &S)<0) || (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 0)<0)) if ((sys_stat(path, &S)<0) || (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 0)<0))
#endif /* ifdef HPUX */
return (False); return (False);
#endif /* ifdef HPUX */
#endif /* !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__) */ #endif /* !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__) */