5 use vars qw(%aliases $opt_a);
6 use subs qw(validate_recipient process_message read_aliases);
7 use Net::Server::Mail::ESMTP;
8 use IPC::Run qw( run );
13 my $smtp = new Net::Server::Mail::ESMTP;
14 $smtp->set_callback(RCPT => \&validate_recipient);
15 $smtp->set_callback(DATA => \&process_message);
17 openlog('[_smtpd]', '', 'mail');
23 sub validate_recipient {
24 my($session, $recipient) = @_;
26 $recipient =~ s/\@.*$//;
27 return(0, 550, "Unknown user $recipient") unless exists $aliases{$recipient};
32 my($session, $data) = @_;
34 #warn "DATA: ". $$data;
36 my @recipients = $session->get_recipients();
37 return(0, 554, 'Error: no valid recipients')
41 'received '.length($$data).' bytes for '.join(',', @recipients)
43 foreach my $recipient ( @recipients ) {
45 $recipient =~ s/\@.*$//;
47 my $result = eval { run $aliases{$recipient}, $data };
49 syslog('info', "pipe command failed: $@");
50 return(0, 451, "pipe command failed: $@");
54 syslog('info', 'message piped');
55 return(1, 250, 'message piped');
62 open(ALIASES, $opt_a || '/etc/aliases' ) or die $!;
68 /^([\w\-\+\.]+):\s*("?)\|(.*)\2\s*$/ or next;
69 #$aliases{$1} = [ split(/\s+/, $3) ];
70 $aliases{$1} = [ qw(/bin/sh -c), $3 ];
77 _smtpd - UnderSMTPD, the underscore SMTP daemon
82 echo 'username: "|someprogram and args"' > /etc/aliases
85 echo "smtp stream tcp nowait mail /usr/local/bin/_smtpd" >>/etc/inetd.conf
86 echo "_smtpd: my.mail.server.ip" >>/etc/hosts.allow
87 echo "_smtpd: ALL" >>/etc/hosts.deny
89 #or add an smtp file to /etc/xinetd.d/
96 server = /usr/local/bin/_smtpd
101 This is a minimal SMTP server which only forwards mail to pipe destinations
102 in /etc/aliases. It does nothing else. Its intended function is on an
103 internal mail server that forwards mail to other programs on a per address
106 UnderSMTPD reads /etc/aliases for usernames; if a match is identified
107 the message is piped to the given program. Any problems executing the program
108 will cause a temporary SMTP error to be returned to the connecting client.
110 Other kinds of aliases are not recognized and cause a permanent SMTP error
111 to be returned to the connecting client, as do usernames not found in
114 UnderSMTPD was originally written to be used with the Request Tracker ticketing
117 UnderSMTPD uses Net::Server::Mail to do all the hard work.
123 =item -a filename: Alternate aliases file
127 =head1 ALIASES FORMAT
129 username: |program and args
130 username: "|program and args"
132 Quotes are not necessary around the pipe symbol, program and arguments but are
133 stripped if present. Line continuations are not supported.
135 =head1 RT ALIASES EXAMPLE
137 support: |/opt/rt3/bin/rt-mailgate --queue support --action correspond --url http://rt.example.com/
138 billing: |/opt/rt3/bin/rt-mailgate --queue billing --action correspond --url http://rt.example.com/
146 Ivan Kohler <ivan-undersmtpd@420.am>