I have been banging my head against this problem for 2 weeks. What I am trying to do is pipe a sendmail alias (catchall for a virtusal domain) to a php script. However, I always get the following error (Cannot mail directly to programs):

Oct 7 14:35:49 fut-02 sm-mta[14057]: o97LZlmh014057: <5minutes@dev2.domain.com>... Cannot mail directly to programs Oct 7 14:35:49 fut-02 sm-mta[14057]: o97LZlmh014057: from=, size=0, class=0, nrcpts=0, proto=ESMTP, daemon=MTA-v4, relay=mail-ww0-f46.google.com []

I have tried the following aliases in my virtusers file:

@domain.com "|php -q /home/myuser/myscript.php"
@domain.com "|/usr/bin/php5 -q /home/myuser/myscript.php"
@domain.com "|php5 /home/myuser/myscript.php"
@domain.com "|myscript.php"
@domain.com "|php5 myscript.php"

I have tried enabling smrsh in the sendmail.mc file 2 different ways:


I then tried linking /usr/bin/php, /usr/bin/php5, (the actual binary), and the script itself to /etc/mail/smrsh/. I have also tried disabling smrsh altogether. Every test results in the same error. To verify smrsh is working I am able to successfully run:

/usr/lib/sm.bin/smrsh -c "/usr/bin/php5 -q /home/user/myscript.php"

A copy of my sendmail.mc is at the bottom of this post.

Am I missing something obvious? Is there possibly somewhere else in the Ubuntu/Debian sendmail configuration that can block mailing to scripts?

FWIW, I tried this setup on Ubuntu 10.10 RC and Debian 5. Same results on both with the exception that Debians default sendmail.mc comes formatted incorrectly (had FEATURES after the MAILER directives).

