P.V.Anthony wrote:
On 03/08/2015 08:04 PM, Mick wrote:
I'm a noobie to postfix myself but I'll have an educated guess and say
'reject_authenticated_sender_login_mismatch' will REJECT if sender does
not match the sasl_username without any exception. If you want to allow
an sasl_username to send messages for an non matching sender, then I'm
pretty sure you will have to remove it from the
smtpd_sender_restrictions.
If you only want to grant certain users permission to do this, you could
write a script and run it as an external policy in place of that
restriction. Postfix will pass the sasl_username and sender details over
to your script, which could then veto each request based on the
sasl_username. Do you know how to do this? If you don't, I could post a
> PERL example tomorrow.
Thank you very much for replying.
The PERL script would be very very very helpful. Thank you again for
offering to help.
Okay, here it goes..... You know I'm a novice right? If anyone on this
group thinks this is a no no, please comment.
Do read the comments denoted by a # at the start of each line or after ;
at the end of the line. It explains what is going on.
You don't need the bottom bit of the script, except for interest / debug
/ future policy ideas and is not intended to be permanent.
Copy, paste and save the script below as /etc/postfix/sasluser.p
You can save it anywhere and by any name, but for this example it is
where I have put it and named it.
Once saved, from the command line set permissions,
chown nobody:nogroup /etc/postfix/sasluser.p
chmod 774 /etc/postfix/sasluser.p
Edit the $allowed array entries to show addresses you want to bypass the
sasl_username not equalling the sender restriction. Make sure you add a
backslash before the '@' symbol.
From the command prompt (PuTTY) switch user to nobody
su nobody
...
type ;
perl /etc/postfix/sasluser.p
If no errors, you should get a blank line without command prompt, if so type
sasl_username=
sender=anaddr...@anydomain.sg
<blank line>
....
You should see action=DUNNO printed on the screen, this because as the
sasl_username field is empty, we assume this is an external incoming
mail which won't match the sender address. DUNNO tells postfix to pass
onto the next test by the way.
If the sasl_username is different from the sender, but is in $allowed,
OR sasl_username not in your $allowed array, but matches the sender
address, you should also get a DUNNO. If you test with an sasl_username
not in $allowed, with a sender address that doesn't match, you will see
action=REJECT + reason
ONLY if you can get the above to work as shown under user nobody,
considder adding it to postfix. Before doing so, do a postfix reload
just to ensure your current config is working sending an email to
confirm. Also *DO* backup both of these files before altering. I've been
caught out like this before where a previous change I made messed up the
setup, but as I hadn't reloaded I didn't notice. It took me hours to
work out that the fault wasn't with what I had just done. Hours!!!
Anyway, if it passes the tests shown above, add this line to master.cf
policy-sg unix - n n - - spawn user=nobody
argv=/etc/postfix/sasluser.p -v
Save, postfix reload, send message. If okay, add the following line to
main.cf in place of reject_authenticated_sender_login_mismatch
check_policy_service unix:private/policy-sg,
If it was the last line, remove the comma.
Save, postfix reload, send message. If it fails, comment out the line,
save, postfix reload, retry sending. Check permissions are correct.
The script is very basic, and though functional is only meant only as a
starting point. It would be better to read the super users in from a
file or database rather than having to alter / add to an array in the
script as a typo / semi colon missing in the script = your mailserver
SMTP dies by server configuration error. Do test thoroughly first.
Just so you know, I only wrote my first PERL script two weeks ago so
there is probably a much neater way write it. The purists certainly
won't approve it looking more like php than PERL, but I'm still
learning. Should all variables be defined by 'my'? Also, this comes with
no warranty or liability. There may be typos. If you you use it, it's at
your own risk!!!!
Good luck,
Mick.
#!/usr/bin/perl
# sasluser.p
# PERL Script hashed up by Snakebyte
# version 0.01
$action="action=DUNNO\n\n";
$sender="";
$sasl_username="\n";
#
# SASL users that are allowed to play at God ;
# Note : you must add a backslash \(escape character) before '@' else PERL
will treat it as an array
# While it won't kill the script, it won't work either.
$allowed[0]="address1\@mydomain.sg";
$allowed[1]="address2\@mydomain.sg";
# add more by $allowed[2]="..."; $allowed[3]="..."; and so on
# Read data passed in by Postfix and grab sender and sasl_username
$a=""; # This is only needed while / if you include the end of the script, but doesn't hurt to leave it
while ($b ne "\n")
{
$b=(<STDIN>);
$a.=$b; # This is only needed while / if you include the end of the script, but doesn't hurt to leave it
if ($b =~ /=/)
{
my ($key, $value) =split (/=/, $b, 2);
if ($key eq "sender") { $sender=$value;}
if ($key eq "sasl_username") { $sasl_username=$value;}
}
}
# --------------
# Disreguard non SASL authenticated and exit the script.
# If you don't do this, incoming mail will be rejected as sasl_username (being
blank) won't equal sender
if ($sasl_username eq "\n")
{
print"action=DUNNO\n\n";
exit(0);
}
# ---------------
# The following line will reject in a similar way that
'reject_authenticated_sender_login_mismatch' would do.
# You can change the text following 'REJECT ' to your own custom message.
# ne = not equal, eq = uqual when comparing strings.
if($sasl_username ne $sender) { $action="action=REJECT Not authorised to send from
this address"; }
# remove linefeed from sasl_username using chomp()
chomp($sasl_username);
# The following lines loop through each element of the $allowed array.
# If one of the entries equals the sasl_usename, it will overwrite former reject to $action to "action=DUNNO"
foreach $loop (@allowed)
{
if($loop eq $sasl_username) { $action="action=DUNNO"; }
}
# -----
# That's it, now print $action followed by a double line feeds '\n\n'
print "$action\n\n";
#print "action=DUNNO\n\n";
# If you un-comment the above line, and comment '#'the one above that, this
script will not reject anything.
# You can ignore the rest keeping only exit(0), but.......
# If you want to see what the other variables the script is receiving from
Postfix, you can log them.
# Create a directory of your choice. eg /var/worldwrite. From PuTTY root privilege command line type
# mkdir /var/worldwrite
# chown nobody:nogroup /var/worldwrite
# chmod 774 /var/worldwrite/
$file="/var/worldwrite/postreport.txt";
my($key, $time_stamp, $now);
$key = lc @_{"client_address"}."/".$attr{"sender"}."/".$attr{"recipient"};
# '>>' appends a file, creating if it doesn't exist if it has permission
# '>' will write new each time. Below is set to append.
# $fh is the file handle
open(my $fh, '>>', $file) or die "Can't open file";
print $fh "Start:\n$a\n$action\nEnd\n";
close $fh;
# If all is working okay, I would delete from print "$action\n\n"; to here, Then delete the worldwrite directory.
# You will only end up with a bloated file, and a directory writeable by nobody (which could be everybody?). Not good.
exit(0);