#!/usr/bin/perl -w # # $Id: //websites/unixwiz/newroot/techtips/postfix-exchange/parse-exchange-users.txt#3 $ # # written by : Stephen J Friedl # Software Consultant # Tustin, California USA # steve@unixwiz.net / www.unxiwiz.net # # ================================================================ # This program is part of a Tech Tip on setting up relay from a # Postfix system into MS Exchange. The entire Tech Tip can be # found at http://www.unixwiz.net/techtips/postfix-exchange-relay.html # ================================================================ # # # This program reads the exported file created by MS Exchange from # the standard input and creates the "relay_recipients" file as # used by Postfix. It strips off any email addresses that are not # SMTP (X.400 and CCMail, for instance), converts everything to lower # case, and writes the results in # # steve@unixwiz.net OK # postmaster@unixwiz.net OK # ... # # format. # # In the absent of any other command-line options, there is a one-for # one mapping of input address to those written to the output (though # duplicates are always suppressed). But this may not be the exact list # of recipients to allow relay for: we may need to actively exclude some # 'sensitive' addresses, as well as add a few that we couldn't get # Exchange to export for whatever reason. These are both specified # with the --include=FILE and --exclude=FILE options. # # Both take the names of files that contain lines of email addresses, # and they are added to the master list being created. Any users in # the "--exclude=FILE" list are guaranteed to be excluded even if # that same username appears in an --include list. This is a failsafe. # # Adding --domain=D (perhaps multiple times) adds an extra check to # all the generated email addresses: addresses that don't have one of # these as their entire domain part are excluded. use strict; my %RESULT = (); my $excludefile = undef; my $includefile = undef; my %DOMAINS = (); foreach ( @ARGV ) { if ( m/^--help/i ) { print STDERR < ) { s/\s+$//; my($objclass, $emailaddresslist, $secaddresslist) = split( m/\t/, lc $_); my @ADDRESSES = (); push @ADDRESSES, split( m/%/, $emailaddresslist ) if $emailaddresslist; push @ADDRESSES, split( m/%/, $secaddresslist ) if $secaddresslist; foreach my $addr ( @ADDRESSES ) { # -------------------------------------------------------- # find and strip off leading SMTP token: this excludes the # X.400 crap. # next unless $addr =~ s/^smtp://; # -------------------------------------------------------- # Have we defined any "valid domains"? If so, make sure we # have one. # if ( %DOMAINS ) { ( my $dom = $addr ) =~ s/.*\@//; next unless $DOMAINS{$dom}; } # -------------------------------------------------------- # CUSTOM PROCESSING # # Many times the "rules" for excluding an address are easier # put in code than they are in the list. Add yours here. # # next if $addr =~ m/\@ntserver\./; # -------------------------------------------------------- # If this is already defined in the table, don't overwrite # it with the current OK. This way any "NO" entries are # not changed to "OK". # next if defined $RESULT{$addr}; $RESULT{$addr} = 'OK'; } } print < ) { # ignore all comments and blank lines s/#.*$//; # dump comments s/\s+$//; # dump trailing white next if length == 0; my $addr = lc $_; $RESULT{$addr} = $resp; } close F; }