From: dan@cedb.dpcsys.org (Dan Busarow)
Newsgroups: comp.unix.admin
Subject: Re: allowing users root access to specific commands
Summary: try this
Date: 25 Jul 92 18:59:52 GMT
Organization: DPC Systems, Monrovia, CA

In article <1992Jul24.130911.6009@dragon.acadiau.ca>, alan@dragon.acadiau.ca (Alan McKay) writes:
> Does anyone know of a way I can give root access to specific users for
> specific commands?  A while ago I pulled a program from the net which
> did this, but I seem to have lost the program before installing it.
> 

I got this from Unix World a few years ago and modified it slightly
to add access lists to restrict it in the manner you describe.

The use of this program is controlled by two files, /etc/.priv.list
which is a list of authorized users and /usr/lib/priv/login_name
which is a list of the commands login_name is allowed to run as root.
If the second file does not exist then the user has UNLIMITED access
which was the original behaviour of the program (priv sh will give you
a root shell).  Also, if you remove the define for NEWPATH you are 
leaving your system wide open to trojan horses with the name of an 
authorized program.

This was also posted in biz.sco.general a few days ago in response to
a different request, my apologies if you get both groups.

Dan
------------------- priv.c -----------------------------------
/*
 * priv  Run a command as superuser
 * by Ron Kuris, December 1988
 */
/* 
    access list added by Dan Busarow, DPC Systems, 11/22/91
 
    files: /etc/.priv.list 
                a list of authorized user login names, one per line
                should be mode 400
              
           /usr/lib/priv/login_name 
                a list of authorized commands, one per line
                this should also be 400
              
    priv should be mode 4111, owned by root
*/

#include <stdio.h>
#include <pwd.h>

#define PRIVLIST "/etc/.priv.list"
#define ACCESSDIR "/usr/lib/priv/"
#define LONGESTNAME 64
#define ERREXIT 1
/* If NEWPATH isn't defined, then PATH is taken from calling program */
#define NEWPATH "PATH=/bin:/etc:/usr/bin"

extern unsigned short getuid();
extern char *malloc();

main(argc,argv,envp)
char **argv, **envp;
int argc;
{
    struct passwd *getpwuid(), *pw;
    extern void exit();
    FILE *fp;
    char aList[64], buffer[LONGESTNAME+1], *lname, *prog;
    short i, j, ok;

    prog = argv[0]; /* store program name */
    if (argc < 2) 
    {   /***
        (void)fprintf(stderr,"Usage: %s command args\n", prog);
        no error messages, this program is not intended for use
        by the general public, authorized users will know how to
        run it
        ***/
        exit(ERREXIT);
    }
    pw = getpwuid((int)getuid());
    lname = pw->pw_name;
    if ((fp = fopen(PRIVLIST, "r")) == NULL) 
    {   (void)fprintf(stderr, "Can't open database\n");
        exit(ERREXIT);
    }
    while (fgets(buffer, LONGESTNAME, fp) != NULL) 
    {   buffer[strlen(buffer)-1] = '\0'; /* zap newline */
        if (!strcmp(lname, buffer)) 
        {   (void)fclose(fp);
            ok = 0;
            strcpy(aList,ACCESSDIR);
            strcat(aList,lname);
            if ((fp = fopen(aList, "r")) == NULL)/* default, no restriction */
                ok = 1;  /* this user is now root so you better trust them! */
            else
            {   while(fgets(buffer,LONGESTNAME,fp) != NULL)
                {   buffer[strlen(buffer)-1] = 0;
                    if(!strcmp(buffer,argv[1]))
                    {   ok = 1;
                        break;
                    }
                }
            }
            if(!ok)             /* failed access list test */
                break;
#ifndef NEWPATH
            if (getenv("PATH") == NULL) 
            {   (void)fprintf(stderr,"%s: No path.\n", prog);
                exit(ERREXIT);
            }
#else
            for (i=0; envp[i]; i++) 
            {   if (!strncmp("PATH=", envp[i], 5)) 
                {   envp[i] = NEWPATH;
                    break;
                }
            }
            if (!envp[i])               /* no PATH, add it to environ */ 
            {   extern char **environ;
                char **newenv = (char **)malloc((i+2)*sizeof(char *));
                for (j = 0; j < i; j++)
                    newenv[j] = envp[j];
                newenv[j] = NEWPATH;
                newenv[j+1] = NULL;
                environ = newenv;
            }
#endif
            (void)setuid(0);
            (void)setgid(0);
            (void)execvp(argv[1], argv+1);
            (void)fprintf(stderr,"%s: can't execute %s\n",prog,argv[1]);
            exit(ERREXIT);
        }
    }
    /* failed authorization test */
    /* originally there was an error message here saying that the
       user is not authorized to run priv.  I removed it on the
       assumption that a program which seems to do nothing is a lot
       less likely to get hacked on than one which tells you that you
       are not authorized to run it.
    */
    (void)fclose(fp);
    exit(ERREXIT);
    /* NOTREACHED */
}

---------------- end priv.c ------------------------------------
-- 
+                                                                            -
   Dan Busarow             dan@cedb.dpcsys.org              uunet!cedb!dan
   DPC SYSTEMS                Monrovia, CA                  (818) 305-5733
-                                                                            +
Newsgroups: comp.unix.admin