Based on my understanding of the milter API docs, I believe this is a
spamass-milter bug aided by confusing sendmail docs and API.

I looked at the sendmail code and did some additional milter tests.
Both confirm the root cause: The "$b" macro is not necessarily updated
the when the first envrcpt milter call is made.

Experimenting with the "$p" macro was enlightening.  This is supposed to
be the current pid.  Both "$b" and "$p" macros are set by initsys() in
envelope.c.  But "$p" is always unset the first time the milter envrcpt
is called.  If the mail has multiple recipients, then the "$p" macro
will be correct for the remaining envrcpt calls.  And so will the "$b"
macro.

The reason is obvious from the sendmail/srvrsmtp.c smtp() function:


                                response = milter_envrcpt(args, e, &state,
                                                        Errors > 0);
                                milter_cmd_done = true;
                                MILTER_REPLY("to");
                        }
#endif /* MILTER */

                        /* no errors during parsing, but might be a duplicate */
                        e->e_to = a->q_paddr;
                        if (!(Errors > 0) && !QS_IS_BADADDR(a->q_state))
                        {
                                if (smtp.sm_nrcpts == 0)
                                        initsys(e);
                                message("250 2.1.5 Recipient ok%s",
                                        QS_IS_QUEUEUP(a->q_state) ?
                                                " (will queue)" : "");
                                smtp.sm_nrcpts++;
                        }




So initsys(e) is called *after* the first milter_envrcpt() call.  Which
means that macros set by initsys() are generally invalid in envrcpt
context. We can obviously not depend on the mail having more than one
recipient.

The issue with the "$b" macro, making this a bit more confusing, is that
it appears to be inherited from the parent.  So it does have a value.
It's just not meaningful.  This might be a sendmail bug?

The issue could probably be fixed in sendmail by moving the initsys(e)
call in front of milter_envrcpt().  But reading the milter docs, I am
not convinced this is the "most correct" fix.  I believe the bug really
is in spamass-milter assuming that the "$b" macro value is valid at this
stage.


I base my conclusion on the smfi_getsymval() API docs saying

  The macro list can be changed using the confMILTER_MACROS_* options in
  sendmail.mc. The scopes of such macros will be determined by when they
  are set by sendmail. For descriptions of macros' values, please see
  the "Sendmail Installation and Operation Guide" provided with your
  sendmail distribution.


This makes it clear that the macro scopes are limited by when sendmail
set the macros.  It is possible to add any macro to the macro list for
any stage without considering the scope, but that's futile.

Macros which are set or updated by initsys() are outside the
milter_envrcpt scpoe and should not be added to the
confMILTER_MACROS_ENVRCPT list.  This includes the "$b" macro.



Bjørn

Attachment: signature.asc
Description: PGP signature

Reply via email to