#   Copyright (c) 1998-2005 Richard Nelson.  All Rights Reserved.
#  This file is used to configure Sendmail for use with Debian systems.
VERSIONID(`$Id: sendmail.mc, v 8.14.3-9.2ubuntu1 2010-08-03 06:56:05 cowboy Exp $')
dnl # Items controlled by /etc/mail/sendmail.conf - DO NOT TOUCH HERE
dnl # Items controlled by /etc/mail/sendmail.conf - DO NOT TOUCH HERE
dnl #
dnl # General defines
dnl #
dnl # SAFE_FILE_ENV: [undefined] If set, sendmail will do a chroot()
dnl #   into this directory before writing files.
dnl #   If *all* your user accounts are under /home then use that
dnl #   instead - it will prevent any writes outside of /home !
dnl #   define(`confSAFE_FILE_ENV',             `')dnl
dnl #
dnl # Daemon options - restrict to servicing LOCALHOST ONLY !!!
dnl # Remove `, Addr=' clauses to receive from any interface
dnl # If you want to support IPv6, switch the commented/uncommentd lines
dnl #
dnl DAEMON_OPTIONS(`Family=inet6, Name=MTA-v6, Port=smtp, Addr=::1')dnl
DAEMON_OPTIONS(`Family=inet,  Name=MTA-v4, Port=smtp')dnl
dnl DAEMON_OPTIONS(`Family=inet6, Name=MSP-v6, Port=submission, M=Ea, Addr=::1')dnl
DAEMON_OPTIONS(`Family=inet,  Name=MSP-v4, Port=submission, M=Ea')dnl
dnl #
dnl # Be somewhat anal in what we allow
dnl define(`confPRIVACY_FLAGS',dnl
dnl `needmailhelo,needexpnhelo,needvrfyhelo,restrictqrun,restrictexpand,nobodyreturn,authwarnings')dnl
dnl #
dnl # Define connection throttling and window length
define(`confCONNECTION_RATE_THROTTLE', `15')dnl
dnl #
dnl # Features
dnl #
dnl # use /etc/mail/local-host-names
dnl #
dnl # The access db is the basis for most of sendmail's checking
FEATURE(`access_db', , `skip')dnl
dnl #
dnl # The greet_pause feature stops some automail bots - but check the
dnl # provided access db for details on excluding localhosts...
FEATURE(`greet_pause', `1000')dnl 1 seconds
dnl #
dnl # Delay_checks allows sender<->recipient checking
FEATURE(`delay_checks', `friend', `n')dnl
dnl #
dnl # If we get too many bad recipients, slow things down...
dnl #
dnl # Stop connections that overflow our concurrent and time connection rates
FEATURE(`conncontrol', `nodelay', `terminate')dnl
FEATURE(`ratecontrol', `nodelay', `terminate')dnl
dnl #
dnl # If you're on a dialup link, you should enable this - so sendmail
dnl # will not bring up the link (it will queue mail for later)
dnl define(`confCON_EXPENSIVE',`True')dnl
dnl #
dnl # Dialup/LAN connection overrides
dnl #
dnl #
dnl # Default Mailer setup
FEATURE(`virtusertable', `hash /etc/mail/virtusers')dnl
  • In the sendmail.cf do you have a prog mailer defined (look for Mprog)? Should be there because of MAILER(`local') but I'm looking on fedora. Oct 8, 2010 at 20:06
  • Yep, it is listed as: Mprog, P=/usr/lib/sm.bin/smrsh, F=lsDFMoqeu9, S=EnvFromL/HdrFromL, R=EnvToL/HdrToL, D=$z:/, T=X-Unix/X-Unix/X-Unix, A=smrsh -c $u
    – Andy Shinn
    Oct 11, 2010 at 18:12

2 Answers 2


You have to modify ruleset 0 (or ruleset 2) to work this out:

R$* < @ virtualdomain.com. > $*     $#prog $: $1 @ virtualdomain.com

The prog delivery agent is discussed at page 727 of the "bat book" (4th edition).

The above does not work with smrsh. It makes the assumption that $#prog is set to a program that decides what actions to take based on its argument.

You can even define your own delivery agent which will do exactly what you want, instead of trying to fit what is available to your case.

  • I've never heard of these rule sets before. I will test this out. At first glance, this looks like a replacement for smrsh, is this correct?
    – Andy Shinn
    Apr 22, 2011 at 23:45
  • $#prog is the "program" delivery agent (using sendmail terminology). If you have enabled FEATURE(smrsh) this program will be executed via smrsh. You have to define your $#prog delivery agent to work with your script. See the operations guide at sendmail.com/sm/open_source/docs
    – adamo
    Apr 25, 2011 at 12:17
  • I am actually looking to use smrsh for security purposes. This allows me to control which binaries a user can specify in their pipe. This sounds like I would have to specify specif user pipe in the local rule instead of the virtual table which defeats the purpose a little bit.
    – Andy Shinn
    May 1, 2011 at 2:09
  • You cannot have pipes in the virtusertable. Pipes go in the /etc/mail/aliases. So if you want emails for certain domains (or addresses in those virtual domains) to trigger specific programs you have to redirect them to specific entries in /etc/mail/aliases with pipes. However in the generic case of a whole domain, you cannot know which was the left hand side of the email address. That is why I recommend doing directly via the rulesets. Then $#prog can execute the programs you want.
    – adamo
    May 1, 2011 at 6:37
  • I've revised my answer to make it a little bit more understandable.
    – adamo
    May 1, 2011 at 6:48

AFAIK you'll need to specify a user or alias in your virtusertable, rather than the pipe. once you've done that, specifying the pipe in your alias file should do the trick.

For example, in /etc/mail/virtusers

@example.com pipeuser

And then in /etc/aliases

pipeuser: "| /usr/bin/php5 -q /home/myuser/myscript.php"

  • The problem going this way is all the email coming into the script is seen as "alias@domain.com" instead of the actual name it was sent from. This isn't usable as the script needs to know the proper From: user.
    – Andy Shinn
    Nov 19, 2010 at 3:06
  • The 'proper From: user' is in the headers
    – jwg
    Jan 15, 2014 at 12:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.