****************************************************************************
*                                                                          *
*                                 runsuid                                  *
*                                                                          *
*              Poor man's set-uid / set-gid script invocation              *
*                                                                          *
****************************************************************************


1) What is runsuid?
====================

runsuid will run a script with another effective user-id / group-id.
The same effect can be accomplished for programs by setting according s-bits
on the program, but this approach is either inherently insecure or impossible
fpor scripts with most kernels.

It is not very flexible, either.

sudo on the other hand allows one to run programs with another user-id, and it
can be configured in a very flexible way. On the other hand, it does not allow
to change the user-id / group-id to non-root ids only.

There is always the same argument going on, that suid scripts and binaries are
bad anyway, but used in the right combination with access restriction they can
ease the live of administrators a lot.  It may be interesting for Web servers
as well, because that way cgi-scripts can be run as different, fixed, users.

runsuid will enable a script to be run, only if the current user is allowed to
do so according to a configuration file.

NOTE: Most times, it is a *bad* idea to let standard users run any program
with root privileges.  Especially scripts tend to be notorious security
problems.  The user may be able to read files which were not intended to be
public readable, the user may even alter files by bugs in the scripts, the
user might be able to invoke arbitrary commands by specifying arguments that
contain shell escape sequences!

But many security problems are not really severe (and are more of a kind of
'stupidity' problems ;) and can be overcome, especially if one does not use
setuid, but setgid scripts.  Still, you have to be aware that a missconfigured
runsuid can be a severe security problem.


2) Installing
=============

Because of its simplicity, runsuid does not have a autoconf script.
Just invoke 'make install' as root (runsuid needs root s-bit - wonder why?).

runsuid compiles fine on Linux, FreeBSD (4.3), Solaris, IRIX, and hpux.
May be on other systems as well.

On hpux, you may have to specify _INCLUDE_POSIX_SOURCE=1 in order to compile
it with 'cc' due to broken headers.


3) Configuration
================

runsuid is configured by one configuration file, /etc/runsuid.rc
The configuration file is checked to be read only for non-root persons on
startup.

Each line of the configuration file is either a comment (beginning with '#'),
an empty line, or contains three main entries and a list of additional
options.  The main entries are:
 - the exact path to the command / script
   (may contain '*' wildcards, which match *exactly* one level)
 - the permitted user:group
 - the effective user:group for this permission pair.
User and group are separated by a colon.  An empty part in the permitted
user:group field specifies that any user/group matches.  An empty part in the
effective user:group field specifies, that the user/group is not changed upon
invocation.  The first matching configuration line is used.

Additional options are:
  <var>="<value>"    set environment variable for executed script
  <var>=+            keep environment variable from calling environment
  <var>=-            remove variable from execution environment
  LOCALE             inherit locale from calling environment

Only HOME, LOGNAME, and TERM are inherited from the calling environment
by default.

USER is set to the name of the effective user.
REAL_USER is set to the name of the calling user.
PATH is set to /usr/sbin:/usr/bin:/sbin:/bin.
SHELL is set to /bin/sh.
LANG is set to C, if option LOCALE is not present.
All these settings can be overwritten by the configuration line options.

LANG and LC_* are not inherited from the calling environment by default due
to locale specific bugs in many scripts. 

When the configuration file does not state that the user is allowed to
run the script, an error message is printed.


An example configuration can be found in runsuid.rc.example


4) Invocation
=============

In order to run a script setuid / setgid, insert the runsuid path in the
interpreter invocation line:

#!/usr/sbin/runsuid /bin/sh
# This script is run with gid 200 according to /etc/runsuid.rc...

The access rights of the script are checked with access(), so only scripts are
invoked, that can be read and executed by the user anyway.  The first line of
the script to be run is read before execution to check whether the interpreter
has been given to runsuid correctly.

Note that the supplementary group list is never changed by runsuid! You might
consider this a security risk under extreme circumstances.

The environment is cleared before the interpreter is exec'ed.  When the script
is running it can check the environment variable REAL_USER to get the login
name of the invoking user.  See Section 3 for details.


5) ToDo
=======

- We could think about splitting the argument ('/bin/sh' in the most cases)
  into interpreter name and arguments at space boundaries.  However, this
  rises a whole lot of additional security problems.  Until they are discussed
  in detail, the safe approach is to just not allow in-script shell arguments.
  If you absolutely need this feature, create a wrapper script using /bin/sh.
- No Changelog so far. However, we have a 'History' section now.


6) Licensing
============

runsuid is distributed under the GNU General Public License - see the
accompanying Copyright file for more details.


7) Contributions
================

runsuid is developed by

   - Matthias Hopf <mat@mshopf.de>

Additionally, security has been checked by

   - Marcelo Magallon <Marcelo.Magallon@informatik.uni-stuttgart.de>

Please do not hesitate to contact me at <runsuid@mshopf.de>,
especially regarding security problems and information.


8) History
==========

- V 1.5
  Fixed stupid options parsing bug and a memory leak. No security implications.
  Spelling corrections.

- V 1.4
  Added LOCALE option.
  Spelling corrections + reformating README.

- V 1.3
  Environment is now cleared.
  Added option support for configuration.

- V 1.2
  Errors are now more verbose.
  Added more debug output if DEBUG is set on compile time.
  Added another workaround for somewhat broken OSes (e.g. hpux).

- V 1.1
  First public release.

