/[smeserver]/rpms/qpsmtpd/sme8/0033-new-plugin-rcpt_map.patch
ViewVC logotype

Annotation of /rpms/qpsmtpd/sme8/0033-new-plugin-rcpt_map.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download)
Sun Nov 14 20:50:20 2010 UTC (14 years ago) by slords
Branch: MAIN
CVS Tags: qpsmtpd-0_84-3_el5_sme, qpsmtpd-0_84-6_el5_sme, qpsmtpd-0_84-2_el5_sme, qpsmtpd-0_84-5_el5_sme, qpsmtpd-0_84-8_el5_sme, qpsmtpd-0_84-9_el5_sme, qpsmtpd-0_84-4_el5_sme, qpsmtpd-0_84-7_el5_sme, HEAD
* Sun Nov 14 2010 <slords@mail.com> 0.84-2.sme
- Sync with upstream git repo.
- Fix require_resolvable_fromhost doesn't work [SME: 6369]
- Fix TLS security defaults [SME: 6366]
- Fix fatal errors when mail has no headers [SME: 6345]

1 slords 1.1 From 7bfad42ac9c07c2981e44a7ad891015a5bf75757 Mon Sep 17 00:00:00 2001
2     From: Hanno Hecker <vetinari@ankh-morp.org>
3     Date: Fri, 6 Mar 2009 00:27:10 +0800
4     Subject: new plugin rcpt_map
5    
6     Check recipients from a postfix style map. The valid return codes are of course
7     qpsmtpd constants. By storing the addresses in a %hash, this is much faster
8     for fixed addresses than using the rcpt_regexp plugin just with fixed strings.
9     This plugin handles only one domain per plugin instance. Use the :N suffix for
10     the plugin if you need several domains mapped.
11     ---
12     plugins/rcpt_map | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
13     1 files changed, 187 insertions(+), 0 deletions(-)
14     create mode 100644 plugins/rcpt_map
15    
16     diff --git a/plugins/rcpt_map b/plugins/rcpt_map
17     new file mode 100644
18     index 0000000..727ae7d
19     --- /dev/null
20     +++ b/plugins/rcpt_map
21     @@ -0,0 +1,187 @@
22     +
23     +=head1 NAME
24     +
25     +rcpt_map - check recipients against recipient map
26     +
27     +=head1 DESCRIPTION
28     +
29     +B<rcpt_map> reads a list of adresses, return codes and comments
30     +from the supplied config file. Adresses are compared with I<eq lc($rcpt)>.
31     +The recipient addresses are checked against this list, and if the first
32     +matches, the return code from that line and the comment are returned to
33     +qpsmtpd. Return code can be any valid plugin return code from
34     +L<Qpsmtpd::Constants>. Matching is always done case insenstive.
35     +
36     +=head1 ARGUMENTS
37     +
38     +The C<file MAP> and C<domain NAME> arguments are required. The default value of
39     +the C<default> argument is C<DENY=No_such_user.> (see below why C<_>).
40     +
41     +=over 4
42     +
43     +=item domain NAME
44     +
45     +If the recipient address does not match this domain name NAME, this plugin will
46     +return C<DECLINED>
47     +
48     +=item file MAP
49     +
50     +Use the config file as map file, format as explained below
51     +
52     +=item default CODE[=MSG]
53     +
54     +Use CODE as default return code (and return MSG as message) if a recipient
55     +was B<not> found in the map. Since we can't use spaces in MSG, every C<_>
56     +is replaced by a space, i.e. use C<DENY=User_not_found> if you want a deny
57     +message C<User not found>.
58     +
59     +=back
60     +
61     +=head1 CONFIG FILE
62     +
63     +The config file contains lines with an address, a return code and a comment,
64     +which will be returned to the sender, if the code is not OK or DECLINED.
65     +Example:
66     +
67     + # example_org_map - config for rcpt_map plugin
68     + me@example.org OK
69     + you@example.org OK
70     + info@example.org DENY User not found.
71     +
72     +=head1 NOTES
73     +
74     +We're currently running this plugin like shown in the following example.
75     +
76     +Excerpt from the C<plugins> config file:
77     +
78     + ## list of valid users, config in /srv/qpsmtpd/config/rcpt_regexp
79     + ## ... except for "*@example.org":
80     + rcpt_regexp
81     + ## only for "@example.org":
82     + rcpt_map domain example.org file /srv/qpsmtpd/config/map_example_org
83     +
84     +And the C<rcpt_regexp> config file:
85     +
86     + ### "example.org" addresses are checked later by the rcpt_map
87     + ### plugin, return DECLINED here:
88     + /^.*\@example\.org$/ DECLINED
89     + ### all other domains just check for valid users, the validity
90     + ### of the domain is checked by the rcpt_ok plugin => never use
91     + ### something else than "DENY" or "DECLINED" here!
92     + /^(abuse|postmaster)\@/ DECLINED
93     + /^(me|you)\@/ DECLINED
94     + /^.*$/ DENY No such user.
95     +
96     +=head1 COPYRIGHT AND LICENSE
97     +
98     +Copyright (c) 2009 Hanno Hecker
99     +
100     +This plugin is licensed under the same terms as the qpsmtpd package itself.
101     +Please see the LICENSE file included with qpsmtpd for details.
102     +
103     +=cut
104     +
105     +use Qpsmtpd::Constants;
106     +
107     +our %map;
108     +
109     +sub register {
110     + my ($self, $qp, %args) = @_;
111     + foreach my $arg (qw(domain file default)) {
112     + next unless exists $args{$arg};
113     + if ($arg eq "default") {
114     + my ($code, $msg) = split /=/, $args{$arg};
115     + $code = Qpsmtpd::Constants::return_code($code);
116     + unless (defined $code) {
117     + $self->log(LOGERROR, "Not a valid constant for 'default' arg");
118     + die "Not a valid constant for 'default' arg";
119     + }
120     +
121     + if ($msg) {
122     + $msg =~ s/_/ /g;
123     + }
124     + else {
125     + $msg = "No such user.";
126     + }
127     +
128     + $self->{_default} = [$code, $msg];
129     + }
130     + else {
131     + $self->{"_$arg"} = $args{$arg};
132     + }
133     + }
134     +
135     + $self->{_default}
136     + or $self->{_default} = [DENY, "No such user"];
137     +
138     + $self->{_file}
139     + or die "No map file given...";
140     +
141     + $self->log(LOGDEBUG, "Using file ".$self->{_file});
142     + %map = $self->read_map(1);
143     + die "Empty map file"
144     + unless keys %map;
145     +}
146     +
147     +sub hook_pre_connection {
148     + my $self = shift;
149     + my ($time) = (stat($self->{_file}))[9] || 0;
150     + if ($time > $self->{_time}) {
151     + my %temp = $self->read_map();
152     + keys %temp
153     + or return DECLINED;
154     + %map = %temp;
155     + }
156     + return DECLINED;
157     +}
158     +
159     +sub read_map {
160     + my $self = shift;
161     + my %hash = ();
162     + open F, $self->{_file}
163     + or do { $_[0] ? die "ERROR opening: $!" : return (); };
164     +
165     + ($self->{_time}) = (stat(F))[9] || 0;
166     +
167     + my $line = 0;
168     + while (<F>) {
169     + ++$line;
170     + s/^\s*//;
171     + next if /^#/;
172     + next unless $_;
173     + my ($addr, $code, $msg) = split ' ', $_, 3;
174     + next unless $addr;
175     +
176     + unless ($code) {
177     + $self->log(LOGERROR,
178     + "No constant in line $line in ".$self->{_file});
179     + next;
180     + }
181     + $code = Qpsmtpd::Constants::return_code($code);
182     + unless (defined $code) {
183     + $self->log(LOGERROR,
184     + "Not a valid constant in line $line in ".$self->{_file});
185     + next;
186     + }
187     + $msg or $msg = "No such user.";
188     + $hash{$addr} = [$code, $msg];
189     + }
190     + return %hash;
191     +}
192     +
193     +sub hook_rcpt {
194     + my ($self, $transaction, $recipient) = @_;
195     + return (DECLINED)
196     + unless $recipient->host && $recipient->user;
197     +
198     + return (DECLINED)
199     + unless lc($recipient->host) eq $self->{_domain};
200     +
201     + my $rcpt = lc $recipient->user . '@' . lc $recipient->host;
202     + return (@{$self->{_default}})
203     + unless exists $map{$rcpt};
204     +
205     + return @{$map{$rcpt}};
206     +}
207     +
208     +# vim: ts=4 sw=4 expandtab syn=perl
209     --
210     1.7.2.2
211    

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed