From 8c7c167c5287758a16c6e9e57c3bc1c3dc3a1e2b Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 13 Feb 2004 14:04:22 +0000 Subject: [PATCH] add postfix export --- FS/FS/part_export.pm | 17 +++++++- bin/postfix.export | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 1 deletion(-) create mode 100755 bin/postfix.export diff --git a/FS/FS/part_export.pm b/FS/FS/part_export.pm index 033840aeb..0d9196171 100644 --- a/FS/FS/part_export.pm +++ b/FS/FS/part_export.pm @@ -903,6 +903,13 @@ tie my %forward_shellcommands_options, 'Tie::IxHash', }, ; +tie my %postfix_options, 'Tie::IxHash', + 'user' => { label=>'Remote username', default=>'root' }, + 'aliases' => { label=>'aliases file location', default=>'/etc/aliases' }, + 'virtual' => { label=>'virtual file location', default=>'/etc/postfix/virtual' }, + 'mydomain' => { label=>'local domain', default=>'' }, +; + #export names cannot have dashes... %exports = ( 'svc_acct' => { @@ -1053,7 +1060,7 @@ tie my %forward_shellcommands_options, 'Tie::IxHash', 'desc' => 'Real-time export to SQL-backed mail server', 'options' => \%sqlmail_options, #'nodomain' => 'Y', - 'notes' => 'Database schema can be made to work with Courier IMAP and Exim. Others could work but are untested. (...extended description from pc-intouch?...)', + 'notes' => 'Database schema can be made to work with Courier IMAP and Exim. Others could work but are untested. (...extended description from fire2wire?...)', }, 'forward_shellcommands' => { @@ -1061,6 +1068,14 @@ tie my %forward_shellcommands_options, 'Tie::IxHash', 'options' => \%forward_shellcommands_options, 'notes' => 'Run remote commands via SSH, for forwards. You will need to setup SSH for unattended operation.

Use these buttons for some useful presets:The following variables are available for interpolation (prefixed with new_ or old_ for replace operations): ', }, + + 'postfix' => { + 'desc' => 'Real-time export to Postfix text files', + 'options' => \%postfix_options, + #'nodomain' => 'Y', + 'notes' => 'Batch export of Postfix aliases and virtual files. File::Rsync must be installed. Run bin/postfix.export to export the files.', + }, + }, 'svc_www' => { diff --git a/bin/postfix.export b/bin/postfix.export new file mode 100755 index 000000000..7894a3ad7 --- /dev/null +++ b/bin/postfix.export @@ -0,0 +1,121 @@ +#!/usr/bin/perl -w + +use strict; +#use File::Path; +use File::Rsync; +use Net::SSH qw(ssh); +use FS::UID qw(adminsuidsetup datasrc); +use FS::Record qw(qsearch); # qsearchs); +use FS::part_export; +#use FS::cust_pkg; +use FS::cust_svc; +#use FS::svc_domain; + +my $user = shift or die &usage; +adminsuidsetup $user; + +my $spooldir = "/usr/local/etc/freeside/export.". datasrc. "/postfix"; +mkdir $spooldir, 0700 unless -d $spooldir; + +my @exports = qsearch('part_export', { 'exporttype' => 'postfix' } ); + +my $rsync = File::Rsync->new({ + rsh => 'ssh', +# dry_run => 1, +}); + +foreach my $export ( @exports ) { + + my $machine = $export->machine; + my $prefix = "$spooldir/$machine"; + mkdir $prefix, 0700 unless -d $prefix; + + #construct %domain hash + + my $mydomain = $export->option('mydomain'); + my %domain; + foreach my $svc_forward ( $export->svc_x ) { + + my( $username, $domain ); + my $srcsvc_acct = $svc_forward->srcsvc_acct; + if ( $srcsvc_acct ) { + ( $username, $domain ) = ( $srcsvc_acct->username, $srcsvc_acct->domain ); + } elsif ( $svc_forward->src =~ /([^@]*)\@([^@]+)$/ ) { + ( $username, $domain ) = ( $1, $2 ); + } else { + die "bad svc_forward record? svcnum ". $svc_forward->svcnum. "\n"; + } + + my( $dusername, $ddomain ); + my $dstsvc_acct = $svc_forward->dstsvc_acct; + if ( $dstsvc_acct ) { + $dusername = $dstsvc_acct->username; + $ddomain = $dstsvc_acct->domain; + } elsif ( $svc_forward->dst =~ /([^@]+)\@([^@]+)$/ ) { + ( $dusername, $ddomain ) = ( $1, $2 ); + } else { + die "bad svc_forward record? svcnum ". $svc_forward->svcnum. "\n"; + } + my $dest; + if ( $ddomain eq $mydomain ) { + $dest = $dusername; + } else { + $dest = "$dusername\@$ddomain"; + } + + push @{$domain{$domain}{$username}}, $dest; + + } + + #write aliases + + my $aliases = delete $domain{$mydomain}; + open(ALIASES, ">$prefix/aliases") or die "can't open $prefix/aliases: $!"; + foreach my $alias ( keys %$aliases ) { + print ALIASES "$alias: ". join(',', @{ $aliases->{$alias} } ). "\n"; + } + close ALIASES; + + #write virtual + + open(VIRTUAL, ">$prefix/virtual") or die "can't open $prefix/virtual: $!"; + foreach my $domain ( keys %domain ) { + print VIRTUAL "$domain DOMAIN\n"; + #foreach my $virtual ( sort { $a ne '' <=> $b ne '' } keys %{$domain{$domain}} ) { + foreach my $virtual ( sort { ( ($b ne '') <=> ($a ne '') ) || $a cmp $b } keys %{$domain{$domain}} ) { + print VIRTUAL "$virtual\@$domain ". + join(',', @{ $domain{$domain}{$virtual} } ). "\n"; + } + print VIRTUAL "\n"; + } + close VIRTUAL; + + #rsync + + my $user = $export->option('user'); + $rsync->exec( { + src => "$prefix/aliases", + dest => "$user\@$machine:". $export->option('aliases'), + } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err); +# warn $rsync->out; + + ssh("$user\@$machine", "newaliases"); +# ssh("$user\@$machine", "postfix reload"); + + $rsync->exec( { + src => "$prefix/virtual", + dest => "$user\@$machine:". $export->option('virtual'), + } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err); +# warn $rsync->out; + + ssh("$user\@$machine", "postfix reload"); + +} + +# ----- + +sub usage { + die "Usage:\n postfix.export user\n"; +} + + -- 2.11.0