David-SkyMesh David-SkyMesh - 3 months ago 11
Perl Question

Get Queue ID during execution of Postfix before-queue (perl) milter

Problem:

Trying to write a milter for Postfix to tie the presence of certain headers in an email to the destination IP address and TCP Port of the outbound relay host.

Following the Postfix milter guide it seems I need to implement a

before-queue
milter.

Doing so using the Sendmail::Milter perl module.

I can get at everything I need in the headers, envelope, etc except for the ultimate destination (IP and port) that it will be relayed to. Obviously that makes sense for a
before-queue
milter.

Where to get the relay information?

Looking at our Postfix logs I can see messages of the following format:

TIMESTAMP HOST postfix/qmgr[pid]: XXXXXXXXXX: log message here
TIMESTAMP HOST postfix/smtp[pid]: XXXXXXXXXX: log message here
TIMESTAMP HOST postfix/smtpd[pid]: XXXXXXXXXX: log message here


Some of the log lines have the relay information I'm looking for, i.e:

<TIMESTAMP> <HOST> postfix/smtp[pid]: XXXXXXXXXX: to=EMAIL, relay=HOST[ADDR]:PORT, ...


That
ADDR
and
PORT
is exactly what I'm looking for. The
XXXXXXXXXX
is what seems to tie it all together in the logs. I'm led to believe that this is called the 'Queue ID' or 'Job ID' depending on what you're talking about.

If I could get at that
XXXXXXXXXX
Queue/Job ID from the milter, then it'd be no problem to tie the logs together.

Tried?

It looks like I might be able to get at some vendor specific information by calling
$ctx->getsymval SYMNAME
from the callbacks.

Additional information is passed in to the vendor filter routines using symbols.
Symbols correspond closely to sendmail macros. The symbols defined depend on the
context. SYMNAME is the name of the symbol to access.

This function returns the value of the symbol name SYMNAME.


The milter guide has code like the following to get at the 'Queue ID':

/* Determine the job ID for logging. */
if (dfc->mctx_jobid == 0 || strcmp(dfc->mctx_jobid, JOBIDUNKNOWN) == 0) {
char *jobid = smfi_getsymval(ctx, "i");
if (jobid != 0)
dfc->mctx_jobid = jobid;
}


I just can't figure out if I can get at that jobid via
getsymval
(and what the
SYMNAME
might be), or via some other context method.

Any ideas?

Answer

Use below to get queue_id.

my $queue_id = $ctx->getsymval('i');