EximWhen I first heard of the requirement at a customer site that a rather large number of users must not receive mail on two days of the week my initial thoughts were unprintable but went along the lines of lunacy and WTF. (Meanwhile I know there are actually sound reasons, but I won't elaborate.) The difficulty stems from the fact that these are Lotus Notes users. It would be trivial to cut them off from SMTP deliveries for a day or two, but how to avoid a Lotus Notes user receiving messages from other Lotus Notes users? It may be possible to implement this requirement with a truckload of Domino agents, but I wouldn't really know where to start. So, once again: a number of Lotus Notes users shall not receive e-mail between early morning and late evening on two days of the week. If such a candidate is sent any message on one of these "forbidden days" (be it a Notes message from within the Lotus Notes domain or an SMTP message from the Internet), the message is to be held until the following day, at which point recipient shall receive it. (Messages must not bounce of course.) Although these users must not receive new messages, they are allowed to send an e-mail if necessary. Go figure.

An idea came up very spontaneously, that I could solve this requirement by having Domino forward messages to a holding area on these "forbidden days". Whatever type of mail arrives for a user would then be forwarded out of Domino to an Exim mail server. Once there, messages would be held until such time when they are allowed to be transferred "back" to the user. The following diagram illustrates the components involved.

What I propose to implement is a temporary forwarding on the "forbidden days" by modifying the Domino directory programmatically on those days, and having an external Exim server batch the messages until they may be delivered to the users. This is what will happen:

  • The candidate users will be assigned a particular LDAP service, say, yokmail. (Alternatively, and this is probably the better method, they're added to a Domino group -- this has the advantage that an authorized end-user can manage that group without bothering an administrator.)
  • Early in the morning of a "forbidden day", a program searches all users with that LDAP service (respectively within the group), and performs LDAP modify operations on the person documents in the Domino Directory to set a forwarding address for the user. In the Domino Directory, a forwarding address is contained in the optional mailaddress attribute type. We'll be setting the forwarding address to

    yok-username@batch.example.com

This prefix (here the string "yok-" -- you don't know what yok means? :-)) is later used to catch these particular forwards; we'll be stripping that prefix off later on in Exim. The username portion is the first userid in Domino's shortname field, a.k.a. userid.

Update: Notes (IMO erroneously) creates a To: header (not just envelope recipient) with this address. I've had to change the forwarding address to username@batch.example.com only.

  • A minute or two later (it takes a moment for the Domino router to recognize the change in the directory), Domino will begin forwarding messages to that SMTP server (Exim), irrespective of whether the message arrived via SMTP or NRPC.
  • We create a specialized Exim manualroute router that detects messages to the batch domain and routes them to a custom transport.
batched_smtp:
       driver = manualroute
       domains = batch.example.com
       transport = bsmtp_appendfile
       # local_part_prefix = yok-
       route_list = * example.com

The route_list specifies that all messages are routed to example.com: this means, that the envelope recipient address is set up correctly for later re- routing back into the system.

  • The custom transport uses the appendfile driver to store each batch message in its own file in the specified directory. ($host is set to the hostname in the route_list above -- example.com.)
bsmtp_appendfile:
       driver = appendfile
       directory = /var/spool/bsmtp/$host
       batch_max = 1000
       use_bsmtp
       user = exim
  • All messages received by Domino on a "forbidden day" are thus routed into Exim and are now happily lying in a spool directory in BSMTP format.

    • At the end of the forbidden day the forwarding address is removed in the Domino Directory, thereby effectively terminating forwarding.
    • A few minutes later (I'll give the replicators about 30 minutes to get their directories in sync), the batch of SMTP for those users is delivered (via SMTP) to the Domino server. Because the forwarding has been disabled, messages are delivered into users' mail files.
    • Delivery of the batch of messages is done via Exim, feeding each file to exim -bS, through the same Exim server. We've ensured the envelope recipient is once again username@example.com and the Exim servers now route the message to the final Domino server as though they'd never seen it before.

The whole thing is relatively trivial to implement, and we're waiting for the go-ahead, and for the powers that be to understand a few disadvantages:

  • Messages composed in Lotus Notes and sent to these users will have certain formatting removed/modified because the mail is being routed over SMTP. Tough.
  • Updating person documents in the Domino directory means that directory catalogues are rebuilt and redistributed. I think the customer can live with that.
  • If you journal your Domino servers, each message received for a user on a "forbidden day" will cause the message to be stored twice: once when it initially arrives, and the second time when Exim returns the message the next day.
  • Messages delivered to these Domino users on the "forbidden days" will effectively be delivered twice (consuming a few CPU cycles) but they'll be seen only once by the end-user.

It sounds a bit convoluted, and it is, but it ought to work nicely. Do you have a simpler, Domino only solution? If so, I'd be curious. (BTW, these are iNotes users.)

Flattr this
Mail, DomiNotes, Exim, and mailhack :: 26 Jan 2010 :: e-mail

Comments

blog comments powered by Disqus