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);







Reply via email to