[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: SUID scripts?



Mike \"Ford\" Ditto wrote:
> 
> Here is an implementation of "secure" set-ID #! files (A.K.A. set-uid
> shell scripts) for Linux 2.0.x.

[ Long kernel hack with unknown security implications and a need to
  be redone for every new kernel version elided... ]

Instead of that it is much simpler to have a compiled "wrapper"
program which can call your shell script, avoiding various race
conditions, and execute it under id you want.  This is, for example,
what I use to run various font making scripts for TeX, under
a special id 'tex' and not 'root', on machines when I do not want
to leave all TeX directory trees world writable.  It can be easily
adapted for these few situations when you **really** want to run
a shell script under some other id.

It is called under a desired name and executes "namesake" not
in your PATH.

   Michal

/****************************************************/
/*                                                  */
/*  Executable wrapper for MakeTeX... programs.     */
/*  Calls its namesake from TOOLS directory.        */
/*  Provide links with different names to make it   */
/*  multipurpose.                                   */
/*                                                  */
/*  Michal Jaegermann, Feb 11 1995                  */
/*                                                  */
/****************************************************/

#include <unistd.h>
#include <string.h>
#include <stdlib.h>

/* Where are real scripts located */
#define TOOLS "/usr/lib/texmf/bin/i686-linux/"
#define ASIZE  120

/*
 * This is a list of names under which we are willing
 * to execute. It has be NULL terminated.
 */
const char *accepted[] = {
    "MakeTeXPK",
    "MakeTeXTFM",
    "MakeTeXMF",
    "MakeTeXmkdir",
    NULL
};

int
main(int argc, char **argv)
{
    char doer[ASIZE] = TOOLS;
    int idx = 0;
    /*
     * If your compiler is broken and the construction below
     * does not work then "tail = strchr(doer, '\0');", or
     * equivalent, will serve as well.
     */
    char *tail = doer + (sizeof(TOOLS) - 1);
    char *start;

    /* find our base name */
    start = (start = strrchr(argv[0], '/')) ?
                               (start + 1) : argv[0];
    /* check if we are on the list */
    while (1) {
	if (NULL == accepted[idx])
	    exit(1);          /* not on the list - bye-bye */
	if (0 == strcmp(accepted[idx], start))
	    break;            /* this is ours */
	idx += 1;
    }
    /*
     * Set pretty bland, but hopefuly secure environment;
     * we intend to run this program 'suid'.
     */
    setenv("PATH", "/usr/local/bin:/bin:/usr/bin", 1);
    setenv("IFS", " ", 1);
    /*
     * You may want/need some other calls to setenv().
     * For example, if your system has an environment
     * variable pointing to shared libraries it should
     * be set here.
     */

    /*
     * Attach our name at the end of a directory string.
     * This assumes that real scripts in TOOLS directory
     * will be called by their own names (but indirectly)
     */
    strncpy(tail, start, sizeof("MakeTeXmkdir" + 1));
    setuid(geteuid());		/* we want priviledges of
				   an owner of this program */
    return execv(doer, argv);   /* do it and tell results   */
}

/*
 * Local variables:
 * compile-command: "gcc -s -O6 -fomit-frame-pointer -m486 -Wall -pipe -o ../MakeTeXPK maketex.c"
 * End:
 */




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index] []