#!/usr/bin/perl -w ########################################################################### # # Script to generate the sendmail access.db file from a list of valid # email addresses and domains (see also the adexport.txt script at # packetslave.com). # # Brian Landers ########################################################################### use strict; use IO::File; # # Constants # our $BASEDIR = '/etc/mail'; our $DOMAINS = 'relay-domains'; # list of domains we accept our $ALLMAIL = 'all-emails.txt'; # list of ALL valid email addresses our $ACCESS = 'access'; # name of access.db source file # -------- Parse all-emails.txt file # KAM: 1-15-04 Moved read of file to top and a check for valid entries to # prevent deleting a valid access.db file if the Exchange Server is down. my @allmail = @{ read_commented_file( "$BASEDIR/$ALLMAIL" ) }; if ($#allmail < 0) { die "The all-emails.txt file contains 0 valid entries. Refusing to create a blank access.db source file."; } # -------- Open a filehandle for the access file # KAM: 1-15-04 Directly write to the access.db file my $filehandle = new IO::File("> $BASEDIR/$ACCESS") or die "Error opening access.db source file. $!"; select($filehandle); # Print a header for the file print << "END"; ###################################################################### # # Sendmail access.db source file # # THIS FILE IS DYNAMICALLY GENERATED! # IF YOU EDIT IT, YOUR CHANGES *WILL* BE LOST! # ###################################################################### # by default we allow relaying from localhost... localhost.localdomain RELAY localhost RELAY 127.0.0.1 RELAY END # -------- The 'valid recipients' section # For each address for which we accept mail, output a line allowing # it to be relayed. Skip any addresses that were in the blocked # address list (this is how we block internal-only addresses). print << "END"; # # All valid emails for which we accept mail # See $BASEDIR/$ALLMAIL # END foreach my $address( @allmail ) { print "To:$address \t RELAY\n"; } # -------- Default 'no such user' entries for all domains my @domains = @{ read_commented_file( "$BASEDIR/$DOMAINS" ) }; # For each domain we accept email, output a DEFAULT entry giving a # 'no such user' error, since any valid address would be handled by # the address entries above. print << "END"; # # Default entry for each domain we accept. Blocks invalid addresses # See $BASEDIR/$DOMAINS # END foreach my $domain( @domains ) { print qq(To:$domain\t ERROR:"User unknown"\n); } close ($filehandle); exit; # -------- Subroutines # # Utility routine to read a file and skip comments # Returns a reference to an array of the file's contents # # Note: reads the whole thing into memory, could be bad for huge files # sub read_commented_file { local *FILE; my $file = shift; die "BUG: didn't get a file to read" unless $file; open( FILE, $file ) || die "$file: $!\n"; chomp( my @data = grep { ! /^\s*$/ && ! /^\s*#/ } ); close FILE; return \@data; }