bug-mailfromd
Re: [Bug-mailfromd] Postfix and mailfromd
Mehmet Tolga Avcioglu <mehmet@xxxxxxxxxxxxx> ha escrit:
> I understand. On some of our setup we need to implement a limit rather
> than a rate function like this. From what I can see in the
> documentation, that is not possible right now.
Quite on the contrary: it is possible. Remember, that mailfromd is
not a mail filter, it is a general-purpose framework that gives you
all the tools necessary to implement any filter and any mail policy.
In your case, all you need to do is design and implement a function that
will keep the message flow statistics in a database and compare
that statistics with some limit values to decide whether or not
to allow that particular message. Find attached one of possible
implementations. It may not suit exactly your needs, but it should
give you a good starting point. To use it, save the attachment to
file mesgquota.mf somewhere in your mailfromd include path[1]
and require[2] or include[3] it to your main mailfromd.rc, e.g.:
#require mesgquota
Then, in the appropriate point of your code, add something like:
if not mesgquota_limit_ok($mail_addr "-" $client_addr, interval("1 day"), 300)
tempfail 421 4.7.1 "you are out of message quota, try again later"
fi
See the comments in mesgquota.mf for more explanations.
Regards,
Sergey
[1] http://mailfromd.man.gnu.org.ua/html_node/Comments.html#IDX170
[2] http://mailfromd.man.gnu.org.ua/html_node/Comments.html#IDX172
[3] http://mailfromd.man.gnu.org.ua/html_node/Comments.html#IDX169
#pragma regex push +extended
#require safedb
string mesgquota_db "%__statedir__/mesgquota.db"
m4_dnl * To see additional diagnostics, comment out the following line *
m4_dnl * and uncomment the line below it (use M4 comment starter) *
m4_define(`mesgquota_debug')
m4_dnl m4_define(`mesgquota_debug',`echo "mesgquota \"$1\":" m4_shift($@)')
func mesgquota_limit_ok(string key, number time_int, number max_count)
returns number
do
number res /* return value: 1 if OK, 0 if over quota */
number now time() /* current time */
number count /* number of messages sent since start of interval */
number ts /* database record timestamp */
/* Get record from the database */
string record safedbget(%mesgquota_db, %key)
mesgquota_debug(%key,"record='%record'")
if %record == ""
/* Empty record: initialize it */
set ts %now
set count 1
set res 1
elif %record matches '([0-9]+) ([0-9]+)'
/* Alanyze the record */
set ts \1
set count \2 + 1
if %now - %ts < %time_int
if %count > %max_count
mesgquota_debug(%key, "is over message quota")
set res 0
else
set res 1
fi
else
/* Reset the record, start new sampling interval */
mesgquota_debug(%key, "resetting record")
set ts %now
set count 1
set res 1
fi
fi
mesgquota_debug(%key, "new record=%ts %count")
safedbput(%mesgquota_db, %key, "%ts %count")
return %res
done
#pragma regex pop