On Mon, 2003-04-21 at 02:15, Aaron Stone wrote:
> Interestingly, it is also the exact place where my LDAP patch needs to
> hook in to create the INBOX for a user who does not have one yet (ie it's
> their first email since the account was created in the LDAP directory).
> You probably have a similar issue if a mailbox is specified for a filter
> rule but does not exist yet.

Nope. The SELECT statement I use makes an implicit INNER JOIN between
filters and mailboxes, making sure that the mailbox exists, otherwise
the row won't be returned.

> With the filters applied higher up on the delivery chain, they can also be
> used to generate bounces, forwards or call external programs.

This would be nice. So what you mean is that the filters table should
have an owner_idnr field and a deliver_to field, replacing the
mailbox_idnr field it has now. The code to scan for filters probably
belongs around the call to auth_check_user (which should be renamed to
auth_check_alias IMHO), as it needs to be called recursively.

For example, if Alice has a filter forwarding some mail to Bob, the
final destination will be resolved like this:
   alias   ([EMAIL PROTECTED])
 -> userid  (5)
 -> filter  (mail that belongs to bob)
 -> alias   ([EMAIL PROTECTED])
 -> userid  (6)
 -> filter  (no filters match)
 -> mailbox (INBOX)

Numbers in filters.deliver_to point to mailboxes while numbers in
aliases.deliver_to point to userids. To handle this I propose a
resolve_alias() function for pipe.c. Here's my idea, in pseudo code:

/* Returns a string describing either an external forward or a mailbox id */
string resolve_alias(string deliver_to, const char *headers)
{
  while (1) {
    deliver_to = auth_check_user(deliver_to);
    if (!deliver_to)
      deliver_to = auth_check_user(strchr(deliver_to, '@'));

    if (is_numeric(deliver_to)) {
      /* a userid was returned and must be resolved to a mailboxid */
      string filter_destination = db_check_filters(deliver_to, headers);

      if (filter_destination) {
        /* a filter matched, returning either a mailboxid or an alias */
        if (is_numeric(filter_destination))
          return filter_destination;
        else
          deliver_to = filter_destination;

      } else {
        /* no filters matched, default to INBOX */
        return db_create_and_get_inbox(deliver_to);
      }
    } else {
      return deliver_to;
    }
  }
}

> If you're interested, I'm working on a Sieve based solution. The project
> has quite a bit of steps involved; I'm at about step 3 of 2349058725. I'd
> be happy to share the work on this project!

At first I also wanted a richer mail filtering language like
Sieve/procmail/maildrop, but now I think simple regexes are in many
cases better. dbmail is often used for serving large amounts of
untrusted users, and allowing them to write filters in a rich language
would slow down performance. It would also be necessary to rip out the
command execution and any possibilities for writing infinite loops in
those languages to avoid security problems.

Also, I found that my entire .procmailrc could be represented with
simple regexes. I think that's the case for 95% of dbmail users (users,
not admins).

> Really nice patch, though! For those who need filtering yesterday (umm,
> me...) and in case the Sieve project tanks, this looks great.

Of course, the two solutions can coexist if/when you finish your
libsieve project.

BTW, I'll be offline until Friday.

-- 
Jonas Jensen <[EMAIL PROTECTED]>

Reply via email to