Hello!  I know this is probably more appropriate in a Cyrus
mailing list, but I wrote this so qmail users can deliver
to their own mailbox in a secure fashion.

The script is explained in the comments.  Please review
it and let me know of any security holes that may be present
as well as ways to fix it.  It *should* be tight because
there is absolutely no user input anywhere.

If this script is satisfactory, copy it to

$CYRUS_BASE_DIR/bin/deliverwrapper.pl

Then execute, as root --
# chown cyrus.mail $CYRUS_BASE_DIR/bin/deliverwrapper.pl
# chmod 6751 $CYRUS_BASE_DIR/bin/deliverwrapper.pl 

and leave deliver mode 750 (as installed).

Now, any user can call the wrapper and deliver mail
to their own mailbox and no others.

If you wish to add any parameters, they may be added
to the $deliver_args variable.  Oh, I also assume
usernames only contain A-Z, a-z, 0-9, and "-.".  If you
have any other names, then you'll have to add them
yourself  and please let me know what you added so
I can do the same.


Again, please let me know of any shortcomings, bugs,
holes, praises, wtf's, etc.  :)


Thanks,

~Patrick



#!/usr/bin/perl

# Wrapper for securely (hopefully ;) calling Cyrus IMAPd's deliver program
# from any user.  This program accepts no arguments and will only deliver
# to the mailbox of the user using only the command line parameters supplied
# by this script.
#
# There is no user input except stdin, which is presumably a message.  If
# it's not a message, then it only munges their own mailbox.  (Actually,
# deliver will complain about invalid headers.)
#
# Calls deliver with -e -a $USER -- $USER
#

$deliver_exe = "/usr/local/cyrus/bin/deliver";
$deliver_args = "-e -a ";  # We tack on "$USER -- $USER" later.
$id_exe = "/usr/bin/id";
$username_chars = "-A-Za-z0-9.";

# Needed for security reasons
$ENV{'PATH'} = "";
$ENV{'BASH_ENV'} = "";

# We need to get the caller's UID
# There is probably a better way of doing this.
$id = `$id_exe`;

# Strip out the user's name and uid.
if( $id =~ /uid=([0-9]+)\(([$username_chars]+)\).*/) {
   $uid = $1;
   $user = $2;

   # Deliver the message
   $deliver_args .= "$user -- $user";
   open(DELIVER, "|$deliver_exe $deliver_args") || die "Can't open
deliver!";
   print DELIVER <STDIN>;
}  else {
   die("Cannot determine username!");
}

Reply via email to