+1. I have something in testing, but since I cannot seem to get the connection object from within the transaction, it is going to mean deprecating the $transaction->relaying() piece altogether and just leap for the jugular. All custom plugins which relying on $transaction->relaying() will have to get rewritten...
Not so fast, John! ;)
OK, this is what I have working and I think I will check it in tomorrow morning after some more testing:
1) plugins/check_relay is now a check plugin and should run just after early_talker (or so); it sets the $connection->{_relay_client} variable to 1 iff the IP address is in the relayclients config file and then it returns DECLINED.
2) Qpsmtpd/Connection.pm now includes a relay_client() method (guess what that does ;).
3) Qpsmtpd/SMTP.pm now sets the $transaction->relaying() to the same value as whatever the $connection->relay_client returns (so existing plugins don't need to change). Smart plugin writers will use the $connection->relay_client() directly.
4) plugins/rcpt_ok is designed to run last of all the rcpt plugins and will check rcpthosts (and morercpthosts). If $connection->relay_client is true at this point, rcpt_ok will return OK, otherwise DENY. The reason for this is that the upstream plugins should return OK/DENY only if whatever they are testing for is true, otherwise they should normally return DECLINED. Hence, my check_finger will return OK only if the user address is valid. And check_badrcptto will only return DENY if the rcpt is on the list.
John