jacques has asked for the wisdom of the Perl Monks concerning the following question:

Fellow monks,

In my aliases file, I have the following entry:

allusers: "|/etc/test.pl"

test.pl is a simple Perl script. It consists of:

system("date | /usr/lib/sendmail jacques\@whatever.com");

When someone sends an email to allusers@whatever.com, the Perl script executes and Jacques gets an email from daemon@whatever.com. That's the problem. The email is coming from 'daemon' instead of the person who sent the email to allusers. How do I get the original sender to appear in the 'from' field?

Replies are listed 'Best First'.
Re: Running Perl program via Sendmail
by Limbic~Region (Chancellor) on Feb 17, 2003 at 19:08 UTC
    jacques,
    I tried to explain why this was not the best approach in the CB when you brought it up earlier.

    The problem as you originally stated it was:

  • The ability to have Sendmail send to all the local users except the system accounts.
  • The ability for this to happen dynamically (no changes when accounts are deleted or added)
  • New Requirement Ability to retain the original sender in the from address.

    My suggestion was to either have an alias that piped the message into a script, which stored the message in a temporary file, parsed the /etc/passwd file, and then sent the message back to Sendmail, and delete the temporary file
    or
    Roll your own useradd

    Now, the reason your solution didn't work is because you didn't let the script re-initiate Sendmail - and because one of the other security concerns I raised (you still have Sendmail's default user set to daemon).

    Here is some pseudo code to help you get started

    1. Read in the message piped to the script line by line 2. Append the data to a temporary file 3. Do not write the "from" line or the "to" line to file 4. Save the "from" off into a variable 5. Parse the /etc/passwd to build a "recipient" list 6. system (cat $tmp|sendmail -bm -f"$from" "$recip");

    You also want to consider the following security precautions:

  • Change the default user to a non-system account if possible
  • Be careful where you put the script as it is possible to delete a file you do not have write permission to provided the directory has certain permissions
  • Be very careful on the permissions/owner you give the script as if it was modified without your knowledge - it would be bad juju

    The code might look something like:

    #/usr/bin/perl -w use strict; open (TMPOUT,">/tmp/somefile"); my $from; my @recipients; while (<>) { print TMPOUT unless (/^From: /i || /^To: /i); ($from = $_) =~ /Some regex to get from/ if (/^From: /i); } close (TMPOUT); open (PASSWD,"/etc/passwd"); while (<PASSWD>) { my @fields = split ":" , $_; push @recip , $fields[0] unless (#system account); } system (cat /tmp/somefile|sendmail -bm -f"$from" "@recips"); unlink "/tmp/somefile";

    This is just to give you an IDEA of how to do it

    Cheers - L~R

    Update: Per jaques's request, I included sample code to go along with the pseudo code

      Thanks! It didn't dawn on me that I can read in the message which is piped. Then I grab the From field as you show. Marvelous.
Re: Running Perl program via Sendmail
by joe++ (Friar) on Feb 18, 2003 at 09:46 UTC
    Slightly OT, but you may want to look into procmail to do the routing based on any mail header or even the mesage body content.

    Procmail's configuration file syntax is rather arcane, but as always Google will help you and there are also independens sites with tips available on the web.

    HTH!

    --
    Cheers, Joe

Re: Running Perl program via Sendmail
by jasonk (Parson) on Feb 17, 2003 at 18:03 UTC
    system("date | /usr/lib/sendmail -f somebody\@somedomain.com jacques\@ +whatever.com");
      That doesn't work. How do I know who that somebody is? It's the person who sent mail to allusers.