SUMMARY: Safe use of setquota.c program

From: Paul N. Youngblood <youngbp_at_email.uah.edu>
Date: Tue, 01 Sep 1998 11:11:41 -0500 (CDT)

Hello Admins,

Thanks VERY MUCH to the following for their rapid responses:

Richard L Jackson Jr <rjackson_at_gmu.edu>
Bob Jones <BJ_at_OREGON.UOREGON.EDU>

Both suggested sudo which is the solution I will use:
 ftp://ftp.courtesan.com/pub/sudo/
 http://www.courtesan.com/sudo/

Additionally, Richard Jackson included (thank you, Richard!)
detailed notes on installation, etc. which I have included below.
My original post is at the very end.

Paul Youngblood

--------Notes from Richard Jackson------------------------------------

- install sudo 1.5.4
Used to eliminate the need for sysop to use the root password and reduce
the need to know both root and sysop passwords. Ftp'ed from
ftp.cs.colorado.edu:/pub/sysadmin/sudo/cu-sudo.v1.5.4.tar.Z
. cd /sys1/src/sudo_1.5.4
. rm config.cache
. ./configure --with-C2 --with-CC=/usr/bin/cc --sbindir=/usr/local/system
. make >& make.log &
. make install >& make.install &(strip is done automatically)
. make clean
. /usr/local/system/visudo (ok, setup /etc/sudoers)
IMPORTANT FILES:
 /etc/sudoers
 /usr/local/system/visudo
 /usr/local/bin/sudo
IMPORTANT NOTE:
Must add Host_Alias if it does not exist in /etc/sudoers. If not, then sudo
will not work. I had to fix portal, nina, pinta, maria.
NOTES:
----------------------
The latest verion of sudo is 1.5.4
The "authoratative" sudo ftp site is ftp://ftp.courtesan.com/pub/sudo/
and there is a web page at http://www.courtesan.com/sudo/

-----------------------------------------------------------------------
---------Original Post-------------------------------------------------

>From youngbp_at_email.uah.edu Tue Sep 1 10:56:52 1998
Date: Mon, 31 Aug 1998 15:44:17 -0500 (CDT)
From: "Paul N. Youngblood" <youngbp_at_email.uah.edu>
To: alpha-osf-managers_at_ornl.gov
Subject: Safe use of setquota.c program
Followup-To: poster

Hello Admins,

I need suggestions on best (secure) ways to arrange for a
non-privileged user to use Richard Jackson's c program setquota.
I got this program from this list's archives. The only way I've
made it work so far is to make it suid root. Thanks for taking
the time to help. I'll summarize. The c program follows.

Paul Youngblood
Univ of Alabama in Huntsville
Email: youngbp_at_uah.edu

/**********************************************************************/
/* */
/* NAME: setquota.c */
/* */
/* PROGRAMMER: Richard Jackson DATE: 950328 */
/* */
/* PURPOSE: Set the quota for a specified user on a specified */
/* filesystem. */
/* */
/* NOTES: */
/* To execute: */
/* 1. setquota username softlimit hardlimit filesystem */
/* for example, */
/* ./setquota jblow 2000 2500 /var/spool/mail */
/* */
/* To build under OSF/1 3.x: */
/* 1. cc -o setquota setquota.c */
/* 2. strip setquota */
/* */
/* Only root or authorized users can successfully run this program. */
/* Authorized users are anybody in group adm */
/* */
/* */
/* MODIFICATION HISTORY: */
/* DATE MOD NAME DESCRIPTION */
/* */
/* 950328 AAA rjackson initial version */
/* 960214 Nick Hill Changed name to setquota and add tests */
/* for authorized non root users to set */
/* quotas */
/* */
/**********************************************************************/

#include <stdio.h> /* printf() */
#include <pwd.h> /* getpwnam() */
#include <stdlib.h> /* atoi(), exit() */
#include <sys/types.h>
#include <ufs/quota.h> /* quotactl() */
#include <sys/mount.h> /* statfs() */
#include <errno.h> /* perror() */
#include <unistd.h> /* geteuid() */
#include <grp.h> /* getgrnam(), endgrent() */
#include <string.h> /* strcpy(), strcmp() */

