Triggering a script using POSTFIX....


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Triggering a script using POSTFIX....
# 1  
Old 04-04-2017
Triggering a script using POSTFIX....

I have a mail server configured on my server (Postfix), I have a script which requires input to be provided to it.

I would like to know if there is a possibility to trigger this script by sending mail to the server.

This is what I am thinking:

Once the mail arrives on server, the mail will contain all the input that script needs.

The script will use these variables in it and get exeucted.

Example. The script needs following input:

1 : Firstname
2 : Lastname
3 : email address
4 : Group name


Is there a possibility to make the script run once a mail comes in and then use the inputs from the mail to finish the job?
# 2  
Old 04-04-2017
Hi,

This is possible, yes. I've done it myself in the past when this has been absolutely the only way I could remotely trigger something on a system (i.e. when SMTP was the only port a server could take incoming connections on, and so I had to use it as a crude job control method). It's not ideal, and you have to be absolutely sure that things are as locked-down security-wise as you can make them to eliminate this being a potential security hole, but if you really have to/need to, this is do-able.

I did it by having an entry in /etc/aliases for the SMTP username that then forwarded into a local pipe to my script.

So an entry like this in /etc/aliases

Code:
scriptuser: "|/usr/bin/sudo /usr/local/bin/script.sh"

would pipe the full body of any e-mail received for the mailbox scriptuser into the script /usr/local/bin/script.sh, in this instance running it via sudo as well (assuming the script needs root access).

As I say, it's a crude method and you need to be as close to 100% sure as you can be that your script does every possible kind of sanity checking and input sanitising that you can think of. But it should work for you - it certainly has for me in the past, when I've had no other choice but to go down that road.
This User Gave Thanks to drysdalk For This Post:
# 3  
Old 04-04-2017
Quote:
Originally Posted by drysdalk
Hi,

This is possible, yes. I've done it myself in the past when this has been absolutely the only way I could remotely trigger something on a system (i.e. when SMTP was the only port a server could take incoming connections on, and so I had to use it as a crude job control method). It's not ideal, and you have to be absolutely sure that things are as locked-down security-wise as you can make them to eliminate this being a potential security hole, but if you really have to/need to, this is do-able.

I did it by having an entry in /etc/aliases for the SMTP username that then forwarded into a local pipe to my script.

So an entry like this in /etc/aliases

Code:
scriptuser: "|/usr/bin/sudo /usr/local/bin/script.sh"

would pipe the full body of any e-mail received for the mailbox scriptuser into the script /usr/local/bin/script.sh, in this instance running it via sudo as well (assuming the script needs root access).

As I say, it's a crude method and you need to be as close to 100% sure as you can be that your script does every possible kind of sanity checking and input sanitising that you can think of. But it should work for you - it certainly has for me in the past, when I've had no other choice but to go down that road.
Man!! Thank you so much for taking time to reply to my question! I really appreciate it my friend. You have no idea, how happy I am to have someone give me some leads to do this.

Now, just to give an insight of what I am doing,
I have OpenLDAP, I have created a script for adding user in it and the script is interactive, it asks for first name, lastname , email id, server name on which access is needed and Group name.

I have to manually enter all these details EVERYDAY!! sometime as many as 25 requests...

I got tired of doing it manually, so I was thinking about it.

May I know, after you sent the mail to your server, and you had already configured the aliases...

A : How did you make the script take these inputs?

I am new to scripting, this is my 1st script!! LOL

So, yes I am a script kiddie,

B: The server is on AWS (so can i not implement some kind of a security for incoming mails?)
# 4  
Old 04-04-2017
Hi,

The main thing to consider is that any e-mail that is fed in to your script will be taken as input. So, you'll decide on a format for your input, and write your script to handle that input when it arrives in the expected e-mail. The problem arises when you consider: what will your script do with e-mails it doesn't expect, and interprets them as valid input ?

For example, consider the following. Imagine you have a script whose purpose in life is to receive an e-mail containing a list of files or directories, and which then removes that list. Let's say you decide on a format like this for your input:

