From: dhesi@cirrus.com (Rahul Dhesi)
Subject: Re: setting mailer userid
Organization: Cirrus Logic Inc.
Date: Fri, 9 Oct 1992 21:56:52 GMT


Robert L. Howard writes:
     I don't think that is what he was asking.  Read it again.

Neil Rickert writes:
     I DO think it was what he was asking.

I suppose I should clarify my real objectives.  Then I will tell you
what solutions I found.

Suppose you are doing MX forwarding for a domain xyz.COM.  Joe, the
person running xyz.COM, would like to be in full control of how you do
this forwarding on the MX host.  A good solution seems to be to define
a mailer (call it xyz_mailer), and invoke it for all mail arriving for
anybody@xyz.COM.  Give Joe a home directory on the MX host and put
xyz_mailer in his home directory.  The mailer might be defined thus:

	Mxyz_mailer, P=/home/joe/xyz_mailer, F=DFMrmnus,
		R=25/10, S=10, A=xyz_mailr $u

The IDA mailertable entry might be:

	xyz_mailer,localhost		xyz.COM

The only hitch is that the mailer will be invoked under a default
userid, usually daemon, which you probably don't want.  I was looking
for a way to guarantee that the mailer would be invoked as Joe's
userid.

Neil Rickert suggested the "deliver" package.  I tried it.  It does
have the capability that I need.  It is achieved in the following way:
For mail destined for xyz.COM, use "deliver" as a (nonlocal) mailer.
Define a system-wide delivery script that will examine the recipient
addresses, and cause mail that to be piped through a user-specific
program as needed.  The user-specific program can be made to execute as
the desired userid.

The catch is that the output of the system-wide deliver deliver script
is read line by line, and part of it is interpreted by /bin/sh.  Thus
shell metacharacters in a destination address won't be handled
correctly.  To avoid problems, "deliver" will block such a message from
being processed at all.  This seemed to be a potential problem to me.
Either "deliver" would not deliver the message, or, if I changed its
source code to allow delivery, a later /bin/sh would try to interpret
such characters.

So I found this alternate solution:

	Mxyz_mailer, P=/local/undoc/setuid, F=DFMSrmnus, 
		R=25/10, S=10, A=setuid joe /home/joe/xyz_mailer $u

This mailer executes a perl script called "setuid", which accepts a
username and a command plus arguments.  It invoked the command as the
specified user.  The mailer flag S is set, which causes the mailer to
be invoked as root.  This is simple, doesn't require setting up a
configuration tree for "deliver", doesn't do things very indirectly the
way "deliver" does, and doesn't have problems with shell globbing
characters.

Here is the program "setuid".

===== begin program "setuid" =====
#! /usr/bin/perl
# Invoke a specified program as specified user.
# TESTED ONLY BRIEFLY -- USE AT YOUR OWN RISK.
# This program should be invoked as root.  It should not itself
# be setuid anything.
$myname = "setuid";

$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb";

if (@ARGV < 2) {
   print "usage: $myname user command [ arg ] ...\n";
   exit (1);
}

# make sure we are root
if ($> != 0) {
   print STDERR "$myname: error: must be root; aborting\n";
   exit(1);
}

$user = shift;

(($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell) =
   getpwnam($user)) || do {
      print STDERR "$myname: error: $user: unknown user\n";
      exit(1);
   };
($<, $>) = ($uid, $uid);	# change to final uid
($(, $)) = ($gid, $gid);	# change to final gid

# make sure we are not root;  if so, security problem; just exit
if ($< == 0 || $> == 0) {
   print STDERR "$myname: security problem: aborting\n";
   exit(1);
}

# Note: metachars in argv[0] may cause trouble.
exec @ARGV;

print STDERR "$myname: exec failed: $!\n";
print STDERR "[@ARGV]\n";
exit(1);
===== end program "setuid" =====
-- 
Rahul Dhesi <dhesi@cirrus.com>
also: dhesi@rahul.net
Newsgroups: comp.mail.sendmail