On 02/26/12 12:36 -0500, Brian J. Murrell wrote:
Subject might be a bit misleading but here is the problem... I have a cyrus imap server serving a userbase. Of course with any mail system comes the issue of handling spam. My users each have two folders in their account: "Junk" and "Not Junk" where they put their spam and mis-identifed spam. On the imap server each user has a system (i.e. linux) account complete with a SpamAssassin configuration including bayesian classification database, etc. so that each user has their own database of what's spam and what isn't. That means that for each user to classify their spam/ham the "sa-learn" process has to run as their own uid. To achieve that goal, as well as timely processing of the spam and ham folders, each user has a process on the mail server running as their uid which monitors those mailboxes and processes them (and/or each user has jobs run from their cron to periodically do the same). The question comes now, how can I have a master process which spawns all of these per-user threads/processes give them some sort of credential that allows them to get access to their imap account, without storing a list of accounts/passwords in a file that would need to keep synchronized with their system passwords (not to mention the security nightmare it would be to store account passwords in plaintext). FWIW, this configuration is Kerberos authenticated/authorized.
Hiemdal KCM should be able to handle renewing kerberos credentials for your users. Another option would be to utilize SASL EXTERNAL authentication to authenticate your users, locally, based on peercred. Cyrus IMAP does not currently have support for external auth, but I'm attaching a Linux specific patch, against cyrus 2.3.12, which works for me. I'm not sure how your spam processing fits into the picture, but your spawned processes will need to function as IMAP clients, and will need to be able to select the GSSAPI or EXTERNAL SASL mechanisms to use either of the above scenarios.
Or is there some alternative interface to the cyrus imap folder mechanism (i.e. not through the IMAP protocol) that I am completely missing, that would be better suited to this problem? One possible solution I can think of that would use the IMAP protocol for all of this is to create a single IMAP account that will be given access (i.e. using cyrus' ACLs) to every users' Junk, Not Junk and INBOX folders in order to read the messages, learn them and in the case of ham, move them back to their INBOX. But before I go down this road I just want to make sure it's really the right road or if there is some alternative that I am just not recognizing yet.
-- Dan White
diff -ruN cyrus-imapd-2.3.12.pristine/imap/imapd.c cyrus-imapd-2.3.12/imap/imapd.c --- cyrus-imapd-2.3.12.pristine/imap/imapd.c 2008-04-13 10:40:29.000000000 -0500 +++ cyrus-imapd-2.3.12/imap/imapd.c 2008-04-22 23:14:20.000000000 -0500 @@ -106,6 +106,7 @@ #include "xmalloc.h" #include "xstrlcat.h" #include "xstrlcpy.h" +#include "pwd.h" #include "pushstats.h" /* SNMP interface */ @@ -715,6 +716,8 @@ char hbuf[NI_MAXHOST]; int niflags; int imapd_haveaddr = 0; + struct ucred pc; + socklen_t pclen = sizeof(pc); signals_poll(); @@ -780,8 +783,25 @@ saslprops.ipremoteport = xstrdup(remoteip); sasl_setprop(imapd_saslconn, SASL_IPLOCALPORT, localip); saslprops.iplocalport = xstrdup(localip); + } else { + if (getsockopt(0, SOL_SOCKET, SO_PEERCRED, (void *)&pc, &pclen) == 0) { + struct passwd *pw = getpwuid(pc.uid); + int result; + result = sasl_setprop(imapd_saslconn, SASL_AUTH_EXTERNAL, pw->pw_name); + if (result != SASL_OK) { + return -1; + } + if(saslprops.authid) { + free(saslprops.authid); + saslprops.authid = NULL; + } + if(pw->pw_name) { + saslprops.authid = xstrdup(pw->pw_name); + } + } } + proc_register("imapd", imapd_clienthost, NULL, NULL); /* Set inactivity timer */
---- Cyrus Home Page: http://www.cyrusimap.org/ List Archives/Info: http://lists.andrew.cmu.edu/pipermail/info-cyrus/