main (int argc, char *argv[])
{
  struct dqblk dqblk_st; /* disk quota structure */
  struct passwd *pw; /* passwd file entry structure */
  u_int softlimit; /* quota soft limit */
  u_int hardlimit; /* quota hard limit */
  struct statfs statfs_st; /* mounted filesystem info */
  uid_t uid; /* user id */
  char user_running[31]; /* username running the program*/
  char progname[31]; /* program name */
  struct group *gstruct; /* group entry structure */
  int authorize=0; /* allow user to do it? 0=no, 1=yes */
  char *ptr, buffer[255];
  char **ptr2;
  
 strcpy(buffer,argv[0]);
 ptr=strrchr(buffer,'/');
 if (ptr==NULL)
   {strncpy(progname,buffer,30);
    progname[30] = '\0';
   }
 else
   {strncpy(progname,++ptr,30);
    progname[30]='\0';
   }

/*
 * make sure we have the required arguments
 */
  if (argc != 5)
  {
    fprintf(stderr, "Usage: %s username softlimit hardlimit filesystem\n",progname);
    fprintf(stderr, " :\n");
    fprintf(stderr, " : soft and hard limits are in units of 1024 as reported\n");
    fprintf(stderr, " : by other Advfs utilities. Eg 204800 is 200Mb\n");
    exit(1);
  }

/*
 * this program requires root privs
 */
  if ( geteuid() != (uid_t) 0)
  {
    fprintf(stderr, "%s: you do not have authorization to use %s\n", progname,progname);
    exit(1);
  }

/*
 * determine who is running me
 */
 
    uid = getuid();
    if ((pw = getpwuid(uid)) == (struct passwd *) NULL)
      {
       fprintf(stderr, "%s: can't find passwd entry for uid %d\n", progname, uid);
       exit(1);
      }
   
    strcpy(user_running,pw->pw_name);
/*
 * check user running against membership of group adm
 */
 
  if ((gstruct= getgrnam("adm")) == NULL )
    {fprintf(stderr,"%s: failed to get group entry for authentication\n",progname);
     exit(1);
    }

  ptr2=gstruct->gr_mem;
  while (ptr2[0] != NULL)
    {if (!strcmp(user_running,ptr2[0]))
       {authorize=1;
        break;
       }
     ptr2++;
    }
  endgrent();
  
  if ((authorize == 0) && strcmp(user_running,"root"))
    {fprintf(stderr,"%s: User %s not authorized to use %s\n",progname,user_running,progname);
     exit(1);
    }
  
/*
 * does this user exist in the /etc/passwd file?
 */
  if ((pw = getpwnam(argv[1])) == (struct passwd *) NULL)
  {
    fprintf(stderr, "%s: can't find passwd entry for %s\n", argv[0], argv[1]);
    exit(1);
  }

/*
 * check if quota's are valid for the specified filesystem
 */
  if (statfs(argv[4], &statfs_st, sizeof(struct statfs)))
  {
    fprintf(stderr, "%s: statfs() failed, errno=%d\n", argv[0], errno);
    exit(1);
  }

/*
 * Filesystem should manage quotas or be AdvFS (i.e., AdvFS always
 * manages quotas). M_QUOTA appears to not be set for AdvFS.
 */
  if (!((statfs_st.f_flags & M_QUOTA) || (statfs_st.f_type == MOUNT_MSFS)))
  {
    fprintf(stderr, "%s: quota is not enabled for %s filesystem\n",
         argv[0], argv[4]);
    exit(1);
  }

/*
 * fetch current values
 */
  if (quotactl(argv[4], QCMD(Q_GETQUOTA, USRQUOTA), pw->pw_uid, &dqblk_st))
  {
    fprintf(stderr, "%s: quotactl() GETQUOTA failed, errno=%d\n",
         argv[0], errno);
    exit(1);
  }
  
  fprintf(stdout,"\n%s : Setting quotas for user %s\n",progname, pw->pw_name);
  fprintf(stdout,"%s : Old softlimit in %s is %d\n",progname,argv[4],dqblk_st.dqb_bsoftlimit/2);
  fprintf(stdout,"%s : Old hardlimit in %s is %d\n",progname,argv[4],dqblk_st.dqb_bhardlimit/2);
  

  if((atoi(argv[2]) < 0) || (atoi(argv[3]) < 0))
    {fprintf(stderr,"%s : invalid negative value given for new soft or hard limit\n",progname);
     exit(1);
    }
    
    
  softlimit = atoi(argv[2]);
  hardlimit = atoi(argv[3]);
/*
 * disk blocks (512 bytes each) times 2. vquota reports number of 1024
 * byte blocks.
 */
  dqblk_st.dqb_bsoftlimit = softlimit * 2;
  dqblk_st.dqb_bhardlimit = hardlimit * 2;
  
  fprintf(stdout,"%s : New softlimit in %s is %d\n",progname,argv[4],dqblk_st.dqb_bsoftlimit/2);
  fprintf(stdout,"%s : New hardlimit in %s is %d\n\n",progname,argv[4],dqblk_st.dqb_bhardlimit/2);


/*
 * set new quotas
 */
  if (quotactl(argv[4], QCMD(Q_SETQUOTA, USRQUOTA), pw->pw_uid, &dqblk_st))
  {
    fprintf(stderr, "%s: quotactl() SETQUOTA failed, errno=%d\n",
         argv[0], errno);
    exit(1);
  }

  exit(0);

}
Received on Tue Sep 01 1998 - 16:10:16 NZST

This archive was generated by hypermail 2.4.0 : Wed Nov 08 2023 - 11:53:38 NZDT