Code:
LIST
/tmp/file1.txt
/var/tmp/*
END

You write your script to read the input a line at a time, and when it sees a line starting with LIST it knows it's found valid input. It will then do an rm -rf on the contents of each line it reads from the e-mail until it sees a line starting with END, at which point it stops.

All reasonable, you might think. Now consider what would happen if your script's e-mail address were to randomly receive a spam e-mail with some lines that looked like this:

Code:
Amazing new deals !
You can trust us, because we've been
LISTED ON EBAY SINCE 2000 !
/* AMAZING BARGAINS \*
/* ASTONISHING PRICES \*
/* THESE DEALS WON'T LAST FOREVER... \*
ENDS TOMORROW !

Your script would dutifully read through the e-mail, see the line starting with LISTED, interpret the LIST as the start of input, and start removing files beginning with the next line....the first part of which is /*. So what will your script then do ? rm -rf /*, that's what. Bye-bye, server.

A very contrived example I'll grant you, but it demonstrates the point. E-mail interfaces are inherently risky because you never can say for sure what might be received in that mailbox, unless you have other ways of restricting that of course.

So you must be sure that your script checks every single bit of its input, and ensures it is absolutely 100% exactly in conformity with what you expect it to handle. If it isn't, it must handle it safely, or refuse to do anything with it.

In summary, the two main things you need to remember when writing scripts triggered by e-mails are:

  1. Make sure only allowed senders and/or servers can e-mail your server's script address to trigger the script.
  2. Make sure that the script does full complete sanity checking on the input anyway, just in case.

Hope this helps give you some pointers.
This User Gave Thanks to drysdalk For This Post:
# 5  
Old 04-04-2017
Quote:
Originally Posted by drysdalk
Hi,

The main thing to consider is that any e-mail that is fed in to your script will be taken as input. So, you'll decide on a format for your input, and write your script to handle that input when it arrives in the expected e-mail. The problem arises when you consider: what will your script do with e-mails it doesn't expect, and interprets them as valid input ?

For example, consider the following. Imagine you have a script whose purpose in life is to receive an e-mail containing a list of files or directories, and which then removes that list. Let's say you decide on a format like this for your input:

Code:
LIST
/tmp/file1.txt
/var/tmp/*
END

You write your script to read the input a line at a time, and when it sees a line starting with LIST it knows it's found valid input. It will then do an rm -rf on the contents of each line it reads from the e-mail until it sees a line starting with END, at which point it stops.

All reasonable, you might think. Now consider what would happen if your script's e-mail address were to randomly receive a spam e-mail with some lines that looked like this:

Code:
Amazing new deals !
You can trust us, because we've been
LISTED ON EBAY SINCE 2000 !
/* AMAZING BARGAINS \*
/* ASTONISHING PRICES \*
/* THESE DEALS WON'T LAST FOREVER... \*
ENDS TOMORROW !

Your script would dutifully read through the e-mail, see the line starting with LISTED, interpret the LIST as the start of input, and start removing files beginning with the next line....the first part of which is /*. So what will your script then do ? rm -rf /*, that's what. Bye-bye, server.

A very contrived example I'll grant you, but it demonstrates the point. E-mail interfaces are inherently risky because you never can say for sure what might be received in that mailbox, unless you have other ways of restricting that of course.

So you must be sure that your script checks every single bit of its input, and ensures it is absolutely 100% exactly in conformity with what you expect it to handle. If it isn't, it must handle it safely, or refuse to do anything with it.

In summary, the two main things you need to remember when writing scripts triggered by e-mails are:

  1. Make sure only allowed senders and/or servers can e-mail your server's script address to trigger the script.
  2. Make sure that the script does full complete sanity checking on the input anyway, just in case.

Hope this helps give you some pointers.
You are absolutely right with that example.

I will make sure that the script only works with desired inputs.

As far as security is concerned I will consult my network team...

Do you think IFS (line) would be a good option to input these variables?


this is an example:

Code:
echo -n "What is the firstname":
read FIRST
echo -n "What is the lastname":
read LAST
echo -n "Is this a new user (Y for yes, N for No)":
read NO
if [[ $NO =~ ^(y|Y)$ ]] ; then
file=`cat uid`

x=$file
y=1
userid=$(( x + y ))


#echo -n  "What is the uid":
#read userid
echo $userid > uid
echo -n "What is the email":
read EMAIL
#echo -n "What is username":
#read USERNAME

===============================================

I will have my mail body consisting of these variables, and then make the script use it.

Does it sound like a good idea?

Moderator's Comments:
Mod Comment Please do wrap your samples/codes in CODE TAGS as per forum rules.

Last edited by RavinderSingh13; 02-06-2020 at 02:15 PM..
# 6  
Old 04-04-2017
Hi,

In terms of the implementation, your script would want to parse line-by-line whatever is piped in to it, and then act based on what it got. The format I've used in general for scripts that run in this way (input is directly piped into them) is:

Code:
#!/bin/bash
/bin/cat - | while read -r line
do
        #Code goes here
done

The point of /bin/cat - at the start is just to print out again whatever is passed into cat as standard input (represented by the - symbol), which will be whatever Postfix is piping into the script. So you can then do whatever you wan to do with each line to determine what it is, what to do with it, and so on.

So in your case, if you had lines that would define and set variables, you could look for them on a line-by-line basis. A quick example of one way of doing this would be the following.

Let's say our e-mail body will contain the following variables: UID, USERNAME and HOMEDIR. We want our script to find these matching lines, and assign the variables it reads in. Finally we'll terminate our message body with a single line reading END, and get the script to write out the variables it's read at that point.

Here's our code:

Code:
#!/bin/bash
/bin/cat - | while read -r line
do
        case "$line" in
                UID=*)
                        uid=`echo "$line" | /usr/bin/awk -F= '{print $2}'`
                        ;;
                USERNAME=*)
                        user=`echo "$line" | /usr/bin/awk -F= '{print $2}'`
                        ;;
                HOMEDIR=*)
                        home=`echo "$line" | /usr/bin/awk -F= '{print $2}'`
                        ;;
                END)
                        echo "The UID is $uid, the username is $user, and the homedir is $home"
                        exit 0
                        ;;
        esac
done

Here's our example input:

Code:
UID=1002
USERNAME=unixforum
HOMEDIR=/home/unixforum
END

And here's what happens when we run the script by piping the contents of our example input into it:

Code:
$ cat example.txt | ./script.sh
The UID is 1002, the username is unixforum, and the homedir is /home/unixforum
$

Hope this gives you an idea of how the implementation would work, and how your approach of reading in and assigning variables to work with might look.
This User Gave Thanks to drysdalk For This Post:
# 7  
Old 04-05-2017
Quote:
Originally Posted by drysdalk
Hi,

In terms of the implementation, your script would want to parse line-by-line whatever is piped in to it, and then act based on what it got. The format I've used in general for scripts that run in this way (input is directly piped into them) is:

Code:
#!/bin/bash
/bin/cat - | while read -r line
do
        #Code goes here
done

The point of /bin/cat - at the start is just to print out again whatever is passed into cat as standard input (represented by the - symbol), which will be whatever Postfix is piping into the script. So you can then do whatever you wan to do with each line to determine what it is, what to do with it, and so on.

So in your case, if you had lines that would define and set variables, you could look for them on a line-by-line basis. A quick example of one way of doing this would be the following.

Let's say our e-mail body will contain the following variables: UID, USERNAME and HOMEDIR. We want our script to find these matching lines, and assign the variables it reads in. Finally we'll terminate our message body with a single line reading END, and get the script to write out the variables it's read at that point.

Here's our code:

Code:
#!/bin/bash
/bin/cat - | while read -r line
do
        case "$line" in
                UID=*)
                        uid=`echo "$line" | /usr/bin/awk -F= '{print $2}'`
                        ;;
                USERNAME=*)
                        user=`echo "$line" | /usr/bin/awk -F= '{print $2}'`
                        ;;
                HOMEDIR=*)
                        home=`echo "$line" | /usr/bin/awk -F= '{print $2}'`
                        ;;
                END)
                        echo "The UID is $uid, the username is $user, and the homedir is $home"
                        exit 0
                        ;;
        esac
done

Here's our example input:

Code:
UID=1002
USERNAME=unixforum
HOMEDIR=/home/unixforum
END

And here's what happens when we run the script by piping the contents of our example input into it:

Code:
$ cat example.txt | ./script.sh
The UID is 1002, the username is unixforum, and the homedir is /home/unixforum
$

Hope this gives you an idea of how the implementation would work, and how your approach of reading in and assigning variables to work with might look.

Thanks man!! This is very informative. Let me try these stuff, I will let you know the results,

My only concern is security implications, lets see how it goes.
Login or Register to Ask a Question

Previous Thread | Next Thread

9 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Triggering UNIX Script from a JAVA program

Hi I am trying to implement one program, where JAVA needs to trigger the backend UNIX script. Tried with options like String cmdArray = {"/bin/ksh","-c","/SCRIPT_ABSOLUTE_PATH/sampleScript.ksh /FILE_ABSOLUTE_PATH Test_File.dat TEST E SFTP"} When I trigger the script from front end with... (1 Reply)
Discussion started by: karumudi7
1 Replies

2. UNIX and Linux Applications

Postfix: Active Directory and postfix alias

I have a mailserver with postfix i want to alias all mail for administrator@domain.fqdn to root@domain.fqdn I have the aliases configured,and i did newliases but doesn't work. How to did this?Postfix is configured for virtual domain on ad server. (2 Replies)
Discussion started by: Linusolaradm1
2 Replies

3. Shell Programming and Scripting

Triggering remote UNIX shell script from Remote desktop

I m trying to run a batch script in remote desktop which executes unix commands on the unix server...the problem is i wnt the output in HTML format.so in my batch script i m giving the cmd like ssh hostname path ksh HC_Report.ksh>out.html ...but it generates the HTML file in remote desktop .i... (2 Replies)
Discussion started by: navsan
2 Replies

4. UNIX for Dummies Questions & Answers

Please help with Postfix config issue - How to allow remote Exchange server to relay to my postfix

Hi guys One of our clients have a problem with sending email to a certain domain. No matter what we try, the mails just dont get delivered. What I did then, is created a new connector on their Exchange server, pointing all mail sent to their client at "domain1" to relay to our Postfix mail... (0 Replies)
Discussion started by: wbdevilliers
0 Replies

5. UNIX for Dummies Questions & Answers

Script triggering Korn shell, how-to stop it?

Script_A.sh has echo "In am in script A" ksh ## K-shell is invoked. Script B.sh ## which I am writing... ./script_A.sh echo "I am in script B" return 0 When I run: $> Script_B.sh $> I am in script A $> Basically, on calling Script_A.sh from within Script_B.sh I have the issue of... (2 Replies)
Discussion started by: baivab
2 Replies

6. IP Networking

postfix - reinject mail to postfix from hold queue directory

hi all. Am using smtpd_recipient_restrictions & check_recipient_access in postfix. The hash file looks like this: emailaddress1 HOLD emailaddress2 HOLD The aim is to place email from these recipients in the hold directory,check them then reinject them back in postfix on some... (0 Replies)
Discussion started by: coolatt
0 Replies

7. Shell Programming and Scripting

Triggering my Unix script....

Hi All, i dont have any idea about perl scripting... i need some suggestion so that i can put my effort to find out the solution:D let me explain....one of my tedious task which will taken care by Unix shell script which i prepared. its a kind of routine work that i am running the... (4 Replies)
Discussion started by: Shahul
4 Replies

8. Shell Programming and Scripting

PHP Script that sends mail - Postfix breaks it

I have a PHP Script that works perfectly on a server that uses Sendmail. However I tried to port it to a new server that has the Postfix to Sendmail compatibility interface, and it doesn't work properly. The php.ini file has the path for sendmail on both servers set to: /usr/sbin/sendmail -t... (0 Replies)
Discussion started by: boopfm523
0 Replies

9. Shell Programming and Scripting

Triggering a Script Recursively With Different Parameter and in Different Process

Hi Every One I have a Compilation Script name scomp which takes the Program name as the command line argument I have around 10000 Programs to compile while each program takes around 10 mins to compile i have written a Mass Compile script Scripts which takes the list of programs as input... (15 Replies)
Discussion started by: pbsrinivas
15 Replies
Login or Register to Ask a Question