first pass at updating head branch to be to be the same as the SAMBA_2_0 branch
[kai/samba-autobuild/.git] / source3 / smbd / quotas.c
index afabb1befdf3d6ccb70c4079ea4bbe22a9ace762..badc0562bc8dd052e511a70144ddbbdad43d8d54 100644 (file)
@@ -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__)