1#! --PERL-- 2# -*- indent-tabs-mode: nil; -*- 3# vim:ft=perl:et:sw=4 4# $Id$ 5 6# Sympa - SYsteme de Multi-Postage Automatique 7# 8# Copyright (c) 1997, 1998, 1999 Institut Pasteur & Christophe Wolfhugel 9# Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 10# 2006, 2007, 2008, 2009, 2010, 2011 Comite Reseau des Universites 11# Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017 GIP RENATER 12# Copyright 2017 The Sympa Community. See the AUTHORS.md file at the top-level 13# directory of this distribution and at 14# <https://github.com/sympa-community/sympa.git>. 15# 16# This program is free software; you can redistribute it and/or modify 17# it under the terms of the GNU General Public License as published by 18# the Free Software Foundation; either version 2 of the License, or 19# (at your option) any later version. 20# 21# This program is distributed in the hope that it will be useful, 22# but WITHOUT ANY WARRANTY; without even the implied warranty of 23# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24# GNU General Public License for more details. 25# 26# You should have received a copy of the GNU General Public License 27# along with this program. If not, see <http://www.gnu.org/licenses/>. 28 29use lib split(/:/, $ENV{SYMPALIB} || ''), '--modulesdir--'; 30use strict; 31use warnings; 32use English qw(-no_match_vars); 33use Getopt::Long; 34use Pod::Usage; 35 36use Conf; 37use Sympa::Constants; 38use Sympa::Crash; # Show traceback. 39use Sympa::Log; 40 41# If this program was invoked by the other, throw standard output away so 42# that parent's output (e.g. via CGI) won't be stained. 43unless (-t) { 44 open STDOUT, '>&STDERR'; 45} 46 47my %options; 48unless (GetOptions(\%options, 'domain=s', 'help|h', 'version|v')) { 49 pod2usage(-exitval => 1, -output => \*STDERR); 50} 51if ($options{'help'}) { 52 pod2usage(0); 53} elsif ($options{'version'}) { 54 printf "Sympa %s\n", Sympa::Constants::VERSION; 55 exit 0; 56} 57 58my $log = Sympa::Log->instance; 59$log->{log_to_stderr} = 'all' if -t; 60 61my $robot_id = $options{'domain'}; 62 63# Load configuration 64unless (Conf::load()) { 65 $log->syslog('err', 'The configuration file %s contains error', 66 Conf::get_sympa_conf()); 67 exit 1; 68} 69 70$log->openlog( 71 $Conf::Conf{'syslog'}, 72 $Conf::Conf{'log_socket_type'}, 73 database_backend => undef 74); 75 76# setting log_level using conf unless it is set by calling option 77$log->{level} = $Conf::Conf{'log_level'}; 78 79my ($aliases_file, $aliases_program, $aliases_db_type); 80if ($robot_id) { 81 unless (Conf::valid_robot($robot_id)) { 82 $log->syslog('err', 'Robot %s does not exist', $robot_id); 83 exit 1; 84 } 85 $aliases_file = Conf::get_robot_conf($robot_id, 'sendmail_aliases'); 86 $aliases_program = Conf::get_robot_conf($robot_id, 'aliases_program'); 87 $aliases_db_type = Conf::get_robot_conf($robot_id, 'aliases_db_type'); 88} else { 89 $aliases_file = $Conf::Conf{'sendmail_aliases'}; 90 $aliases_program = $Conf::Conf{'aliases_program'}; 91 $aliases_db_type = $Conf::Conf{'aliases_db_type'}; 92} 93if ($aliases_file eq 'none') { 94 exit 0; # do nothing 95} elsif (!-e $aliases_file) { 96 $log->syslog('err', 'The aliases file %s does not exist', $aliases_file); 97 exit 1; 98} 99unless ($aliases_db_type =~ /\A\w+\z/) { 100 $log->syslog('err', 'Invalid aliases_db_type "%s"', $aliases_db_type); 101 exit 1; 102} 103 104if ($aliases_program =~ m{\A/}) { 105 $log->syslog('debug2', 'Executing "%s %s"', 106 $aliases_program, $aliases_file); 107 108 exec $aliases_program, $aliases_file; 109} elsif ($aliases_program eq 'makemap') { 110 $log->syslog('debug2', 'Executing "%s %s %s < %s"', 111 q{--MAKEMAP--}, $aliases_db_type, $aliases_file, $aliases_file); 112 113 unless (open STDIN, '<', $aliases_file) { 114 $log->syslog('err', 'Canot open %s', $aliases_file); 115 exit 1; 116 } 117 exec q{--MAKEMAP--}, $aliases_db_type, $aliases_file; 118} elsif ($aliases_program eq 'newaliases') { 119 $log->syslog( 120 'debug2', 121 'Executing "%s"', 122 q{--NEWALIASES-- --NEWALIASES_ARG--} 123 ); 124 125 # Some newaliases utilities e.g. with Postfix cannot take arguments. 126 # OTOH if it may take arg, exec() must take separate one to avoid shell 127 # metacharacters. 128 if (q{--NEWALIASES_ARG--}) { 129 exec q{--NEWALIASES--}, q{--NEWALIASES_ARG--}; 130 } else { 131 exec q{--NEWALIASES--}; 132 } 133} elsif ($aliases_program eq 'postalias') { 134 $log->syslog('debug2', 'Executing "%s %s:%s"', 135 q{--POSTALIAS--}, $aliases_db_type, $aliases_file); 136 137 exec q{--POSTALIAS--}, "$aliases_db_type:$aliases_file"; 138} elsif ($aliases_program eq 'postmap') { 139 $log->syslog('debug2', 'Executing "%s %s:%s"', 140 q{--POSTMAP--}, $aliases_db_type, $aliases_file); 141 142 exec q{--POSTMAP--}, "$aliases_db_type:$aliases_file"; 143} elsif ($aliases_program eq 'none') { 144 $log->syslog('debug2', 'Skipping execution of aliases_program'); 145 exit 0; 146} else { 147 $log->syslog('err', 'Invalid aliases_program "%s"', $aliases_program); 148 exit 1; 149} 150 151my $errno = $ERRNO; 152$log->syslog('err', 'Cannot execute aliases_program "%s": %m', 153 $aliases_program); 154exit($errno || 1); 155 156__END__ 157 158=encoding utf-8 159 160=head1 NAME 161 162sympa_newaliases, sympa_newaliases.pl - Alias database maintenance 163 164=head1 SYNOPSIS 165 166 sympa_newaliases.pl --domain=dom.ain 167 168=head1 DESCRIPTION 169 170F<sympa_newaliases.pl> is a program to maintain alias database. 171 172It is typically invoked from 173L<Sympa::Aliases::Template> module via sympa_newaliases-wrapper, 174then updates alias database. 175 176=head1 OPTIONS 177 178F<sympa_newaliases.pl> may run with following options. 179 180=over 181 182=item C<--domain=>I<domain> 183 184Name of virtual robot on which aliases will be updated. 185 186=item C<-h>, C<--help> 187 188Print this help message. 189 190=back 191 192=head1 CONFIGURATION PARAMETERS 193 194Following site configuration parameters in F<--CONFIG--> will be referred. 195They may be overridden by robot.conf of each virtual robot. 196 197=over 198 199=item sendmail_aliases 200 201Source text of alias database. 202 203Default value is F<$SENDMAIL_ALIASES>. 204 205=item aliases_program 206 207System command to update alias database. 208Possible values are: 209 210=over 211 212=item C<makemap> 213 214Sendmail makemap utility. 215 216=item C<newaliases> 217 218L<newaliases(1)> or compatible utility. 219 220=item C<postalias> 221 222Postfix L<postalias(1)> utility. 223 224=item C<postmap> 225 226Postfix L<postmap(1)> utility. 227 228=item Full path 229 230Full path to executable file. 231File will be invoked with the value of C<sendmail_aliases> as an argument. 232 233=back 234 235Default value is C<newaliases>. 236 237=item aliases_db_type 238 239Type of alias database. 240This is meaningful when value of C<aliases_program> parameter is 241C<makemap>, C<postalias> or C<postmap>. 242 243Possible values will be vary by system commands. 244For example, C<postalias> and C<postmap> can support any of 245C<btree>, C<cdb>, C<dbm>, C<hash> and C<sdbm>. 246 247Default value is C<hash>. 248 249=back 250 251=head1 RETURN VALUE 252 253Returns with exit code 0. 254If invoked system command failed, returns with its exit code. 255On other failures, returns with 1. 256 257=head1 FILES 258 259=over 260 261=item F<--CONFIG--> 262 263Sympa site configuration. 264 265=item F<$LIBEXECDIR/sympa_newaliases-wrapper> 266 267Set UID wrapper for sympa_newaliases.pl. 268 269=back 270 271=head1 HISTORY 272 273sympa_newaliases.pl appeared on Sympa 6.1.18. 274It was initially written by 275IKEDA Soji <ikeda@conversion.co.jp>. 276 277=head1 SEE ALSO 278 279L<Sympa::Aliases::Template>. 280 281=cut 282