diff options
Diffstat (limited to 'source/smbd/quotas.c')
-rw-r--r-- | source/smbd/quotas.c | 111 |
1 files changed, 55 insertions, 56 deletions
diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c index afabb1befdf..badc0562bc8 100644 --- a/source/smbd/quotas.c +++ b/source/smbd/quotas.c @@ -47,7 +47,6 @@ try to get the disk space from disk quotas (LINUX version) BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { - uid_t euser_id; int r; struct dqblk D; SMB_STRUCT_STAT S; @@ -55,6 +54,9 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U struct mntent *mnt; SMB_DEV_T devno; int found; + uid_t euser_id; + + euser_id = geteuid(); /* find the block device file */ @@ -81,10 +83,10 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U return(False); } - euser_id=geteuid(); - seteuid(0); + save_re_uid(); + set_effective_uid(0); r=quotactl(QCMD(Q_GETQUOTA,USRQUOTA), mnt->mnt_fsname, euser_id, (caddr_t)&D); - seteuid(euser_id); + restore_re_uid(); /* Use softlimit to determine disk space, except when it has been exceeded */ *bsize = 1024; @@ -212,11 +214,10 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U *dsize = request.qf_entry.user_q.f_use ; - if ( *dfree ) - *dfree -= *dsize ; - - if ( *dfree < 0 ) + if ( *dfree < *dsize ) *dfree = 0 ; + else + *dfree -= *dsize ; *bsize = 4096 ; /* Cray blocksize */ @@ -244,7 +245,7 @@ Quota code by Peter Urbanec (amiga@cse.unsw.edu.au). BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { - uid_t user_id, euser_id; + uid_t euser_id; int ret; struct dqblk D; #if defined(SUNOS5) @@ -261,6 +262,8 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U SMB_DEV_T devno ; static SMB_DEV_T devno_cached = 0 ; int found ; + + euser_id = geteuid(); if ( sys_stat(path,&sbuf) == -1 ) return(False) ; @@ -312,18 +315,14 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U return(False) ; } - euser_id = geteuid(); - user_id = getuid(); - - setuid(0); /* Solaris seems to want to give info only to super-user */ - seteuid(0); + save_re_uid(); + set_effective_uid(0); #if defined(SUNOS5) DEBUG(5,("disk_quotas: looking for quotas file \"%s\"\n", name)); if((file=sys_open(name, O_RDONLY,0))<0) { - setuid(user_id); /* Restore the original UID status */ - seteuid(euser_id); - return(False); + restore_re_uid(); + return(False); } command.op = Q_GETQUOTA; command.uid = euser_id; @@ -335,8 +334,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U ret = quotactl(Q_GETQUOTA, name, euser_id, &D); #endif - setuid(user_id); /* Restore the original uid status. */ - seteuid(euser_id); + restore_re_uid(); if (ret < 0) { DEBUG(5,("disk_quotas ioctl (Solaris) failed. Error = %s\n", strerror(errno) )); @@ -353,14 +351,13 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U if (D.dqb_bsoftlimit==0) return(False); *bsize = DEV_BSIZE; - *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; *dsize = D.dqb_bsoftlimit; - if(*dfree < 0) - { + if (D.dqb_curblocks > D.dqb_bsoftlimit) { *dfree = 0; *dsize = D.dqb_curblocks; - } + } else + *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; DEBUG(5,("disk_quotas for path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n", path,(double)*bsize,(double)*dfree,(double)*dsize)); @@ -378,21 +375,26 @@ try to get the disk space from disk quotas - OSF1 version BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { - uid_t user_id, euser_id; int r, save_errno; struct dqblk D; SMB_STRUCT_STAT S; + uid_t euser_id; + /* + * This code presumes that OSF1 will only + * give out quota info when the real uid + * matches the effective uid. JRA. + */ euser_id = geteuid(); - user_id = getuid(); + save_re_uid(); + if (set_re_uid() != 0) return False; - setreuid(euser_id, -1); r= quotactl(path,QCMD(Q_GETQUOTA, USRQUOTA),euser_id,(char *) &D); - if (r) + if (r) { save_errno = errno; + } - if (setreuid(user_id, -1) == -1) - DEBUG(5,("Unable to reset uid to %d\n", user_id)); + restore_re_uid(); *bsize = DEV_BSIZE; @@ -423,7 +425,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U return (True); } -#elif defined (SGI6) +#elif defined (IRIX6) /**************************************************************************** try to get the disk space from disk quotas (IRIX 6.2 version) ****************************************************************************/ @@ -469,7 +471,8 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U } euser_id=geteuid(); - seteuid(0); + save_re_uid(); + set_effective_uid(0); /* Use softlimit to determine disk space, except when it has been exceeded */ @@ -479,7 +482,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U { r=quotactl (Q_GETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &D); - seteuid(euser_id); /* Restore the original uid status. */ + restore_re_uid(); if (r==-1) return(False); @@ -510,7 +513,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U { r=quotactl (Q_XGETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &F); - seteuid(euser_id); /* Restore the original uid status. */ + restore_re_uid(); if (r==-1) return(False); @@ -539,8 +542,8 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U } else { - seteuid(euser_id); /* Restore the original uid status. */ - return(False); + restore_re_uid(); + return(False); } return (True); @@ -570,9 +573,9 @@ try to get the disk space from disk quotas - default version BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { - uid_t euser_id; int r; struct dqblk D; + uid_t euser_id; #if !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__) char dev_disk[256]; SMB_STRUCT_STAT S; @@ -584,36 +587,32 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U euser_id = geteuid(); #ifdef HPUX - { - uid_t user_id; - - /* for HPUX, real uid must be same as euid to execute quotactl for euid */ - user_id = getuid(); - setresuid(euser_id,-1,-1); - r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D); - if (setresuid(user_id,-1,-1)) - DEBUG(5,("Unable to reset uid to %d\n", user_id)); - } + /* for HPUX, real uid must be same as euid to execute quotactl for euid */ + save_re_uid(); + if (set_re_uid() != 0) return False; + + r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D); + + restore_re_uid(); #else #if defined(__FreeBSD__) || defined(__OpenBSD__) { /* FreeBSD patches from Marty Moll <martym@arbor.edu> */ - uid_t user_id; gid_t egrp_id; - /* Need to be root to get quotas in FreeBSD */ - user_id = getuid(); + save_re_uid(); + set_effective_uid(0); + egrp_id = getegid(); - setuid(0); - seteuid(0); r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D); /* As FreeBSD has group quotas, if getting the user quota fails, try getting the group instead. */ - if (r) - r= quotactl(path,QCMD(Q_GETQUOTA,GRPQUOTA),egrp_id,(char *) &D); - setuid(user_id); - seteuid(euser_id); + if (r) { + r= quotactl(path,QCMD(Q_GETQUOTA,GRPQUOTA),egrp_id,(char *) &D); + } + + restore_re_uid(); } #elif defined(AIX) /* AIX has both USER and GROUP quotas: @@ -622,7 +621,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U #else /* !__FreeBSD__ && !AIX && !__OpenBSD__ */ r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D); #endif /* !__FreeBSD__ && !AIX && !__OpenBSD__ */ -#endif /* HAVE_SETRES */ +#endif /* HPUX */ /* Use softlimit to determine disk space, except when it has been exceeded */ #if defined(__FreeBSD__) || defined(__OpenBSD__) |