I use samba on redhat linux (7.1)
For default in redhat each user has also his own group.

I created a new group for each samba share that I defined so I can control which users can access to the shares, but if I use the user quota I can't control the quota on this shares.
Using a group quota I can assign separate quota to each share (the shares are on the same HD partition):
- each user has a quota on the home share
- each "not home" share has its own quota


The only problem is that I can't see the quota in windows box. So I modified the smbd/quotas.c to read the quota group associated to the group of the file/directory if the user quota result is 0 (zero). I added a parameter to the function get_smb_linux_* to get an user or a group quota.

I attach the output of the commnad:
diff -u -r samba-2.2.7a/source/smbd/quotas.c samba-2.2.7amds/source/smbd/quotas.c



--- samba-2.2.7a/source/smbd/quotas.c Wed Dec 11 10:17:40 2002 +++ samba-2.2.7amds/source/smbd/quotas.c Tue Mar 4 09:43:05 2003 @@ -66,13 +66,18 @@ 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, LINUX_SMB_DISK_QUOTA *dp, char type )
{
int ret = -1;
struct fs_disk_quota D;
ZERO_STRUCT(D);


- if ((ret = quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D)))
+ if ( type == 'g' ) {
+ ret = quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), path, euser_id, (caddr_t)&D);
+ } else {
+ ret = quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
+ }
+ if (ret)
return ret;


        dp->bsize = (SMB_BIG_UINT)512;
@@ -89,7 +94,7 @@
  Abstract out the old and new Linux quota get calls.
 ****************************************************************************/

-static int get_smb_linux_v1_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, LINUX_SMB_DISK_QUOTA *dp, char type )
{
struct v1_kern_dqblk D;
int ret;
@@ -97,7 +102,12 @@
ZERO_STRUCT(D);
dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;


- if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D)))
+ if ( type == 'g' ) {
+ ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), path, euser_id, (caddr_t)&D);
+ } else {
+ ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
+ }
+ if (ret)
return -1;


        dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
@@ -110,7 +120,7 @@
        return 0;
 }

-static int get_smb_linux_v2_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
+static int get_smb_linux_v2_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp, char type )
{
struct v2_kern_dqblk D;
int ret;
@@ -118,7 +128,12 @@
ZERO_STRUCT(D);
dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;


- if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D)))
+ if ( type == 'g' ) {
+ ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), path, euser_id, (caddr_t)&D);
+ } else {
+ ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
+ }
+ if (ret)
return -1;


        dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
@@ -135,7 +150,7 @@
  Brand-new generic quota interface.
 ****************************************************************************/

-static int get_smb_linux_gen_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
+static int get_smb_linux_gen_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp, char type )
{
struct if_dqblk D;
int ret;
@@ -143,7 +158,12 @@
ZERO_STRUCT(D);
dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;


- if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D)))
+ if ( type == 'g' ) {
+ ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), path, euser_id, (caddr_t)&D);
+ } else {
+ ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
+ }
+ if (ret)
return -1;


        dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
@@ -170,6 +190,7 @@
        SMB_DEV_T devno;
        int found;
        uid_t euser_id;
+       gid_t fgrp_id;

euser_id = geteuid();

@@ -179,6 +200,7 @@
                return(False) ;

        devno = S.st_dev ;
+       fgrp_id = S.st_gid;

        fp = setmntent(MOUNTED,"r");
        found = False ;
@@ -202,15 +224,31 @@
        set_effective_uid(0);

if (strcmp(mnt->mnt_type, "xfs")) {
- r=get_smb_linux_gen_quota(mnt->mnt_fsname, euser_id, &D);
+ r=get_smb_linux_gen_quota(mnt->mnt_fsname, euser_id, &D, 'u');
if (r == -1) {
- r=get_smb_linux_v2_quota(mnt->mnt_fsname, euser_id, &D);
+ r=get_smb_linux_v2_quota(mnt->mnt_fsname, euser_id, &D, 'u');
if (r == -1)
- r=get_smb_linux_v1_quota(mnt->mnt_fsname, euser_id, &D);
+ r=get_smb_linux_v1_quota(mnt->mnt_fsname, euser_id, &D, 'u');
}
} else {
- r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, &D);
+ r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, &D, 'u');
}
+
+ /* Massimo Del Sarto delsarto at inpe.unipi.it */
+ /* if no limits try with quota group ad gid of the dir */
+ if (r != -1)
+ if ( (D.softlimit == 0) && (D.hardlimit == 0) ) {
+ if (strcmp(mnt->mnt_type, "xfs")) {
+ r=get_smb_linux_gen_quota(mnt->mnt_fsname, fgrp_id, &D, 'g');
+ if (r == -1) {
+ r=get_smb_linux_v2_quota(mnt->mnt_fsname, fgrp_id, &D, 'g');
+ if (r == -1)
+ r=get_smb_linux_v1_quota(mnt->mnt_fsname, fgrp_id, &D, 'g');
+ }
+ } else {
+ r=get_smb_linux_xfs_quota(mnt->mnt_fsname, fgrp_id, &D, 'g');
+ }
+ }


restore_re_uid();





Reply via email to