Search code examples
perlpostfix-mtamilter

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?


Solution

  • Use below to get queue_id.

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