in reply to Running Perl program via Sendmail

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

  • Replies are listed 'Best First'.
    Re: Re: Running Perl program via Sendmail
    by jacques (Priest) on Feb 17, 2003 at 20:31 UTC
      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.