]>
git.proxmox.com Git - pmg-api.git/blob - PMG/RuleCache.pm
1 package PMG
::RuleCache
;
14 my $ocache_size = 1023;
17 my ($type, $ruledb) = @_;
21 $self->{ruledb
} = $ruledb;
28 my $dbh = $ruledb->{dbh
};
30 my $sha1 = Digest
::SHA-
>new;
35 # read a consistent snapshot
36 $dbh->do("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
38 my $sth = $dbh->prepare(
39 "SELECT ID, Name, Priority, Active, Direction FROM Rule " .
41 "ORDER BY Priority DESC");
45 while (my $ref = $sth->fetchrow_hashref()) {
46 my $ruleid = $ref->{id
};
47 my $rule = PMG
::RuleDB
::Rule-
>new(
48 $ref->{name
}, $ref->{priority
}, $ref->{active
},
51 $rule->{id
} = $ruleid;
54 $sha1->add(join (',', values (%$ref)) . "|");
56 my ($from, $to, $when, $what, $action);
58 my $sth1 = $dbh->prepare(
59 "SELECT Objectgroup_ID, Grouptype FROM RuleGroup " .
60 "where RuleGroup.Rule_ID = '$ruleid' " .
61 "ORDER BY Grouptype, Objectgroup_ID");
64 while (my $ref1 = $sth1->fetchrow_hashref()) {
65 my $gtype = $ref1->{grouptype
};
66 my $groupid = $ref1->{objectgroup_id
};
68 # emtyp groups differ from non-existent groups!
70 if ($gtype == 0) { #from
71 $from = [] if !defined ($from);
72 } elsif ($gtype == 1) { # to
73 $to = [] if !defined ($to);
74 } elsif ($gtype == 2) { # when
75 $when = [] if !defined ($when);
76 } elsif ($gtype == 3) { # what
77 $what = [] if !defined ($what);
78 } elsif ($gtype == 4) { # action
79 $action = [] if !defined ($action);
82 my $sth2 = $dbh->prepare(
83 "SELECT ID FROM Object where Objectgroup_ID = '$groupid' " .
86 while (my $ref2 = $sth2->fetchrow_hashref()) {
87 my $objid = $ref2->{'id'};
88 my $obj = $self->_get_object($objid);
90 $sha1->add (join (',', $objid, $gtype, $groupid) . "|");
91 $sha1->add ($obj->{digest
}, "|");
93 if ($gtype == 0) { #from
95 } elsif ($gtype == 1) { # to
97 } elsif ($gtype == 2) { # when
99 } elsif ($gtype == 3) { # what
101 if ($obj->otype == PMG
::RuleDB
::ArchiveFilter-
>otype) {
102 if ($rule->{direction
} == 0) {
103 $self->{archivefilter_in
} = 1;
104 } elsif ($rule->{direction
} == 1) {
105 $self->{archivefilter_out
} = 1;
107 $self->{archivefilter_in
} = 1;
108 $self->{archivefilter_out
} = 1;
111 } elsif ($gtype == 4) { # action
113 $self->{"$ruleid:final"} = 1 if $obj->final();
121 $self->{"$ruleid:from"} = $from;
122 $self->{"$ruleid:to"} = $to;
123 $self->{"$ruleid:when"} = $when;
124 $self->{"$ruleid:what"} = $what;
125 $self->{"$ruleid:action"} = $action;
128 # Cache Greylist Exclusion
129 $sth = $dbh->prepare(
130 "SELECT object.id FROM object, objectgroup " .
131 "WHERE class = 'greylist' AND " .
132 "objectgroup.id = object.objectgroup_id " .
133 "ORDER BY object.id");
136 my $grey_excl_sender = ();
137 my $grey_excl_receiver = ();
138 while (my $ref2 = $sth->fetchrow_hashref()) {
139 my $obj = $self->_get_object ($ref2->{'id'});
141 if ($obj->receivertest()) {
142 push @$grey_excl_receiver, $obj;
144 push @$grey_excl_sender, $obj;
146 $sha1->add (join (',', values (%$ref2)) . "|");
147 $sha1->add ($obj->{digest
}, "|");
150 $self->{"greylist:sender"} = $grey_excl_sender;
151 $self->{"greylist:receiver"} = $grey_excl_receiver;
157 $dbh->rollback; # end transaction
159 syslog
('err', PMG
::Utils
::msgquote
("unable to load rulecache : $err")) if $err;
161 $self->{rules
} = $rules;
163 $self->{digest
} = $sha1->hexdigest;
169 my ($self, $ruleid) = @_;
171 defined($ruleid) || croak
("undefined rule id: ERROR");
173 return $self->{"$ruleid:final"};
183 my ($self, $objid) = @_;
185 my $cid = $objid % $ocache_size;
187 my $obj = $self->{ocache
}[$cid];
189 if (!defined ($obj) || $obj->{id
} != $objid) {
190 $obj = $self->{ruledb
}->load_object($objid);
191 $self->{ocache
}[$cid] = $obj;
194 $obj || croak
"unable to get object $objid: ERROR";
200 my ($self, $ruleid) = @_;
202 defined($ruleid) || croak
("undefined rule id: ERROR");
204 return $self->{"$ruleid:action"};
208 my ($self, $addr, $ip) = @_;
210 my $grey = $self->{"greylist:sender"};
212 foreach my $obj (@$grey) {
213 if ($obj->who_match ($addr, $ip)) {
221 sub greylist_match_receiver
{
222 my ($self, $addr) = @_;
224 my $grey = $self->{"greylist:receiver"};
226 foreach my $obj (@$grey) {
227 if ($obj->who_match($addr)) {
236 my ($self, $ruleid, $addr, $ip, $ldap) = @_;
238 my $from = $self->{"$ruleid:from"};
240 return 1 if !defined ($from);
242 foreach my $obj (@$from) {
243 return 1 if $obj->who_match($addr, $ip, $ldap);
250 my ($self, $ruleid, $addr, $ldap) = @_;
252 my $to = $self->{"$ruleid:to"};
254 return 1 if !defined ($to);
256 foreach my $obj (@$to) {
257 return 1 if $obj->who_match($addr, undef, $ldap);
264 my ($self, $ruleid, $time) = @_;
266 my $when = $self->{"$ruleid:when"};
268 return 1 if !defined ($when);
270 foreach my $obj (@$when) {
271 return 1 if $obj->when_match($time);
278 my ($self, $ruleid, $queue, $element, $msginfo, $dbh) = @_;
280 my $what = $self->{"$ruleid:what"};
284 # $res->{marks} is used by mark specific actions like remove-attachments
285 # $res->{$target}->{marks} is only used in apply_rules() to exclude some
286 # targets (spam blacklist and whitelist)
288 if (!defined ($what)) {
290 foreach my $target (@{$msginfo->{targets
}}) {
291 $res->{$target}->{marks
} = [];
300 foreach my $obj (@$what) {
301 if (!$obj->can('what_match_targets')) {
302 if (my $match = $obj->what_match($queue, $element, $msginfo, $dbh)) {
303 push @$marks, @$match;
308 foreach my $target (@{$msginfo->{targets
}}) {
309 $res->{$target}->{marks
} = $marks;
310 $res->{marks
} = $marks;
313 foreach my $obj (@$what) {
314 if ($obj->can ("what_match_targets")) {
316 if ($target_info = $obj->what_match_targets($queue, $element, $msginfo, $dbh)) {
317 foreach my $k (keys %$target_info) {
318 my $cmarks = $target_info->{$k}->{marks
}; # make a copy
319 $res->{$k} = $target_info->{$k};
320 push @{$res->{$k}->{marks
}}, @$cmarks if $cmarks;