auto-import cyrus-imapd-2.2.12-1.2.fc4 on branch devel from

cyrus-imapd-2.2.12-1.2.fc4.src.rpm
This commit is contained in:
John Dennis 2005-04-15 20:24:15 +00:00
parent f607264efd
commit 38f2261a6f
44 changed files with 6199 additions and 0 deletions

View File

@ -0,0 +1,3 @@
cyrus-imapd-2.2.12.tar.gz
cyrus-imapd-README.HOWTO-recover-mailboxes.db
cyrus_sharedbackup-0.1.tar.gz

181
README.autocreate-cyrus-2.2 Normal file
View File

@ -0,0 +1,181 @@
Cyrus IMAP autocreate Inbox patch
----------------------------------
NOTE : This patch has been created at the University of Athens. For more info, as well
as more patches on Cyrus IMAPD server, please visit http://email.uoa.gr
The design of Cyrus IMAP server does not predict the automatic creation of users'
INBOX folders. The creation of a user's INBOX is considered to be an external task,
that has to be completed as part of the user e-mail account creation procedure.
Hence, to create a new e-mail account the site administrator has to
a) Include the new account in the user database for the authentication procedure
(e.g. sasldb, shadow, mysql, ldap).
b) Create the corresponding INBOX folder.
Alternatively, the user, if succesfully authenticated, may create his own INBOX folder,
as long as the configuration of the site allows it (see "autocreatequota" in imapd.conf).
Unlike what uncareful readers may think, enabling the "autocreatequota" option, doesn't
lead to the automatic INBOX folder creation by Cyrus IMAP server.
In fact, "autocreate" means that the IMAP clients are allowed to automatically create
the user INBOX.
This patch adds the functionality of automatic creation of the users' INBOX folders into
the Cyrus IMAP server. It is implemented as two features, namely the "create on login"
and "create on post".
Create on login
===============
This feauture provides automatic creation of a user's INBOX folder when all of the
following requirements are met:
i) The user has succesfully passed the authentication procedure.
ii) The user's authorization ID (typically the same as the user's
authentication ID) doesn't belong to the imap_admins or admins
accounts (see imapd.conf).
iii) The "autocreatequota" option in the imap configuration file
has been set to a non zero value.
iv) The corresponding to the user's authorizationID INBOX folder
does not exist.
The user's first login is the most typical case when all four requirements are met.
Note that if the authenticatedID is allowed to proxy to another account for which
all of the above requirements are met, the corresponding INBOX folder for that account
will be created.
Create on post
==============
This feauture provides automatic creation of a user's INBOX folder when all of the
following requirements are met.
i) An e-mail message addressed to the user has been received.
ii) The recipient is not any of the imap_admins or admins accounts.
Note that passing e-mails to admins or imap_admins accounts from
the MTA to LMTP should be avoided in any case.
iii) The recipient's INBOX does not exist.
iv) The "autocreatequota" option in the imap configuration file
has been set to a non zero value.
v) The "createonpost" option in the imap configuration file
has been switched on.
Besides the automatic creation of INBOX folder, additional functionalities are
provided:
A) Automatic creation of INBOX subfolders controlled by "autocreateinboxfolders"
configuration option. eg
autocreateinboxfolders: sent|drafts|spam|templates
B) Automatic subscription of INBOX subfolders controlled by "autosubscribeinboxfolders"
configuration option. eg
autosubscribeinboxfolders: sent|spam
Obviously, only subscription to subfolders included in the "autocreateinboxfolder"
list is meaningfull.
C) Automatic subscription to shared folders (bulletin boards). The user gets
automatically subscribed to the shared folders declared in the "autosubscribesharedfolders"
configuration option in imapd.conf.
eg autosubscribesharedfolders: public_folder | public_folder.subfolder
In order the above action to succeed, the shared folder has to pre-exist the INBOX creation
and the user must have the apropriate permissions in order to be able to subscribe to the
shared folder.
* A new config option has been added. 'autosubscribe_all_sharedfolders' is a yes/no
option. When set to yes, the user is automatically subscribed to all shared folders one
has permission to subscribe to. Please, note that when this option is set to yes, then
'autosubscribesharedfolders' option is overriden.
D) Automatic creation of a predefined default sieve script.
This is very useful when a default sieve script is used for every user. Usually, a
default anti-spam script may me be written in a file and copied to each user
sieve scripts upon the INBOX creation. The imapd.conf options that have been added
are 'autocreate_sieve_script', 'autocreate_sieve_compiledscript' and
'generate_compiled_sieve_script'.
autocreate_sieve_script configuration option refers to the full path of the file
that contains the sieve script. The default value is null and if no file is defined,
then no default script is created upon INBOX creation. (The feature is disabled)
eg autocreate_sieve_script: /etc/default_sieve_script
autocreate_sieve_compiledscript configuration option refers to the full path of the
file that contains the bytecode compiled sieve script. If this filename is defined
in imapd.conf and the file exists, then it is automatically copied in the user's sieve
directory. If it is not defined, then a bytecode sieve script gets on the fly compiled
by the daemon.
eg autocreate_sieve_compiledscript: /etc/default_sieve_script.bc
generate_compiled_sieve_script is a boolean option that triggers the compilation of the
source sieve script to bytecode sieve script. The file that the bytecode script will
be saved is pointed by autocreate_sieve_compiledscript.
Ways of compiling a sieve script :
1. Compile a sieve script using the standard sievec utility, distributed by CMU
2. Compile a sieve script using the compile_sieve utility, released by UoA. This
tool is almost identical to the sievec utility, with the difference that it
reads the input and output file from autocreate_sieve_script and
autocreate_sieve_compiledscript options in imapd.conf
3. Let cyrus create a compiled sieve script using a source script. Cyrus can be
instructed to save the compiled script any time a compiled script does not exist.
NOTES :
1. In order this functionality to work, the following requirements must have been met:
- 'sieveusehomedir' option must be 'no' in the configuration (default).
- 'sievedir' option must have a valid value.
2. Currently, this patch checks the validity of the source script while generating a
bytecode compiled script, but not the validity of the bytecode sieve script file.
The administrator should make sure that the provided files contain a valid sieve
script as well as the compiled script is updated every time the source script changes.
Issues to be considered
=======================
I) In order to use the create on post feauture one should be absolutely sure that:
a) The MTA checks the validity of the e-mail recipient before sending the e-mail to
LMTP. This is an RFC821 requirement. This usually expands to "the mta should be
able to use the account database as user mailbox database".
b) Only authorized accounts/services can talk to LMTP.
II) Especially in the case of imap logins, the current patch implementation checks
for the INBOX folder existence upon login, causing an extra mailbox lookup in most
of the cases.
A better approach would be to chase the "IMAP_MAILBOX_NONEXISTENT" error code and
check if the error is associated with an INBOX folder. However, this would mess up
Cyrus code. The way it was implemented may not have been the most performance
optimized, but it produces a much cleaner and simple patch.
Virtual Domains Support
=======================
Virtual domains are supported by all versions of the patch for cyrus-imapd-2.2.1-BETA and
later. However, it is not possible to declare different INBOX subfolders to be created or
shared folders to be subscribed to for every domain.
Things to be done
=================
1. Support MURDER architecture.
For more information and updates please visit http://email.uoa.gr/autocreate

42
README.autosievefolder Normal file
View File

@ -0,0 +1,42 @@
Cyrus IMAP autosievefolder patch
----------------------------------
NOTE : This patch has been created at the University of Athens. For more info, as well
as more patches on Cyrus IMAPD server, please visit http://email.uoa.gr
When the lmtpd daemon receives an email message prior to delivering it to the
INBOX folder of the user, checks if the user has specified sieve filters. If the
user has specified sieve filters the filters are evaluated. If the message matches
any of the filters the action that is specified in the filter is executed. If the action
is FileInto it is stored in the subfolder specified in the filter. If the
subfolder doesn't exist then the message is sent to the INBOX folder of the user.
With this patch if the folder doesn't exist AND the name of the subfolder is
specified in the autosievefolders option, OR the anysievefolder is set to
yes in the cyrus-imap configuration file then the subfolder is created and the mail
is stored there.
Check the following options of the imapd.conf file
==================================================
* anysievefolder : It must be "yes" in order to permit the autocreation of any
INBOX subfolder requested by a sieve filter, through the "fileinto" action. (default = no)
* autosievefolders : It is a "|" separated list of subfolders of INBOX that will be
automatically created, if requested by a sieve filter, through the "fileinto"
action. (default = null)
i.e. autosievefolders: Junk | Spam
WARNING: anysievefolder, takes precedence over autosievefolders . Which means that if
anysievefolder is set to "yes", cyrus will create any INBOX subfolder requested, no-matter what the value of autosievefolders is.
Things to be done
=================
1. Support cyrus wildcards in the autosievefolders option.
For more information and updates please visit http://email.uoa.gr/projects/cyrus/autosievefolder

32
batchreconstruct Normal file
View File

@ -0,0 +1,32 @@
#!/usr/bin/perl
#
# Usage: batchreconstruct inputfile
#
# Purpose: Runs the Cyrus reconstruct command on each newly-created
# Cyrus mailbox created by folderxfer
#
# Input: List of usernames, one per line
#
#$Id: batchreconstruct,v 1.1 2005/04/15 20:24:15 jdennis Exp $
#$whoami = "/usr/ucb/whoami"; # Solaris
$whoami = "/usr/bin/whoami";
$reconstruct = "/usr/lib/cyrus-imapd/reconstruct";
$cmd = "$reconstruct -r";
chop ($iam = `$whoami`);
if ($iam ne "cyrus" ) {
die "You must be cyrus to run this script!\n";
}
$users = "$ARGV[0]";
if (!$users) { die "Usage: $0 input_file\n"; }
open(MB,"$users") || die "can't open $users";
while (<MB>) {
chop;
system("$cmd user.$_");
}
close MB;

81
bsd2cyrus Normal file
View File

@ -0,0 +1,81 @@
#!/usr/bin/perl
eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}'
if $running_under_some_shell;
#
# Usage: bsd2cyrus inputfile
#
# Purpose: Maps a user's Berkeley-format mail folder names into the
# Cyrus namespace
#
# Input: List of usernames, one per line
#
# Output: Lines of the format
# username:Cyrus-mailbox-name:BSD-mailbox-name
#
#$Id: bsd2cyrus,v 1.1 2004/02/04 12:59:42 karsten Exp $
require "find.pl";
# User's subdirectory where personal mail folders are stored
# (typically $HOME/mail)
$maildir = "mail";
$inputfile = "$ARGV[0]";
if (! $inputfile) { die "Usage: $0 inputfile\n"; }
open (DATA, $inputfile) || die "can't open $inputfile";
while (<DATA>) {
chop;
($user,$pw,$uid,$gid,$quota,$cmnt,$gcos,$home) = getpwnam $_;
next if $home eq "";
&find("$home/$maildir");
}
close DATA;
foreach (@folders) {
($user,$folder) = split(/:/,$_,2);
if (! rfc822($folder) ) { next; }
@tokens = split(/\//, $folder);
$mailbox = $tokens[$#tokens];
# Sanity checks - earlier tests should have caught these.
next if ($mailbox =~ /\.gz$/); # Skip gzipped files
next if ($mailbox =~ /\.Z$/); # Skip compressed files
next if ($mailbox =~ /^\./); # Skip hidden files
# Replace "bad" characters with an underscore followed by
# the ASCII representation of the "bad" character.
$mailbox = rm_badchars($mailbox);
print "$user:user.$user.$mailbox:$folder\n";
}
sub wanted {
(($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
-f _;
if ($_ ne '.') { push @folders, "$user:$dir/$_"; }
}
sub rfc822 {
my ($file) = @_;
my ($rc) = 1;
if (-d $file || -z $file || -B $file || -x $file) {
$rc = 0;
}
return $rc;
}
sub rm_badchars {
my ($mailbox) = @_;
$mailbox =~ s/ /_040/g;
$mailbox =~ s/\!/_041/g;
$mailbox =~ s/\"/_042/g;
$mailbox =~ s/\#/_043/g;
return $mailbox;
}

26
cpmsg Normal file
View File

@ -0,0 +1,26 @@
#!/usr/bin/perl
#
# Usage: cat mailbox.txt | formail -s cpmsg
#
# where 'cpmsg' is the name of this script
#
# Purpose: Called by formail once for each mail message in a Berkeley-
# format mailbox
#
#$Id: cpmsg,v 1.1 2005/04/15 20:24:15 jdennis Exp $
$maildir = "$ARGV[0]";
if (!$maildir) { die "Usage: $0 $maildir"; }
# Formail increments this number for each message. The
# leading "0"'s must be removed (e.g. 001 becomes 1)
$filenum = ($ENV{FILENO} - 0) + 1;
open (OUTFILE,">$maildir/$filenum.");
while (<STDIN>) {
chop;
print OUTFILE "$_\015\012"; # Add CRLF to each line!
}
close OUTFILE;

34
cyrus-deliver-wrapper.c Normal file
View File

@ -0,0 +1,34 @@
/*
* Wrapper for cyrus 'deliver' to allow anyone to run it -
* I hope this is secure! Should be setgid mail.
*/
#include <stdio.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include <sysexits.h>
#ifndef LIBEXECDIR
#define LIBEXECDIR "/usr/lib/cyrus-imapd"
#endif
int main(int argc, char *argv[])
{
char *const envp[] = { NULL };
struct passwd *ent = getpwuid(getuid());
const char *uname = (ent && ent->pw_name && ent->pw_name[0])
? ent->pw_name : "anonymous";
if (argc != 2) {
fprintf(stderr, "Usage: %s mailbox\n", argv[0]);
return EX_USAGE;
}
execle(LIBEXECDIR"/deliver", "deliver", "-e",
"-a", uname, "-m", argv[1],
NULL, envp);
perror("exec "LIBEXECDIR"/deliver");
return EX_OSERR;
}

View File

@ -0,0 +1,12 @@
--- cyrus-imapd-2.1.15/imap/message.c.orig 2003-11-11 15:45:11.000000000 +0100
+++ cyrus-imapd-2.1.15/imap/message.c 2003-11-11 15:35:11.000000000 +0100
@@ -246,7 +246,8 @@
for (p = (unsigned char *)buf; *p; p++) {
if (*p == '\n') {
- if (!sawcr) r = IMAP_MESSAGE_CONTAINSNL;
+ /* Do *NOT* check for RFC compliant line breaks (bare newlines) */
+ /* if (!sawcr) r = IMAP_MESSAGE_CONTAINSNL; */
sawcr = 0;
if (blankline) {
inheader = 0;

View File

@ -0,0 +1,23 @@
--- cyrus-imapd-2.1.16/master/master.c.getrlimit 2003-12-28 17:32:46.000000000 +0100
+++ cyrus-imapd-2.1.16/master/master.c 2003-12-28 17:43:56.000000000 +0100
@@ -1208,12 +1208,10 @@
rl.rlim_cur = x;
rl.rlim_max = x;
if (setrlimit(RLIMIT_NUMFDS, &rl) < 0) {
- syslog(LOG_ERR, "setrlimit: Unable to set file descriptors limit to %ld: %m", x);
#ifdef HAVE_GETRLIMIT
if (!getrlimit(RLIMIT_NUMFDS, &rl)) {
- syslog(LOG_ERR, "retrying with %ld (current max)", rl.rlim_max);
rl.rlim_cur = rl.rlim_max;
if (setrlimit(RLIMIT_NUMFDS, &rl) < 0) {
syslog(LOG_ERR, "setrlimit: Unable to set file descriptors limit to %ld: %m", x);
@@ -1228,6 +1226,7 @@
rl.rlim_max);
}
#else
+ syslog(LOG_ERR, "setrlimit: Unable to set file descriptors limit to %ld: %m", x);
}
#endif /* HAVE_GETRLIMIT */
}

View File

@ -0,0 +1,77 @@
--- cyrus-imapd-2.1.3/lib/lock_flock.c Tue Oct 2 16:08:13 2001
+++ cyrus-imapd-2.1.3-patched/lib/lock_flock.c Tue Apr 16 09:44:58 2002
@@ -51,6 +51,10 @@
#endif
#include "lock.h"
+#include <syslog.h>
+
+/* Locking timeout parameter */
+#define MAXTIME 99
const char *lock_method_desc = "flock";
@@ -69,6 +73,18 @@
* 'failaction' is provided, it is filled in with a pointer to a fixed
* string naming the action that failed.
*
+ * Modified by jwade 4/16/2002 to work around seen file locking problem
+ * Added locking timeout parameter to allow processes that are
+ * waiting for a lock to eventually time out
+ *
+ * Calls flock() in non-blocking fashion and then retries until a
+ * maximum delay is reached or the lock succeeds.
+ *
+ * As written, uses a quadratic backoff on retries with MAXTIME being
+ * the longest interval delay. Total delay time is the sum of the squares
+ * of all integers whose square is less than MAXTIME. In the case of
+ * MAXTIME = 99 this is 0+1+4+9+16+25+36+49+64+81= 285 Seconds
+ * This time is arbitrary and can be adjusted
*/
int lock_reopen(fd, filename, sbuf, failaction)
int fd;
@@ -79,17 +95,29 @@
int r;
struct stat sbuffile, sbufspare;
int newfd;
+ int delay=0, i=0;
if (!sbuf) sbuf = &sbufspare;
- for (;;) {
- r = flock(fd, LOCK_EX);
+ for(i=0,delay=0;;) {
+ r = flock(fd, LOCK_EX|LOCK_NB);
if (r == -1) {
- if (errno == EINTR) continue;
- if (failaction) *failaction = "locking";
+ if (errno == EINTR) {
+ continue;
+ }
+ else if ((errno == EWOULDBLOCK) && (delay < MAXTIME)) {
+ syslog(LOG_DEBUG, "lock: reopen-blocked sleeping for %d on interval %d (%d, %s)" , delay, i, fd, filename);
+ sleep(delay);
+ i++;
+ delay = i*i;
+ continue;
+ }
+ if (failaction) {
+ if (delay >= MAXTIME) *failaction = "locking_timeout";
+ else *failaction = "locking";
+ }
return -1;
}
-
fstat(fd, sbuf);
r = stat(filename, &sbuffile);
if (r == -1) {
@@ -97,9 +125,7 @@
flock(fd, LOCK_UN);
return -1;
}
-
if (sbuf->st_ino == sbuffile.st_ino) return 0;
-
newfd = open(filename, O_RDWR);
if (newfd == -1) {
if (failaction) *failaction = "opening";

View File

@ -0,0 +1,14 @@
--- lib/cyrusdb_skiplist.c.orig Tue Apr 23 20:25:48 2002
+++ lib/cyrusdb_skiplist.c Wed May 8 13:49:23 2002
@@ -69,6 +69,11 @@
#define PROB (0.5)
+#ifdef __FreeBSD__
+/* #define fdatasync(fd) fsync(fd) */
+#define O_DSYNC 0
+#endif
+
/*
*
* disk format; all numbers in network byte order

View File

@ -0,0 +1,43 @@
diff -Naur cyrus-imapd-2.2.10.orig/lib/auth_unix.c cyrus-imapd-2.2.10/lib/auth_unix.c
--- cyrus-imapd-2.2.10.orig/lib/auth_unix.c Tue Sep 14 00:49:29 2004
+++ cyrus-imapd-2.2.10/lib/auth_unix.c Thu Dec 16 08:36:32 2004
@@ -48,6 +48,7 @@
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
+#include <stdio.h>
#include <ctype.h>
#include <string.h>
@@ -226,6 +227,10 @@
struct passwd *pwd;
struct group *grp;
char **mem;
+ FILE *groupcache;
+ char fnamebuf[1024];
+ const char *config_dir =
+ libcyrus_config_getstring(CYRUSOPT_CONFIG_DIR);
identifier = auth_canonifyid(identifier, 0);
if (!identifier) return 0;
@@ -242,8 +247,11 @@
pwd = getpwnam(identifier);
+ strcpy(fnamebuf, config_dir);
+ strcat(fnamebuf, "/group.cache");
+ groupcache = fopen(fnamebuf, "r");
setgrent();
- while ((grp = getgrent())) {
+ while (grp = ( (groupcache) ? fgetgrent(groupcache) : getgrent() )) {
for (mem = grp->gr_mem; *mem; mem++) {
if (!strcmp(*mem, identifier)) break;
}
@@ -256,6 +264,7 @@
}
}
endgrent();
+ if (groupcache) fclose(groupcache);
return newstate;
}

View File

@ -0,0 +1,491 @@
diff -Naur cyrus-imapd-2.2.10/imap/ctl_cyrusdb.c cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/ctl_cyrusdb.c
--- cyrus-imapd-2.2.10/imap/ctl_cyrusdb.c 2004-07-13 05:34:20.000000000 +0300
+++ cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/ctl_cyrusdb.c 2004-11-24 13:30:54.000000000 +0200
@@ -136,7 +136,7 @@
/* if it is MBTYPE_RESERVED, unset it & call mboxlist_delete */
if(!r && (mbtype & MBTYPE_RESERVE)) {
if(!r) {
- r = mboxlist_deletemailbox(name, 1, NULL, NULL, 0, 0, 1);
+ r = mboxlist_deletemailbox(name, 1, NULL, NULL, 0, 0, 1, 1);
if(r) {
/* log the error */
syslog(LOG_ERR,
diff -Naur cyrus-imapd-2.2.10/imap/ctl_mboxlist.c cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/ctl_mboxlist.c
--- cyrus-imapd-2.2.10/imap/ctl_mboxlist.c 2004-05-22 06:45:48.000000000 +0300
+++ cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/ctl_mboxlist.c 2004-11-24 13:30:54.000000000 +0200
@@ -456,7 +456,7 @@
wipe_head = wipe_head->next;
- ret = mboxlist_deletemailbox(me->mailbox, 1, "", NULL, 0, 1, 1);
+ ret = mboxlist_deletemailbox(me->mailbox, 1, "", NULL, 0, 1, 1, 1);
if(ret) {
fprintf(stderr, "couldn't delete defunct mailbox %s\n",
me->mailbox);
diff -Naur cyrus-imapd-2.2.10/imap/imapd.c cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/imapd.c
--- cyrus-imapd-2.2.10/imap/imapd.c 2004-11-18 00:29:03.000000000 +0200
+++ cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/imapd.c 2004-11-24 13:30:54.000000000 +0200
@@ -3725,7 +3725,7 @@
r = mboxlist_deletemailbox(name, imapd_userisadmin,
imapd_userid, imapd_authstate,
- 0, 0, 0);
+ 0, 0, 0, 1);
if(r) {
prot_printf(imapd_out, "* NO delete %s: %s\r\n",
@@ -3744,6 +3744,12 @@
char mailboxname[MAX_MAILBOX_NAME+1];
char *p;
int domainlen = 0;
+ int keepQuota = 1;
+
+ if(name && *name == '+') {
+ keepQuota = 0;
+ name++;
+ }
r = (*imapd_namespace.mboxname_tointernal)(&imapd_namespace, name,
imapd_userid, mailboxname);
@@ -3754,7 +3760,7 @@
r = mboxlist_deletemailbox(mailboxname, imapd_userisadmin,
imapd_userid, imapd_authstate, 1,
- localonly, 0);
+ localonly, 0, keepQuota);
}
/* was it a top-level user mailbox? */
@@ -4715,6 +4721,7 @@
{
int newquota = -1;
int badresource = 0;
+ int rmquota = 0;
int c;
int force = 0;
static struct buf arg;
@@ -4729,7 +4736,8 @@
if (c != ')' || arg.s[0] != '\0') {
for (;;) {
if (c != ' ') goto badlist;
- if (strcasecmp(arg.s, "storage") != 0) badresource = 1;
+ if (strcasecmp(arg.s, "remove") == 0) rmquota = 1;
+ else if (strcasecmp(arg.s, "storage") != 0) badresource = 1;
c = getword(imapd_in, &arg);
if (c != ' ' && c != ')') goto badlist;
if (arg.s[0] == '\0') goto badlist;
@@ -4766,7 +4774,10 @@
imapd_userid, mailboxname);
if (!r) {
- r = mboxlist_setquota(mailboxname, newquota, force);
+ if(!rmquota)
+ r = mboxlist_setquota(mailboxname, newquota, force);
+ else
+ r = mboxlist_unsetquota(mailboxname);
}
}
@@ -6413,7 +6424,7 @@
/* note also that we need to remember to let proxyadmins do this */
r = mboxlist_deletemailbox(mailboxname,
imapd_userisadmin || imapd_userisproxyadmin,
- imapd_userid, imapd_authstate, 0, 1, 0);
+ imapd_userid, imapd_authstate, 0, 1, 0, 1);
if(r) syslog(LOG_ERR,
"Could not delete local mailbox during move of %s",
mailboxname);
diff -Naur cyrus-imapd-2.2.10/imap/mailbox.c cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/mailbox.c
--- cyrus-imapd-2.2.10/imap/mailbox.c 2004-05-22 06:45:51.000000000 +0300
+++ cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/mailbox.c 2004-11-24 13:30:54.000000000 +0200
@@ -2117,27 +2117,7 @@
seen_delete_mailbox(mailbox);
- if (delete_quota_root && !rquota) {
- quota_delete(&mailbox->quota, &tid);
- free(mailbox->quota.root);
- mailbox->quota.root = NULL;
- } else if (!rquota) {
- /* Free any quota being used by this mailbox */
- if (mailbox->quota.used >= mailbox->quota_mailbox_used) {
- mailbox->quota.used -= mailbox->quota_mailbox_used;
- }
- else {
- mailbox->quota.used = 0;
- }
- r = quota_write(&mailbox->quota, &tid);
- if (r) {
- syslog(LOG_ERR,
- "LOSTQUOTA: unable to record free of %lu bytes in quota %s",
- mailbox->quota_mailbox_used, mailbox->quota.root);
- }
- else
- quota_commit(&tid);
- }
+ mailbox_updatequota(mailbox,NULL);
/* remove all files in directory */
strlcpy(buf, mailbox->path, sizeof(buf));
@@ -2751,3 +2731,49 @@
if (*p == '.') *p = '/';
}
}
+
+
+/* This function is used to update the quota. Can be used to replace
+ * identical parts of the code, and can be quite handy some times
+ * The tid is used in order to make possible to make the quota update
+ * being a part of a bigger transaction to the quota db */
+int mailbox_updatequota(struct mailbox *mailbox, struct txn **tid)
+{
+ int r = 0, havetid = 0;
+ struct txn **ltid = NULL;
+
+ if(tid) {
+ ltid = tid;
+ havetid = 1;
+ }
+ /* Ensure that we are locked */
+ if(!mailbox->header_lock_count) return IMAP_INTERNAL;
+
+
+ if(mailbox->quota.root) {
+ r = quota_read(&mailbox->quota, ltid, 1);
+ if( r == 0 ) {
+ if (mailbox->quota.used >= mailbox->quota_mailbox_used) {
+ mailbox->quota.used -= mailbox->quota_mailbox_used;
+ }
+ else {
+ mailbox->quota.used = 0;
+ }
+ r = quota_write(&mailbox->quota, ltid);
+ if (r) {
+ syslog(LOG_ERR,
+ "LOSTQUOTA: unable to record free of %lu bytes in quota %s",
+ mailbox->quota_mailbox_used, mailbox->quota.root);
+ }
+ else if(!havetid)
+ quota_commit(&tid);
+ }
+ /* It is not a big mistake not to have quota .. just remove from the mailbox */
+ else if ( r == IMAP_QUOTAROOT_NONEXISTENT) {
+ free(mailbox->quota.root);
+ r = 0;
+ }
+ }
+ return r;
+}
+
diff -Naur cyrus-imapd-2.2.10/imap/mailbox.h cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/mailbox.h
--- cyrus-imapd-2.2.10/imap/mailbox.h 2004-01-22 23:17:09.000000000 +0200
+++ cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/mailbox.h 2004-11-24 13:30:54.000000000 +0200
@@ -305,6 +305,8 @@
struct mailbox *mailboxp);
extern int mailbox_delete(struct mailbox *mailbox, int delete_quota_root);
+extern int mailbox_updatequota(struct mailbox *mailbox, struct txn **tid);
+
extern int mailbox_rename_copy(struct mailbox *oldmailbox,
const char *newname, char *newpath,
bit32 *olduidvalidityp, bit32 *newuidvalidityp,
diff -Naur cyrus-imapd-2.2.10/imap/mboxlist.c cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/mboxlist.c
--- cyrus-imapd-2.2.10/imap/mboxlist.c 2004-07-26 21:08:03.000000000 +0300
+++ cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/mboxlist.c 2004-11-24 13:30:54.000000000 +0200
@@ -93,6 +93,11 @@
static int mboxlist_opensubs();
static void mboxlist_closesubs();
+static int child_cb(char *name,
+ int matchlen __attribute__((unused)),
+ int maycreate __attribute__((unused)),
+ void *rock);
+
static int mboxlist_rmquota(const char *name, int matchlen, int maycreate,
void *rock);
static int mboxlist_changequota(const char *name, int matchlen, int maycreate,
@@ -100,6 +105,7 @@
struct change_rock {
struct quota *quota;
+ struct quota *oldquota;
struct txn **tid;
};
@@ -893,9 +899,9 @@
*/
int mboxlist_deletemailbox(const char *name, int isadmin, char *userid,
struct auth_state *auth_state, int checkacl,
- int local_only, int force)
+ int local_only, int force, int keepQuota)
{
- int r;
+ int r, has_children = 0;
char *acl;
long access;
struct mailbox mailbox;
@@ -907,6 +913,7 @@
int deleteright = get_deleteright();
const char *p;
mupdate_handle *mupdate_h = NULL;
+ char *quotaroot = NULL;
if(!isadmin && force) return IMAP_PERMISSION_DENIED;
@@ -1018,13 +1025,44 @@
if ((r && !force) || isremote) goto done;
- if (!r || force) r = mailbox_delete(&mailbox, deletequotaroot);
+ if (!r || force) {
+ /* first we have to keep the previous quota root in order to delete it */
+ if(mailbox.quota.root)
+ quotaroot = xstrdup(mailbox.quota.root);
+ r = mailbox_delete(&mailbox, deletequotaroot);
+ }
/*
* See if we have to remove mailbox's quota root
*/
- if (!r && mailbox.quota.root != NULL) {
+ if (!r && quotaroot != NULL) {
/* xxx look for any other mailboxes in this quotaroot */
+ /* If we have not asked to remove the quota (default behaviour), we check
+ * whether there are any subfolders beneeth the quota root. If there aren't
+ * any subfolders the reasonable thing is to delete the quota */
+ if(keepQuota) {
+ char pattern[MAX_MAILBOX_PATH+1];
+ strlcpy(pattern, quotaroot, sizeof(pattern));
+ if (config_virtdomains && name[strlen(name)-1] == '!') {
+ strlcat(pattern, "*", sizeof(pattern));
+ }
+ else {
+ strlcat(pattern, ".*", sizeof(pattern));
+ }
+ /* find if there are subfolders. Then we want to
+ * keep the existing quota */
+ mboxlist_findall(NULL, pattern, isadmin, userid,
+ auth_state, child_cb, (void *) &has_children);
+
+ if(!has_children)
+ if(!mboxlist_mylookup(quotaroot, NULL, NULL, NULL, NULL, NULL, 0 ))
+ has_children = 1;
+ }
+ /* If we want to remove the quota explicitely or the quota root folder has no subfolders
+ * we execute the rmquota patch */
+ if(!keepQuota || !has_children )
+ mboxlist_unsetquota(quotaroot);
+ free(quotaroot);
}
done:
@@ -2357,6 +2395,7 @@
if (r) return r;
crock.quota = &quota;
+ crock.oldquota = NULL;
crock.tid = &tid;
/* top level mailbox */
if(have_mailbox)
@@ -2375,17 +2414,21 @@
*/
int mboxlist_unsetquota(const char *root)
{
+ char newquota[MAX_MAILBOX_PATH+1];
char pattern[MAX_MAILBOX_PATH+1];
struct quota quota;
- int r=0;
+ struct change_rock crock;
+ int r=0, k=0;
if (!root[0] || root[0] == '.' || strchr(root, '/')
|| strchr(root, '*') || strchr(root, '%') || strchr(root, '?')) {
return IMAP_MAILBOX_BADNAME;
}
+
+ crock.tid=NULL;
quota.root = (char *) root;
- r = quota_read(&quota, NULL, 0);
+ r = quota_read(&quota, crock.tid, 0);
if (r == IMAP_QUOTAROOT_NONEXISTENT) {
/* already unset */
return 0;
@@ -2402,13 +2445,45 @@
}
else
strlcat(pattern, ".*", sizeof(pattern));
-
- /* top level mailbox */
- mboxlist_rmquota(root, 0, 0, (void *)root);
- /* submailboxes - we're using internal names here */
- mboxlist_findall(NULL, pattern, 1, 0, 0, mboxlist_rmquota, (void *)root);
- r = quota_delete(&quota, NULL);
+ r = quota_delete(&quota, crock.tid);
+
+ /* If we cannot delete the quota then abort the operation */
+ if(!r) {
+ /* quota_findroot performs several checks that we can
+ * assume that are already done, and don't have to perform
+ * them again. One of them is that it returns 1 only if
+ * quotaroot exists.
+ */
+ if(quota_findroot(newquota, sizeof(newquota), root)) {
+ struct quota rootquota;
+ rootquota.root = newquota;
+ k = quota_read(&rootquota, crock.tid, 0);
+ if (!k) {
+ crock.quota = &rootquota;
+ crock.oldquota = &quota;
+ /* top level mailbox */
+ k = mboxlist_changequota(root, 0, 0, &crock);
+ }
+ /* submailboxes - we're using internal names here */
+ if (!k)
+ k = mboxlist_findall(NULL, pattern, 1, 0, 0, mboxlist_changequota, &crock);
+ if(!k)
+ k = quota_write(&rootquota, crock.tid);
+
+ }
+ else {
+ /* top level mailbox */
+ mboxlist_rmquota(root, 0, 0, (void *)root);
+ /* submailboxes - we're using internal names here */
+ mboxlist_findall(NULL, pattern, 1, 0, 0, mboxlist_rmquota, (void *)root);
+ }
+ }
+
+ if(!r && !k)
+ quota_commit(crock.tid);
+ else
+ quota_abort(crock.tid);
return r;
}
@@ -2506,6 +2581,7 @@
struct mailbox mailbox;
struct change_rock *crock = (struct change_rock *) rock;
struct quota *mboxlist_newquota = crock->quota;
+ struct quota *mboxlist_oldquota = crock->oldquota;
struct txn **tid = crock->tid;
assert(rock != NULL);
@@ -2523,27 +2599,24 @@
if (r) goto error;
if (mailbox.quota.root) {
- if (strlen(mailbox.quota.root) >= strlen(mboxlist_newquota->root)) {
- /* Part of a child quota root */
- mailbox_close(&mailbox);
- return 0;
- }
-
- r = quota_read(&mailbox.quota, tid, 1);
- if (r) goto error;
- if (mailbox.quota.used >= mailbox.quota_mailbox_used) {
- mailbox.quota.used -= mailbox.quota_mailbox_used;
- }
- else {
- mailbox.quota.used = 0;
- }
- r = quota_write(&mailbox.quota, tid);
- if (r) {
- syslog(LOG_ERR,
- "LOSTQUOTA: unable to record free of %lu bytes in quota %s",
- mailbox.quota_mailbox_used, mailbox.quota.root);
- }
- free(mailbox.quota.root);
+ if(mboxlist_oldquota) {
+ if (strlen(mailbox.quota.root) > strlen(mboxlist_oldquota->root)) {
+ /* Part of a child quota root */
+ mailbox_close(&mailbox);
+ return 0;
+ }
+ }
+ else {
+ if (strlen(mailbox.quota.root) >= strlen(mboxlist_newquota->root)) {
+ /* Part of a child quota root */
+ mailbox_close(&mailbox);
+ return 0;
+ }
+ }
+
+ r = mailbox_updatequota(&mailbox,tid);
+ if (r)
+ goto error;
}
mailbox.quota.root = xstrdup(mboxlist_newquota->root);
@@ -2553,18 +2626,24 @@
mboxlist_newquota->used += mailbox.quota_mailbox_used;
mailbox_close(&mailbox);
return 0;
-
+
error:
mailbox_close(&mailbox);
+ syslog(LOG_ERR, "LOSTQUOTA: unable to change quota root for %s to %s: %s. \
+ Command aborted. Run reconstruct to make sure mailboxes \
+ are in consistent state",
+ name, mboxlist_newquota->root, error_message(r));
+ return 1;
error_noclose:
syslog(LOG_ERR, "LOSTQUOTA: unable to change quota root for %s to %s: %s",
- name, mboxlist_newquota->root, error_message(r));
+ name, mboxlist_newquota->root, error_message(r));
/* Note, we're a callback, and it's not a huge tragedy if we
* fail, so we don't ever return a failure */
return 0;
}
+
/* must be called after cyrus_init */
void mboxlist_init(int myflags)
{
diff -Naur cyrus-imapd-2.2.10/imap/mboxlist.h cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/mboxlist.h
--- cyrus-imapd-2.2.10/imap/mboxlist.h 2004-03-17 20:07:49.000000000 +0200
+++ cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/mboxlist.h 2004-11-24 13:30:54.000000000 +0200
@@ -122,7 +122,7 @@
* the planet */
int mboxlist_deletemailbox(const char *name, int isadmin, char *userid,
struct auth_state *auth_state, int checkacl,
- int local_only, int force);
+ int local_only, int force, int keepQuota);
/* Rename/move a mailbox (hierarchical) */
int mboxlist_renamemailbox(char *oldname, char *newname, char *partition,
diff -Naur cyrus-imapd-2.2.10/imap/mupdate.c cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/mupdate.c
--- cyrus-imapd-2.2.10/imap/mupdate.c 2004-05-29 08:18:21.000000000 +0300
+++ cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/mupdate.c 2004-11-24 13:30:54.000000000 +0200
@@ -2191,7 +2191,7 @@
remote_boxes.head = r->next;
} else if (ret < 0) {
/* Local without corresponding remote, delete it */
- mboxlist_deletemailbox(l->mailbox, 1, "", NULL, 0, 0, 0);
+ mboxlist_deletemailbox(l->mailbox, 1, "", NULL, 0, 0, 0, 1);
local_boxes.head = l->next;
} else /* (ret > 0) */ {
/* Remote without corresponding local, insert it */
@@ -2206,7 +2206,7 @@
if(l && !r) {
/* we have more deletes to do */
while(l) {
- mboxlist_deletemailbox(l->mailbox, 1, "", NULL, 0, 0, 0);
+ mboxlist_deletemailbox(l->mailbox, 1, "", NULL, 0, 0, 0, 1);
local_boxes.head = l->next;
l = local_boxes.head;
}
diff -Naur cyrus-imapd-2.2.10/imap/nntpd.c cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/nntpd.c
--- cyrus-imapd-2.2.10/imap/nntpd.c 2004-09-09 19:21:26.000000000 +0300
+++ cyrus-imapd-2.2.10.rmquota+deletemailbox.uncompiled/imap/nntpd.c 2004-11-24 13:30:54.000000000 +0200
@@ -3234,7 +3234,7 @@
/* XXX should we delete right away, or wait until empty? */
r = mboxlist_deletemailbox(mailboxname, 0,
- newsmaster, newsmaster_authstate, 1, 0, 0);
+ newsmaster, newsmaster_authstate, 1, 0, 0, 1);
return r;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,193 @@
diff -Naur cyrus-imapd-2.2.12/README.autosievefolder cyrus-imapd-2.2.12-autosieve.uncompiled/README.autosievefolder
--- cyrus-imapd-2.2.12/README.autosievefolder 1970-01-01 02:00:00 +0200
+++ cyrus-imapd-2.2.12-autosieve.uncompiled/README.autosievefolder 2005-02-15 13:59:51 +0200
@@ -0,0 +1,42 @@
+Cyrus IMAP autosievefolder patch
+----------------------------------
+
+NOTE : This patch has been created at the University of Athens. For more info, as well
+as more patches on Cyrus IMAPD server, please visit http://email.uoa.gr
+
+
+ When the lmtpd daemon receives an email message prior to delivering it to the
+INBOX folder of the user, checks if the user has specified sieve filters. If the
+user has specified sieve filters the filters are evaluated. If the message matches
+any of the filters the action that is specified in the filter is executed. If the action
+is FileInto it is stored in the subfolder specified in the filter. If the
+subfolder doesn't exist then the message is sent to the INBOX folder of the user.
+
+ With this patch if the folder doesn't exist AND the name of the subfolder is
+specified in the autosievefolders option, OR the anysievefolder is set to
+yes in the cyrus-imap configuration file then the subfolder is created and the mail
+is stored there.
+
+
+Check the following options of the imapd.conf file
+==================================================
+
+* anysievefolder : It must be "yes" in order to permit the autocreation of any
+INBOX subfolder requested by a sieve filter, through the "fileinto" action. (default = no)
+* autosievefolders : It is a "|" separated list of subfolders of INBOX that will be
+automatically created, if requested by a sieve filter, through the "fileinto"
+action. (default = null)
+ i.e. autosievefolders: Junk | Spam
+
+WARNING: anysievefolder, takes precedence over autosievefolders . Which means that if
+anysievefolder is set to "yes", cyrus will create any INBOX subfolder requested, no-matter what the value of autosievefolders is.
+
+
+Things to be done
+=================
+
+1. Support cyrus wildcards in the autosievefolders option.
+
+
+For more information and updates please visit http://email.uoa.gr/projects/cyrus/autosievefolder
+
diff -Naur cyrus-imapd-2.2.12/imap/lmtp_sieve.c cyrus-imapd-2.2.12-autosieve.uncompiled/imap/lmtp_sieve.c
--- cyrus-imapd-2.2.12/imap/lmtp_sieve.c 2004-06-01 16:47:16 +0300
+++ cyrus-imapd-2.2.12-autosieve.uncompiled/imap/lmtp_sieve.c 2005-02-15 13:59:51 +0200
@@ -72,6 +72,8 @@
#include "util.h"
#include "version.h"
#include "xmalloc.h"
+#include "imap_err.h"
+
static int sieve_usehomedir = 0;
static const char *sieve_dir = NULL;
@@ -98,6 +100,9 @@
int quotaoverride,
int acloverride);
+static int autosieve_subfolder(char *userid, struct auth_state *auth_state,
+ char *subfolder, struct namespace *namespace);
+
static char *make_sieve_db(const char *user)
{
static char buf[MAX_MAILBOX_PATH+1];
@@ -312,6 +317,7 @@
}
+
static int sieve_redirect(void *ac,
void *ic __attribute__((unused)),
void *sc, void *mc, const char **errmsg)
@@ -444,7 +450,18 @@
sd->username, mdata->notifyheader,
namebuf, quotaoverride, 0);
}
-
+ if (ret == IMAP_MAILBOX_NONEXISTENT) {
+ /* if "plus" folder under INBOX, then try to create it */
+ syslog(LOG_DEBUG, "calling autosieve folder for : %s", namebuf);
+ ret = autosieve_subfolder((char *) sd->username, sd->authstate, namebuf, mdata->namespace);
+
+ if (!ret)
+ ret = deliver_mailbox(md->data, mdata->stage, md->size,
+ fc->imapflags->flag, fc->imapflags->nflags,
+ (char *) sd->username, sd->authstate, md->id,
+ sd->username, mdata->notifyheader,
+ namebuf, quotaoverride, 0);
+ }
if (!ret) {
snmp_increment(SIEVE_FILEINTO, 1);
return SIEVE_OK;
@@ -882,3 +899,77 @@
return r;
}
+
+
+#define SEP '|'
+
+static int autosieve_subfolder(char *userid, struct auth_state *auth_state,
+ char *subfolder, struct namespace *namespace)
+{
+ char option_name_external[MAX_MAILBOX_NAME + 1];
+ char option_name_internal[MAX_MAILBOX_NAME + 1];
+ const char *subf ;
+ char *p, *q, *next_subf;
+ int len, r = 0;
+ int createsievefolder = 0;
+
+ /* Check if subfolder or userid are NULL */
+ if(subfolder == NULL || userid == NULL)
+ return IMAP_MAILBOX_NONEXISTENT;
+
+ if (config_getswitch(IMAPOPT_ANYSIEVEFOLDER))
+ createsievefolder = 1;
+ else if ((subf = config_getstring(IMAPOPT_AUTOSIEVEFOLDERS)) != NULL) {
+ /* Roll through subf */
+ next_subf = (char *) subf;
+ while (*next_subf) {
+ for (p = next_subf ; isspace((int) *p) || *p == SEP ; p++);
+ for (next_subf = p ; *next_subf && *next_subf != SEP ; next_subf++);
+ for (q = next_subf ; q > p && (isspace((int) *q) || *q == SEP || !*q); q--);
+
+ if (!*p) continue;
+
+ len = q - p + 1;
+ /*
+ * This is a preliminary length check based on the assumption
+ * that the *final* internal format will be something
+ * like user.userid.subfolder(s).
+ */
+ if (len > sizeof(option_name_external) - strlen(userid) - 5)
+ return IMAP_MAILBOX_BADNAME;
+
+ strlcpy(option_name_external, namespace->prefix[NAMESPACE_INBOX], sizeof(option_name_external));
+ strncat(option_name_external, p, len);
+
+ /*
+ * Transform the option folder name to internal namespace and compare it
+ * with what must be created.
+ */
+ r = namespace->mboxname_tointernal(namespace, option_name_external, userid, option_name_internal);
+ if (r) continue;
+
+ if (!strcmp(option_name_internal, subfolder)) {
+ createsievefolder = 1;
+ break;
+ }
+ }
+ }
+
+ if (createsievefolder) {
+ /* Folder is already in internal namespace format */
+ r = mboxlist_createmailbox(subfolder, MAILBOX_FORMAT_NORMAL, NULL,
+ 1, userid, auth_state, 0, 0, 0);
+ if (!r) {
+ mboxlist_changesub(subfolder, userid, auth_state, 1, 1);
+ syslog(LOG_DEBUG, "autosievefolder: User %s, folder %s creation succeeded.",
+ userid, subfolder);
+ return 0;
+ } else {
+ syslog(LOG_ERR, "autosievefolder: User %s, folder %s creation failed. %s",
+ userid, subfolder,error_message(r));
+ return r;
+ }
+ } else
+ return IMAP_MAILBOX_NONEXISTENT;
+}
+
diff -Naur cyrus-imapd-2.2.12/lib/imapoptions cyrus-imapd-2.2.12-autosieve.uncompiled/lib/imapoptions
--- cyrus-imapd-2.2.12/lib/imapoptions 2004-07-21 22:07:45 +0300
+++ cyrus-imapd-2.2.12-autosieve.uncompiled/lib/imapoptions 2005-02-15 13:59:51 +0200
@@ -752,6 +752,15 @@
/* If enabled, lmtpd will look for Sieve scripts in user's home
directories: ~user/.sieve. */
+{ "anysievefolder", 0, SWITCH }
+/* It must be "yes" in order to permit the autocreation of any INBOX subfolder
+ requested by a sieve filter, through the "fileinto" action. (default = no) */
+
+{ "autosievefolders", NULL, STRING }
+/* It is a "|" separated list of subfolders of INBOX that will be automatically created,
+ if requested by a sieve filter, through the "fileinto" action. (default = null)
+ i.e. autosievefolders: Junk | Spam */
+
{ "singleinstancestore", 1, SWITCH }
/* If enabled, lmtpd and nntpd attempt to only write one copy of a message per
partition and create hard links, resulting in a potentially large

Binary file not shown.

View File

@ -0,0 +1,104 @@
# Small patch to Cyrus IMAP 2.2.4 which modifies \Seen state handling to
# make it compatible with Outlook Express. OE makes two connections to a
# given mailfolder: one generates indexes while the other fetches messages.
# Unfortunately it gets confused if \Seen updates caused by the message
# stream aren't immediately flushed and picked up by the index stream.
#
# This patch is a 2.2.4 port from the patch found here:
# http://www-uxsup.csx.cam.ac.uk/~dpc22/cyrus/patches/2.1.16/OutLookExpress-seenstate.patch
#
diff -Naur cyrus-imapd-2.2.4.orig/imap/imapd.c cyrus-imapd-2.2.4/imap/imapd.c
--- cyrus-imapd-2.2.4.orig/imap/imapd.c Thu May 6 20:46:21 2004
+++ cyrus-imapd-2.2.4/imap/imapd.c Fri May 21 02:10:25 2004
@@ -3063,6 +3063,10 @@
snprintf(mytime, sizeof(mytime), "%2.3f",
(clock() - start) / (double) CLOCKS_PER_SEC);
+ /* Checkpoint \Seen immediately after each FETCH completes. Checks for
+ * changes from other processes at the same time */
+ index_check_existing(imapd_mailbox, usinguid, 1);
+
if (r) {
prot_printf(imapd_out, "%s NO %s (%s sec)\r\n", tag,
error_message(r), mytime);
@@ -3184,7 +3188,7 @@
index_fetch(imapd_mailbox, msgno, 0, &fetchargs, &fetchedsomething);
- index_check(imapd_mailbox, 0, 0);
+ index_check_existing(imapd_mailbox, 0, 1);
if (fetchedsomething) {
prot_printf(imapd_out, "%s OK %s\r\n", tag,
@@ -3321,7 +3325,9 @@
flag, nflags);
if (usinguid) {
- index_check(imapd_mailbox, 1, 0);
+ index_check(imapd_mailbox, 1, 1); /* Check \Seen too */
+ } else {
+ index_check_existing(imapd_mailbox, 0, 1);
}
if (r) {
diff -Naur cyrus-imapd-2.2.4.orig/imap/imapd.h cyrus-imapd-2.2.4/imap/imapd.h
--- cyrus-imapd-2.2.4.orig/imap/imapd.h Wed Oct 22 20:50:07 2003
+++ cyrus-imapd-2.2.4/imap/imapd.h Fri May 21 02:06:02 2004
@@ -233,6 +233,8 @@
extern void index_operatemailbox(struct mailbox *mailbox);
extern void index_check(struct mailbox *mailbox, int usinguid,
int checkseen);
+extern void
+index_check_existing(struct mailbox *mailbox, int usinguid, int checkseen);
extern void index_checkseen(struct mailbox *mailbox, int quiet,
int usinguid, int oldexists);
diff -Naur cyrus-imapd-2.2.4.orig/imap/index.c cyrus-imapd-2.2.4/imap/index.c
--- cyrus-imapd-2.2.4.orig/imap/index.c Wed Apr 21 19:40:48 2004
+++ cyrus-imapd-2.2.4/imap/index.c Fri May 21 02:06:02 2004
@@ -425,6 +425,45 @@
}
}
+/* Nasty hack to report system + user flags updates without checking for
+ * new mail or expunge (relies on index atomic rewrite+rename for expunge).
+ *
+ * Needed to keep Outlook Express happy without breaking IMAP concurrent
+ * access regime which (quite correctly) prohibits unsolicited EXPUNGE and
+ * EXIST responses for non-UID versions of FETCH and STORE. Otherwise you
+ * can end up with hilarous situations such as:
+ *
+ * . FETCH 2 fast
+ * * EXPUNGE 1 <-- from concurrent session.
+ * . FETCH (data relating to previous message _3_, if it exists)
+ *
+ */
+
+void
+index_check_existing(struct mailbox *mailbox, int usinguid, int checkseen)
+{
+ int msgno, i;
+ bit32 user_flags[MAX_USER_FLAGS/32];
+
+ if (imapd_exists == -1)
+ return;
+
+ if (checkseen)
+ index_checkseen(mailbox, 0, usinguid, imapd_exists);
+
+ for (msgno = 1; msgno <= imapd_exists; msgno++) {
+ if (flagreport[msgno] < LAST_UPDATED(msgno)) {
+ for (i = 0; i < VECTOR_SIZE(user_flags); i++) {
+ user_flags[i] = USER_FLAGS(msgno, i);
+ }
+ index_fetchflags(mailbox, msgno, SYSTEM_FLAGS(msgno), user_flags,
+ LAST_UPDATED(msgno));
+ if (usinguid) prot_printf(imapd_out, " UID %u", UID(msgno));
+ prot_printf(imapd_out, ")\r\n");
+ }
+ }
+}
+
/*
* Checkpoint the user's \Seen state
*

View File

@ -0,0 +1,109 @@
diff -Naur cyrus-imapd-2.2.4.orig/doc/man/deliver.8.html cyrus-imapd-2.2.4/doc/man/deliver.8.html
--- cyrus-imapd-2.2.4.orig/doc/man/deliver.8.html Sun May 16 23:05:05 2004
+++ cyrus-imapd-2.2.4/doc/man/deliver.8.html Thu May 20 19:21:15 2004
@@ -221,13 +221,15 @@
<td width="10%"></td>
<td width="89%">
<p>Depending on the setting of <b>reject8bit</b> in
-<b>imapd.conf(5)</b>, deliver either rejects messages with
-8-bit-set characters in the headers or changes these
-characters to &lsquo;X&rsquo;. This is because such
-characters can&rsquo;t be interpreted since the character
-set is not known, although some communities not well-served
-by US-ASCII assume that those characters can be used to
-represent characters not present in US-ASCII.</p>
+<b>imapd.conf(5)</b>, deliver either rejects/accepts
+messages with 8-bit-set characters in the headers. If we
+accept messages with 8-bit-set characters in the headers,
+then depending on the setting of <b>munge8bit</b>, these
+characters are either left un-touched or changed to . This
+is because such characters can&rsquo;t be interpreted since
+the character set is not known, although some communities
+not well-served by US-ASCII assume that those characters can
+be used to represent characters not present in US-ASCII.</p>
<!-- INDENTATION -->
<p>A method for encoding 8-bit-set characters is provided by
RFC 2047.</p>
diff -Naur cyrus-imapd-2.2.4.orig/imap/message.c cyrus-imapd-2.2.4/imap/message.c
--- cyrus-imapd-2.2.4.orig/imap/message.c Fri Feb 27 18:44:55 2004
+++ cyrus-imapd-2.2.4/imap/message.c Thu May 20 19:15:23 2004
@@ -227,6 +227,7 @@
int n;
int sawcr = 0, sawnl;
int reject8bit = config_getswitch(IMAPOPT_REJECT8BIT);
+ int munge8bit = config_getswitch(IMAPOPT_MUNGE8BIT);
int inheader = 1, blankline = 1;
while (size) {
@@ -262,7 +263,7 @@
/* We have been configured to reject all mail of this
form. */
if (!r) r = IMAP_MESSAGE_CONTAINS8BIT;
- } else {
+ } else if (munge8bit) {
/* We have been configured to munge all mail of this
form. */
*p = 'X';
diff -Naur cyrus-imapd-2.2.4.orig/imap/spool.c cyrus-imapd-2.2.4/imap/spool.c
--- cyrus-imapd-2.2.4.orig/imap/spool.c Thu Mar 4 17:09:34 2004
+++ cyrus-imapd-2.2.4/imap/spool.c Thu May 20 19:16:52 2004
@@ -140,6 +140,7 @@
state s = NAME_START;
int r = 0;
int reject8bit = config_getswitch(IMAPOPT_REJECT8BIT);
+ int munge8bit = config_getswitch(IMAPOPT_MUNGE8BIT);
const char **skip = NULL;
if (namelen == 0) {
@@ -266,7 +267,7 @@
form. */
r = IMAP_MESSAGE_CONTAINS8BIT;
goto ph_error;
- } else {
+ } else if (munge8bit) {
/* We have been configured to munge all mail of this
form. */
c = 'X';
diff -Naur cyrus-imapd-2.2.4.orig/lib/imapoptions cyrus-imapd-2.2.4/lib/imapoptions
--- cyrus-imapd-2.2.4.orig/lib/imapoptions Wed May 5 20:53:09 2004
+++ cyrus-imapd-2.2.4/lib/imapoptions Thu May 20 19:15:23 2004
@@ -454,6 +454,12 @@
{ "mboxlist_db", "skiplist", STRINGLIST("flat", "berkeley", "skiplist")}
/* The cyrusdb backend to use for the mailbox list. */
+{ "munge8bit", 1, SWITCH }
+/* If enabled, lmtpd munges messages with 8-bit characters. These characters
+ are changed to . If \fBreject8bit\fR is enabled, setting \fBmunge8bit\fR
+ has no effect. (A proper soultion to non-ASCII characters in headers is
+ offered by RFC 2047 and its predecessors.) */
+
# xxx badly worded
{ "mupdate_connections_max", 128, INT }
/* The max number of connections that a mupdate process will allow, this
@@ -654,9 +660,7 @@
{ "reject8bit", 0, SWITCH }
/* If enabled, lmtpd rejects messages with 8-bit characters in the
- headers. Otherwise, 8-bit characters are changed to `X'. (A
- proper soultion to non-ASCII characters in headers is offered by
- RFC 2047 and its predecessors.) */
+ headers. */
{ "rfc2046_strict", 0, SWITCH }
/* If enabled, imapd will be strict (per RFC 2046) when matching MIME
diff -Naur cyrus-imapd-2.2.4.orig/man/deliver.8 cyrus-imapd-2.2.4/man/deliver.8
--- cyrus-imapd-2.2.4.orig/man/deliver.8 Sat May 25 21:57:47 2002
+++ cyrus-imapd-2.2.4/man/deliver.8 Thu May 20 19:15:23 2004
@@ -147,8 +147,10 @@
Accept messages using the LMTP protocol.
.SH NOTES
Depending on the setting of \fBreject8bit\fR in \fBimapd.conf(5)\fR, deliver
-either rejects messages with 8-bit-set characters in the headers or
-changes these characters to `X'.
+either rejects/accepts messages with 8-bit-set characters in the headers.
+If we accept messages with 8-bit-set characters in the headers, then depending
+on the setting of \fBmunge8bit\fR, these characters are either left un-touched
+or changed to .
This is because such characters can't be interpreted since the
character set is not known, although some communities not well-served by
US-ASCII assume that those characters can be used to represent characters not

33
cyrus-imapd-README.RPM Normal file
View File

@ -0,0 +1,33 @@
---------------
Cyrus IMAPd RPM
---------------
This is a _very_ 'quick and dirty' install howto.
The following steps should lead you to a running Cyrus IMAP server:
1) Install on a distribution which is supported by this RPM. Don't install
on a dirty system, where you have previously tried to install from source.
2) Don't install if you have a previous Cyrus IMAPd installation <=2.1.x on
your box. Upgrading any Invoca rpm based installation should be fine.
3) Make sure you understand that this RPM installs in FHS compliant
directories, like /var/lib/imap and /var/spool/imap
4) Make sure cyrus-sasl 2.x is installed.
5) Make sure saslauthd is running. If not, edit /etc/sysconfig/saslauthd as
needed and do 'chkconfig saslauthd on ; service saslauthd start'
6) Install the cyrus-imapd RPMs.
7) If it's your first install of Cyrus IMAPd, then set a password for the
cyrus user in whatever database you are using to authenticate.
8) Make sure your MTA delivers to Cyrus IMAPd, I recommend LMTP for this.
9) Start Cyrus IMAPd with 'service cyrus-imapd start'
10) Run cyradm and create a user. Usually it's something like this:
'cyradm --user=cyrus --auth=login localhost'
11) If you're using sendmail, be aware that cyrusv2.m4 included in standard
sendmail distribution uses socket /var/imap/socket/lmtp while this rpm
uses /var/lib/imap/socket/lmtp.
12) Check your syslog configuration. This RPM uses the mail facility to log
messages. On busy sites you may want to limit the mail facility to the
info priority with something like 'mail.info /var/log/maillog' in
/etc/syslog.conf.
Enjoy!

View File

@ -0,0 +1,10 @@
The programs provided here in the contrib directory are taken from
various places on the net. Sometimes I even don't know where I found
them and the license may also be unclear. If the creator of one of the
scripts doesn't like to see it included in this contrib section, let
me know and I'll remove it from the package.
I have never used any of the scripts here so I really don't know how
they work or whether there are better ways to complete a task. I've
been told that there are better tools to migrate from UW-IMAP. So be
warned, use at your own risk.

View File

@ -0,0 +1,30 @@
If you have a lot of groups or very large groups, cyrus-imapd login can become
quite slow due to the way cyrus-imapd handles groups. This may become worse
when using nss_ldap or other slow nss backends to resolve groups.
Caching using nscd can increase speed dramatically but unfortunately not for
all functions cyrus-imapd uses. nscd helps speeding up getgrnam() calls but not
getgrent() calls, which are used by cyrus-imapd to get a complete list of all
groups available.
The groupfile patch implements a quick fix to the problem by using a separate
group.cache file to speed up those operations using getgrent() calls.
Calls to getgrnam() are not touched which means that the group.cache
file must be kept in sync with the group source you are using with nss
configured in /etc/nsswitch.conf. If group.cache doesn't exist,
the patch has no effect and cyrus-imapd handles groups through getgrent().
Quick HOWTO:
- configure group lookup in /etc/nsswitch.conf if not already done
- configure name service cache in /etc/nscd.conf (not mandatory)
- start nscd with "service nscd start" (not mandatory)
- configure a service which periodically updates the group.cache file using the
upd_groupcache script. Either set up a cronjob or use a event in the cyrus
configuration.
Sample /etc/cyrus.conf event to update the group cache every 10 minutes:
EVENTS {
# some events removed here ***
...........................***
# this is only necessary if using group cache feature
groupcache cmd="upd_groupcache" period=10
}

View File

@ -0,0 +1,34 @@
--- cyrus-imapd-2.2.6/imap/message.c.acceptinvalidfrom 2004-10-30 15:03:02.220642392 -0700
+++ cyrus-imapd-2.2.6/imap/message.c 2004-10-30 15:06:01.838336352 -0700
@@ -229,6 +229,8 @@
int reject8bit = config_getswitch(IMAPOPT_REJECT8BIT);
int munge8bit = config_getswitch(IMAPOPT_MUNGE8BIT);
int inheader = 1, blankline = 1;
+ char is_from;
+ static const char * from_header = "From ";
while (size) {
n = prot_read(from, buf, size > 4096 ? 4096 : size);
@@ -294,8 +296,20 @@
/* Check for valid header name */
if (sawnl && buf[0] != ' ' && buf[0] != '\t') {
if (buf[0] == ':') return IMAP_MESSAGE_BADHEADER;
- for (p = (unsigned char *)buf; *p != ':'; p++) {
- if (*p <= ' ') return IMAP_MESSAGE_BADHEADER;
+ p = (unsigned char *) buf;
+ if (*p == '>')
+ p++;
+ if (*p == from_header[0])
+ is_from = 0;
+ else
+ is_from = -1;
+ for (; *p != ':' && is_from < 5; p++) {
+ if (is_from > 0 && *p != from_header[is_from])
+ is_from = -1;
+ if (is_from >= 0)
+ is_from++;
+ else
+ if (*p <= ' ') return IMAP_MESSAGE_BADHEADER;
}
}

7
cyrus-imapd-db.cfg Normal file
View File

@ -0,0 +1,7 @@
CONFIG_DB_DUPLICATE=berkeley
CONFIG_DB_MBOX=skiplist
CONFIG_DB_SEEN=skiplist
CONFIG_DB_SUBS=flat
CONFIG_DB_TLS=berkeley
CONFIG_DB_ANNOTATION=skiplist
CONFIG_DB_SIEVE=2.2.3

18
cyrus-imapd-gcc4.patch Normal file
View File

@ -0,0 +1,18 @@
--- cyrus-imapd-2.2.10/tools/config2header.orig 2005-03-04 17:18:04.519026273 -0500
+++ cyrus-imapd-2.2.10/tools/config2header 2005-03-04 17:19:45.234962450 -0500
@@ -214,7 +214,6 @@
print HFILE <<EOF
IMAPOPT_LAST
};
-extern struct imapopt_s imapopts[];
enum enum_value {
IMAP_ENUM_ZERO = 0,
@@ -260,6 +259,7 @@
print HFILE <<EOF
};
+extern struct imapopt_s imapopts[];
#endif /* INCLUDED_IMAPOPTIONS_H */
EOF
;

View File

@ -0,0 +1,28 @@
divert(-1)
include(`../m4/cf.m4')
define(`confDEF_USER_ID',``8:12'')
OSTYPE(`linux')
undefine(`UUCP_RELAY')
undefine(`BITNET_RELAY')
FEATURE(redirect)
FEATURE(always_add_domain)
FEATURE(use_cw_file)
FEATURE(local_procmail)
define(`CYRUS_MAILER_FLAGS',`Aw5:/|@o')
define(`confLOCAL_MAILER',`cyrus')
dnl # Note: CYUSER isn't needed, but must put $u in mailer args otherwise
dnl # it uses SMTP for delivery!
define(`CYRUS_MAILER_ARGS', `procmail -p /etc/procmailrc.cyrus CYUSER=$u')
define(`CYRUS_MAILER_PATH', `/usr/bin/procmail')
MAILER(cyrus)
MAILER(procmail)
MAILER(smtp)
HACK(check_mail3,`hash -a@JUNK /etc/mail/deny')
HACK(use_ip,`/etc/mail/ip_allow')
HACK(use_names,`/etc/mail/name_allow')
HACK(use_relayto,`/etc/mail/relay_allow')
HACK(check_rcpt4)
HACK(check_relay3)
dnl Not yet tested...
dnl LOCAL_RULE_0
dnl Rbb + $+ < @ $=w . > $#cyrusbb $: $1

View File

@ -0,0 +1,29 @@
PUSHDIVERT(-1)
#
# Copyright (c) 2002 Sendmail, Inc. and its suppliers.
# All rights reserved.
#
# By using this file, you agree to the terms and conditions set
# forth in the LICENSE file which can be found at the top level of
# the sendmail distribution.
#
# Contributed by Kenneth Murchison.
#
_DEFIFNOT(`_DEF_CYRUSV2_MAILER_FLAGS', `lsDFMnqXz')
_DEFIFNOT(`CYRUSV2_MAILER_FLAGS', `A@/:|m')
ifdef(`CYRUSV2_MAILER_ARGS',, `define(`CYRUSV2_MAILER_ARGS', `FILE /var/imap/socket/lmtp')')
define(`_CYRUSV2_QGRP', `ifelse(defn(`CYRUSV2_MAILER_QGRP'),`',`', ` Q=CYRUSV2_MAILER_QGRP,')')dnl
POPDIVERT
#########################################
### Cyrus V2 Mailer specification ###
#########################################
VERSIONID(`$Id: cyrus-imapd-sendmail-8.12.9-cyrusv2.m4,v 1.1 2004/02/04 12:59:42 karsten Exp $')
Mcyrusv2, P=[IPC], F=_MODMF_(CONCAT(_DEF_CYRUSV2_MAILER_FLAGS, CYRUSV2_MAILER_FLAGS), `CYRUSV2'),
S=EnvFromSMTP/HdrFromL, R=EnvToL/HdrToL, E=\r\n,
_OPTINS(`CYRUSV2_MAILER_MAXMSGS', `m=', `, ')_OPTINS(`CYRUSV2_MAILER_MAXRCPTS', `r=', `, ')_OPTINS(`CYRUSV2_MAILER_CHARSET', `C=', `, ')T=DNS/RFC822/SMTP,_CYRUSV2_QGRP
A=CYRUSV2_MAILER_ARGS

35
cyrus-imapd.cron-daily Normal file
View File

@ -0,0 +1,35 @@
#!/bin/sh
#
# This file is run on a daily basis to perform a backup of your
# mailbox list which can be used to recreate mailboxes.db from backup.
# Restore is done using ctl_mboxlist after uncompressing the file.
BACKDIR="/var/lib/imap/backup"
MBOXLIST="${BACKDIR}/mboxlist"
ROTATE=6
# fallback to su if runuser not available
if [ -x /sbin/runuser ]; then
RUNUSER=runuser
else
RUNUSER=su
fi
# source custom configuration
if [ -f /etc/sysconfig/cyrus-imapd ]; then
. /etc/sysconfig/cyrus-imapd
fi
[ -x /usr/lib/cyrus-imapd/ctl_mboxlist ] || exit 0
# rotate mailbox lists
seq $[ $ROTATE - 1 ] 1 | while read i; do
[ -f ${MBOXLIST}.${i}.gz ] && mv -f ${MBOXLIST}.${i}.gz ${MBOXLIST}.$[ $i + 1 ].gz
done
[ -f ${MBOXLIST}.gz ] && mv -f ${MBOXLIST}.gz ${MBOXLIST}.1.gz
# export mailboxes.db
$RUNUSER - cyrus -c "umask 077 < /dev/null ; /usr/lib/cyrus-imapd/ctl_mboxlist -d | gzip > ${MBOXLIST}.gz"
exit 0
# EOF

242
cyrus-imapd.cvt_cyrusdb_all Normal file
View File

@ -0,0 +1,242 @@
#!/bin/sh
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# This script converts all db files of a cyrus installation from their
# existing format to the format required by the current installation.
# The format of current db files is determined using the 'file' command
# with a magic file added for skiplist db, the new format is read from
# a config file usually in /usr/share/cyrus-imapd/rpm/db.cfg, which is
# created while compiling. After converting, the db.cfg file is
# copied to a cache file usually at /var/lib/imap/rpm/db.cfg.cache to
# allow bypassing this converting script if both files are identical.
# While this is a bit less secure, it may be useful on big server where
# db converting is done automatically.
#
# This script can safely be run as root, it will reexec itself as user
# cyrus if needed.
#
# author: Simon Matter, Invoca Systems <simon.matter@invoca.ch>
# changelog
# v1.0.1, Oct 22 2002 Simon Matter <simon.matter@invoca.ch>
# - added two-step conversion method
#
# v1.0.2, Jan 10 2003 Simon Matter <simon.matter@invoca.ch>
# - fixed a bug where cvt_cyrusdb was called to convert empty or
# nonexistent files
#
# v1.0.3, Mar 14 2003 Simon Matter <simon.matter@invoca.ch>
# - fixed a problem with new versions of the file command
#
# v1.0.4
# - added GPL license
#
# v1.0.5, May 02 2003 Simon Matter <simon.matter@invoca.ch>
# - modified exec path
#
# v1.0.6, Jul 18 2003 Simon Matter <simon.matter@invoca.ch>
# - changed db3 to berkeley
# - added new db backends for 2.2
#
# v1.0.7, Jan 23 2004 Simon Matter <simon.matter@invoca.ch>
# - included some modifications from Luca Olivetti <luca@olivetti.cjb.net>
# - added masssievec functionality
#
# v1.0.8, Jan 28 2004 Simon Matter <simon.matter@invoca.ch>
# - convert sieve scripts to UTF-8 before calling masssievec
#
# v1.0.9, Jan 29 2004 Simon Matter <simon.matter@invoca.ch>
# - convert sieve scripts to UTF-8 only if sievec failed before
#
# v1.0.10, Feb 24 2004 Simon Matter <simon.matter@invoca.ch>
# - change su within init script to get input from
# /dev/null, this prevents hang when running in SELinux
#
# v1.0.11, Mar 02 2004 Simon Matter <simon.matter@invoca.ch>
# - fixed SELinux fix
#
# v1.0.12, Dec 16 2004 Simon Matter <simon.matter@invoca.ch>
# - use runuser instead of su if available
if [ -n "$(/sbin/pidof cyrus-master)" ]; then
echo "ERROR: cyrus-master is running, unable to convert mailboxes!"
exit 1
fi
if [ ! -f /etc/imapd.conf ]; then
echo "ERROR: configuration file not found."
exit 1
fi
# fallback to su if runuser not available
if [ -x /sbin/runuser ]; then
RUNUSER=runuser
else
RUNUSER=su
fi
# force cyrus user for security reasons
if [ ! $(whoami) = "cyrus" ]; then
exec $RUNUSER - cyrus -c "cd $PWD < /dev/null ; $0"
fi
# files get mode 0600
umask 166
# get_config [config default]
# extracts config option from config file
get_config() {
if config=$(grep "^$1" /etc/imapd.conf); then
echo $config | cut -d: -f2 | sed -e 's/^ *//' -e 's/-nosync//' -e 's/ *$//'
else
echo $2
fi
}
# where to find files and directories
system_magic=$(file --version | awk '/magic file/ {print $4}')
cyrus_magic=/usr/share/cyrus-imapd/rpm/magic
cvt_cyrusdb=/usr/lib/cyrus-imapd/cvt_cyrusdb
sievec=/usr/lib/cyrus-imapd/sievec
imap_prefix=$(get_config configdirectory /var/lib/imap)
sieve_dir=$(get_config sievedir /var/lib/imap/sieve)
db_cfg=/usr/share/cyrus-imapd/rpm/db.cfg
db_current=${imap_prefix}/rpm/db.cfg.current
db_cache=${imap_prefix}/rpm/db.cfg.cache
# source default db backend config
. $db_cfg
# get configured db backend config
CONFIG_DB_DUPLICATE=$(get_config duplicate_db $CONFIG_DB_DUPLICATE)
CONFIG_DB_MBOX=$(get_config mboxlist_db $CONFIG_DB_MBOX)
CONFIG_DB_SEEN=$(get_config seenstate_db $CONFIG_DB_SEEN)
CONFIG_DB_SUBS=$(get_config subscription_db $CONFIG_DB_SUBS)
CONFIG_DB_TLS=$(get_config tlscache_db $CONFIG_DB_TLS)
CONFIG_DB_ANNOTATION=$(get_config annotation_db $CONFIG_DB_ANNOTATION)
# remember current db backend config
{
echo "CONFIG_DB_DUPLICATE=$CONFIG_DB_DUPLICATE"
echo "CONFIG_DB_MBOX=$CONFIG_DB_MBOX"
echo "CONFIG_DB_SEEN=$CONFIG_DB_SEEN"
echo "CONFIG_DB_SUBS=$CONFIG_DB_SUBS"
echo "CONFIG_DB_TLS=$CONFIG_DB_TLS"
echo "CONFIG_DB_ANNOTATION=$CONFIG_DB_ANNOTATION"
echo "CONFIG_DB_SIEVE=$CONFIG_DB_SIEVE"
} > $db_current
# file_type [file]
file_type() {
this_type=$(file -b -m "$system_magic:$cyrus_magic" "$1" 2> /dev/null)
if echo "$this_type" | grep -qi skip > /dev/null 2>&1; then
echo skiplist
elif echo "$this_type" | grep -qi text > /dev/null 2>&1; then
echo flat
else
echo berkeley
fi
}
# cvt_file [file] [db]
cvt_file() {
target="$1"
new_db="$2"
if [ -s "$target" ]; then
old_db=$(file_type "$target")
if [ ! "$old_db" = "$new_db" ]; then
# The two-step conversion is paranoia against the filenames being encoded
# inside the database or logfiles (berkeley does this, for example).
rm -f "${target}.flat"
if [ "$old_db" = "flat" ]; then
cp -a "$target" "${target}.flat"
else
$cvt_cyrusdb "$target" "$old_db" "${target}.flat" flat
fi
RETVAL=$?
ERRVAL=$[ $ERRVAL + $RETVAL ]
if [ $RETVAL -eq 0 ]; then
rm -f "$target"
if [ -s "${target}.flat" ]; then
if [ "$new_db" = "flat" ]; then
cp -a "${target}.flat" "$target"
else
$cvt_cyrusdb "${target}.flat" flat "$target" "$new_db"
fi
fi
RETVAL=$?
ERRVAL=$[ $ERRVAL + $RETVAL ]
if [ $RETVAL -eq 0 ]; then
rm -f "${target}.flat"
else
echo "ERROR: unable to convert ${target}.flat from flat to $new_db"
fi
else
echo "ERROR: unable to convert $target from $old_db to flat"
fi
fi
fi
}
# cvt_to_utf8 [file]
cvt_to_utf8() {
target="$1"
if [ -s "$target" ]; then
if ! $sievec "$target" "${target}.sievec"; then
iconv --from-code=ISO-8859-1 --to-code=UTF-8 --output="${target}.UTF-8" "$target"
if [ -s "${target}.UTF-8" ]; then
# preserve timestamp
touch --reference="$target" "${target}.UTF-8"
mv -f "${target}.UTF-8" "$target"
else
ERRVAL=$[ $ERRVAL + 1 ]
fi
fi
rm -f "${target}.sievec"
fi
}
ERRVAL=0
# do we need to convert databases ?
if ! cmp -s $db_current $db_cache; then
# we treat sieve scripts the same way like db files
find ${sieve_dir}/ -name "*.script" -type f | while read db_file trash; do
cvt_to_utf8 "$db_file"
done
/usr/lib/cyrus-imapd/masssievec /usr/lib/cyrus-imapd/sievec
# convert all db files
cvt_file $imap_prefix/deliver.db "$CONFIG_DB_DUPLICATE"
cvt_file $imap_prefix/mailboxes.db "$CONFIG_DB_MBOX"
cvt_file $imap_prefix/tls_sessions.db "$CONFIG_DB_TLS"
cvt_file $imap_prefix/annotations.db "$CONFIG_DB_ANNOTATION"
find ${imap_prefix}/user/ -name "*.seen" -type f | while read db_file trash; do
cvt_file "$db_file" "$CONFIG_DB_SEEN"
done
find ${imap_prefix}/user/ -name "*.sub" -type f | while read db_file trash; do
cvt_file "$db_file" "$CONFIG_DB_SUBS"
done
fi
# copy the current config file so we can check whether something has changed
if [ $ERRVAL -eq 0 ]; then
mv -f $db_current $db_cache
else
rm -f $db_cache
rm -f $db_current
fi
exit $ERRVAL

View File

@ -0,0 +1,11 @@
configdirectory: /var/lib/imap
partition-default: /var/spool/imap
admins: cyrus
sievedir: /var/lib/imap/sieve
sendmail: /usr/sbin/sendmail
hashimapspool: true
sasl_pwcheck_method: saslauthd
sasl_mech_list: PLAIN
tls_cert_file: /usr/share/ssl/certs/cyrus-imapd.pem
tls_key_file: /usr/share/ssl/certs/cyrus-imapd.pem
tls_ca_file: /usr/share/ssl/certs/ca-bundle.crt

154
cyrus-imapd.init Normal file
View File

@ -0,0 +1,154 @@
#!/bin/sh
#
# chkconfig: - 65 35
# description: The Cyrus IMAPD master serves as a master process for the Cyrus \
# IMAP and POP servers.
# config: /etc/cyrus.conf
# config: /etc/imapd.conf
# pidfile: /var/run/cyrus-master.pid
# author: Simon Matter, Invoca Systems <simon.matter@invoca.ch>
# version: 2005010600
# changed: 2002020200 chkconfig modified
# 2002042500 rewrote start function
# 2002091800 added auto db converting functionality
# 2003020400 modified to use builtin daemon mode
# 2003050200 modified exec path
# 2003050900 return RETVAL from rhstatus(), did some cleanup
# 2003060700 added umask for cvt_cyrusdb_all log
# 2004012300 modified auto db converting functionality for 2.2
# 2004012700 fixed startup procedure
# 2004022400 change su within init script to get input from
# /dev/null, this prevents hang when running in SELinux
# 2004052000 don't enable cyrus-imapd per default
# 2004111900 use runuser instead of su if available
# 2005010600 removed LIB placeholder
# Source function library
if [ -f /etc/init.d/functions ]; then
. /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ]; then
. /etc/rc.d/init.d/functions
else
exit 0
fi
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0
# check if the config files are present
[ -f /etc/cyrus.conf ] || exit 0
[ -f /etc/imapd.conf ] || exit 0
# This is our service name
BASENAME=$(basename $0)
if [ -L $0 ]; then
BASENAME=$(find $0 -name $BASENAME -printf %l)
BASENAME=$(basename $BASENAME)
fi
# fallback to su if runuser not available
if [ -x /sbin/runuser ]; then
RUNUSER=runuser
else
RUNUSER=su
fi
CYRUSMASTER=/usr/lib/cyrus-imapd/cyrus-master
CYRUS_PROC_NAME=$(basename $CYRUSMASTER)
ALWAYS_CONVERT=1
# Source service configuration.
if [ -f /etc/sysconfig/$BASENAME ]; then
. /etc/sysconfig/$BASENAME
else
echo "$BASENAME: configfile /etc/sysconfig/$BASENAME does NOT exist !"
exit 1
fi
RETVAL=0
start() {
echo -n $"Starting $BASENAME: "
if [ $(/sbin/pidof -s $CYRUSMASTER) ]; then
echo -n $"$BASENAME already running."
false
else
echo -n $"preparing databases... "
$RUNUSER - cyrus -c "umask 166 ; /usr/lib/cyrus-imapd/cvt_cyrusdb_all > /var/lib/imap/rpm/cvt_cyrusdb_all.log 2>&1" < /dev/null
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
echo -n $"done. "
daemon $CYRUSMASTER -d $CYRUSOPTIONS
else
echo -n $"error! "
initlog -n $BASENAME -s "error converting databases, check /var/lib/imap/rpm/cvt_cyrusdb_all.log"
failure $"$BASENAME startup"
fi
fi
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$BASENAME
return $RETVAL
}
stop() {
echo -n $"Shutting down $BASENAME: "
killproc $CYRUSMASTER
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$BASENAME
echo
return $RETVAL
}
restart() {
stop
start
}
reload() {
echo -n $"Reloading cyrus.conf file: "
killproc $CYRUSMASTER -HUP
RETVAL=$?
echo
return $RETVAL
}
condrestart() {
[ -e /var/lock/subsys/$BASENAME ] && restart || :
}
rhstatus() {
status $CYRUSMASTER
RETVAL=$?
return $RETVAL
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
reload)
reload
;;
condrestart)
condrestart
;;
status)
rhstatus
;;
*)
echo $"Usage: $BASENAME {start|stop|restart|reload|condrestart|status}"
RETVAL=1
esac
exit $RETVAL

7
cyrus-imapd.logrotate Normal file
View File

@ -0,0 +1,7 @@
/var/log/imapd.log /var/log/auth.log {
missingok
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}

9
cyrus-imapd.magic Normal file
View File

@ -0,0 +1,9 @@
# Magic
# Magic data for file(1) command.
# Format is described in magic(files), where:
# files is 5 on V7 and BSD, 4 on SV, and ?? in the SVID.
#------------------------------------------------------------------------------
# skiplist: file(1) magic Cyrus skiplist DB
#
0 string \241\002\213\015skiplist\ file\0\0\0 Cyrus skiplist DB

3
cyrus-imapd.pam-config Normal file
View File

@ -0,0 +1,3 @@
#%PAM-1.0
auth required pam_stack.so service=system-auth
account required pam_stack.so service=system-auth

View File

@ -0,0 +1,30 @@
#!/bin/sh
IMAPCONF=/etc/imapd.conf
CONFDIR=$(grep -se "^configdirectory:" $IMAPCONF | cut -d":" -f2)
if [ "x$CONFDIR" = "x" ]; then
echo "$0 error: configdirectory not found in /etc/imapd.conf, exiting!"
exit 1
fi
find $CONFDIR -type d ! -name "lost+found" -exec chmod 700 {} \; -exec chown cyrus:mail {} \;
grep -se "^partition-.*:" $IMAPCONF | cut -d":" -f2 | while read SPOOLDIR; do
if [ "x$SPOOLDIR" = "x" ]; then
echo "$0 warning: invalid partition configuration in /etc/imapd.conf found!"
else
find $SPOOLDIR -type d ! -name "lost+found" -exec chmod 700 {} \; -exec chown cyrus:mail {} \;
fi
done
find $CONFDIR -type f ! -name "lost+found" -exec chmod 600 {} \; -exec chown cyrus:mail {} \;
grep -se "^partition-.*:" $IMAPCONF | cut -d":" -f2 | while read SPOOLDIR; do
if [ "x$SPOOLDIR" = "x" ]; then
echo "$0 warning: invalid partition configuration in /etc/imapd.conf found!"
else
find $SPOOLDIR -type f ! -name "lost+found" -exec chmod 600 {} \; -exec chown cyrus:mail {} \;
fi
done
# lmtp socket must be accessible by group mail
chmod 750 $CONFDIR
chmod 750 ${CONFDIR}/socket

1266
cyrus-imapd.spec Normal file

File diff suppressed because it is too large Load Diff

5
cyrus-imapd.sysconfig Normal file
View File

@ -0,0 +1,5 @@
# Options to cyrus-master
CYRUSOPTIONS=""
# Mailbox list dumps are rotated n times via cron.daily
#ROTATE=6

View File

@ -0,0 +1,66 @@
#!/bin/sh
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# This script updates a cache of the unix group database. It's purpose is to
# speedup group authorization when using large groups with slow nss backends.
# For more info consult the README.groupcache file.
#
# This script can safely be run as root, it will reexec itself as user
# cyrus if needed.
#
# author: Simon Matter, Invoca Systems <simon.matter@invoca.ch>
# changelog
# v1.0.0, Dec 15 2004 Simon Matter <simon.matter@invoca.ch>
# - initial release
if [ ! -f /etc/imapd.conf ]; then
echo "ERROR: configuration file not found."
exit 1
fi
# fallback to su if runuser not available
if [ -x /sbin/runuser ]; then
RUNUSER=runuser
else
RUNUSER=su
fi
# force cyrus user for security reasons
if [ ! $(whoami) = "cyrus" ]; then
exec $RUNUSER - cyrus -c "cd $PWD < /dev/null ; $0"
fi
# files get mode 0600
umask 166
# get_config [config default]
# extracts config option from config file
get_config() {
if config=$(grep "^$1" /etc/imapd.conf); then
echo $config | cut -d: -f2
else
echo $2
fi
}
# where to find files and directories
imap_prefix=$(get_config configdirectory /var/lib/imap)
group_cache=${imap_prefix}/group.cache
TMPCACHE=$(mktemp ${group_cache}.XXXXXX) || exit 1
getent group >> $TMPCACHE
mv -f $TMPCACHE $group_cache

129
cyrus-procmailrc Normal file
View File

@ -0,0 +1,129 @@
#################################################
# procmailrc
# This is the main procmail file with common SPAM recipes
# Based on the article at
# http://www.ncworldmag.com/ncw-05-1998/ncw-05-imap.html
#
#
# First we define some basics
PATH=/usr/bin:/bin
SHELL=/bin/sh
# We define DELIVERTO just to prevent a lot of extra
# typing later on. We define SPAMIT to prevent even more
# repetitive typing, as it's the same action for every user.
# This assumes we set up a SPAM folder right off the INBOX
# for every user on the system. If we neglect to do that, we'll
# get in a bit of trouble.
DELIVERTO=/usr/cyrus/bin/deliver-wrapper
SPAMIT="$DELIVERTO user.$LOGNAME.SPAM"
# This file includes the appropriate procmail.$LOGNAME
# file so that each user has his or her own recipe techniques
# for subscribed lists, e-mail alerts, etc.
# Before we begin any recipes, let's make a backup
# copy of any incoming mail.
#
# Remember to comment out the next recipe once
# you know everything is working fine, otherwise
# you'll fill up the backup directory very quickly.
# Some procmail tutorials demonstrate how you can
# set a quota on the backup directory so that you can
# leave it in force at all times.
:0 ic
| $DELIVERTO user.$LOGNAME.Backup
###############################
# If there used to be an existing system-wide procmailrc, you can
# include it here
#INCLUDERC=/etc/procmailrc
# We shouldn't be running as a privileged user, but just in case,
# make sure we drop any privileges we have
DROPPRIVS=1
###############################
# If users want to be able to define their own private recipes
# and put them in their home .procmailrc files, comment out
# the next definition.
#
# These recipes will be processed BEFORE the user-specific
# recipes that are kept in the /home/cyrus directory
#
# setup some variables, before we start
ALERTSBOX=user.$LOGNAME.Folders.Alerts
LISTSBOX=user.$LOGNAME.Folders.Lists
#
INCLUDERC=$HOME/.procmailrc
# If you want to define user-specific recipes that
# you manage centrally (perhaps because you don't want
# to allow your users to "roll their own," then
# uncomment the following line. In this case, you have
# to create a file for each user in the form:
# procmail.username -- for example, procmail.Joe
#
# INCLUDERC=/usr/cyrus/etc/procmail.$LOGNAME
#############################
# Now we begin our recipes
#############################
# Email-specific SPAM recipes
# Here's one example
#### NOTE: surely cyrus 'deliver' does its own locking? There should
#### thus be no need for :0:$LOGNAME.lock
:0
* ^To:.*anyplace@juno.com
| $SPAMIT
#############################
# General SPAM Recipes
# Here are a few examples
#
# The "To:" line doesn't exist
#:0
#* !^To:
#| $SPAMIT
# The "To:" line is empty
#:0
#* ^To: $
#| $SPAMIT
# The "From:" line is empty
#:0
#* ^From: $
#| $SPAMIT
#############################
# All the mail that falls
# through the above recipes
# will be put into the user's
# inbox. This is always the LAST
# recipe to appear in the file.
:0W
| $DELIVERTO user.$LOGNAME
# If that fails - maybe because the user is out of quota, or the mailbox
# hasn't been created - then force a bounce (otherwise the message would
# get silently appended to /var/spool/mail/$LOGNAME).
# This is EX_CANTCREAT (Can't create output)
EXITCODE=73
:0
/dev/null
#
# End of procmailrc file
##############################

View File

@ -0,0 +1,58 @@
##############################
# Begin procmailrc.joe file
#
# This is Joe's specific set of procmail
# recipes. It assumes that Joe has a
# number of specific folders created
# to which these recipes refer. Otherwise
# the mail cannot be sorted properly.
#
# First, let's define some high-level
# folder macros to save typing later on.
# The ALERTSBOX points to the
# folder where we'll sort out various
# incoming news alerts.
# The LISTSBOX will point to a
# folder where we'll sort out various
# list services to which we're subscribed.
#
# Both ALERTSBOX and LISTSBOX
# are subfolders of a generic folder called,
# duh, Folders, which is right off the
# user's INBOX.
#
# So if a Linux-kernel message comes in
# it gets deposited in the folder
# Folders/Lists/Linux_Kernel which is
# represented in Cyrus IMAP terms as
# user.Joe.Folders.Lists.Linux_kernel
#
############################
# Put anchordesk alerts in news alerts folder
:0:$LOGNAME.lock
* ^From:.*anchordesk
| $DELIVERTO $ALERTSBOX.News-Alerts
# Put NC World alerts in their own folder
:0:$LOGNAME.lock
* ^From:.*NCWorld@FDDS.com
| $DELIVERTO $ALERTSBOX.NCWorld-Alerts
#############################
# List processing & Misc Alerts
:0:$LOGNAME.lock
* (^Cc:|^CC:|^To:|^Sender:).*linux-kernel@vger.rutgers.edu
| $DELIVERTO $LISTSBOX.Linux_Kernel
:0:$LOGNAME.lock
* (^Cc:|^CC:|^To:|^Sender:).*linux-net@vger.rutgers.edu
| $DELIVERTO $LISTSBOX.Linux_Net
#
# End of procmailrc.joe file
##############################

127
cyrus_ldap_quota.pl Normal file
View File

@ -0,0 +1,127 @@
#!/usr/bin/perl
use Cyrus::IMAP::Admin;
# This script was created by Kevin J. Menard, Jr. <kmenard@wpi.edu>.
# It requires root privileges to write to a file in /etc. Best use is
# to set this up as cron job. Works for me. Hope it does for you.
# Any questions/complaints/praise/whatever, send 'em to the address
# above. -- 08/16/2001
# These are the variables you might want to tweak.
my $quota_attr = "mailQuota";
my $mail_attr = "mailRoutingAddress";
my $user = "cyrus";
my $passwd = "blah";
# These are the ones that you shouldn't have to.
my @entries = ();
my $index = 0;
my $counter = 0;
my $old_timestamp = 0;
my $timestamp = "199412161032Z";
# Open the /etc/cyrus_ldap_quota_time file; it's a long name, but
# shouldn't interfere with existing files :) This file contains 1 line,
# the generalized time format of the last time the script ran. This is
# used for the search, so we only update quotas that have been modified
# since then.
{
if (-e "/etc/cyrus_ldap_quota_time")
{
open(TIME_FILE, "/etc/cyrus_ldap_quota_time") or die "could not
open the time file: $!\n";
while(<TIME_FILE>) { $old_timestamp = $_; }
close(TIME_FILE);
}
# Now we deal with the case where the file doesn't exist, that is to
# say the first time the script was run.
unless ($old_timestamp == 0) { $timestamp = $old_timestamp; }
# Now that we have that information, we can overwrite the file with
# the new timestamp. Maybe this overkill, but this is only a
# temporary solution anyway.
open(TIME_FILE, ">/etc/cyrus_ldap_quota_time") or die "could not
create file: $!\n";
my @time = (localtime)[0..5];
printf TIME_FILE $time[5] + 1900;
printf TIME_FILE "%02d", $time[4] + 1;
for (my $i = 3; $i >= 0; $i--) { printf TIME_FILE "%02d", $time[$i];}
print TIME_FILE 'Z';
close(TIME_FILE);
}
# This is where we do the search and then parse the results into a
# useable form. In this case, an arry of hash entries.
{
# Okay, this very ugly line sets up the LDAP search, and the strips
# away the meaningless stuff. This could be prettier, but I didn't
# want to add a dependency for an LDAP module, and everyone should
# have LDAP search. The greps are just to make things simpler.
(my $query = "ldapsearch -x '(&(modifyTimestamp>=$timestamp)($quota_attr=*))' $quota_attr $mail_attr
| grep -v ^# | grep -v ^dn | grep -v ^version | grep -v ^search | grep -v ^result | grep -v ^\$") =~ s!\n!!;
# Now actually do the commands in the above line.
my $result = `$query`;
# Split the output into an array, one entry per line.
my @output = split(/\n/, $result);
# Now go through each line . . .
foreach (@output)
{
# Split on the attribute:value boundary.
(my $key, my $value) = split(/: /);
# Handle mailRoutingAddress; strip away everything after '@'.
if ($value =~ m!@!)
{
($value, undef) = split (/@/, $value);
}
# Add each doctored up attribute:value pair to the entries array.
$entries[$index]{$key} = $value;
# A crude hack to make sure each of the two attributes makes it
# into one of the entries array element.
if ($counter % 2)
{
$index++;
}
$counter++;
}
}
# Now here's the actual interaction with Cyrus IMAPd. It's all pretty
# self-explanatory.
{
my $imap = Cyrus::IMAP::Admin->new('localhost') or die "imap:
cannot connect to server: $!\n";
$imap->send(undef, undef, "LOGIN %s %s", $user, $passwd) or die
"could not send user:pass to the server: $!\n";
for (my $i = 0; $i <= $#entries; $i++)
{
$imap->setquota("user." . $entries[$i]{$mail_attr}, "STORAGE",
$entries[$i]{$quota_attr})
or die "imap: could not set quota for
user.$entries[$i]{$mail_attr}: $!\n";
}
$imap=undef;
}

46
folderxfer Normal file
View File

@ -0,0 +1,46 @@
#!/usr/bin/perl
#
# Usage: folderxfer inputfile
#
# Purpose: Converts contents of Berkeley-format mail folders
# to Cyrus mailboxes
#
# Input: Output of 'bsd2cyrus'
# (username:Cyrus-folder-name:Berkeley-folder-path)
#
# Warnings: The root mailbox and empty Cyrus folder must
# exist before conversion takes place, and source folders
# should be checked for RFC 822 content before being processed
#
#$Id: folderxfer,v 1.1 2004/02/04 12:59:42 karsten Exp $
$pwd = "/usr/lib/cyrus-imapd";
$mailstore = "/var/spool/imap"; # Cyrus mailstore
$cat = "/bin/cat";
$cmd = "/usr/bin/formail -n 20 -s $pwd/cpmsg";
$folders = "$ARGV[0]";
if (!$folders) { die "Usage: $0 filename"; }
open (MB,"$folders") || die "can't open $folders";
while (<MB>) {
chop;
# Be careful with this split - the last token might have
# whitespace we want to preserve
($user,$cyrusfolder,$folder) = split(/:/,$_,3);
@fields = split(/\./,$cyrusfolder);
$cyrfol = $fields[$#fields];
$fcat = "$cat \"$folder\"";
print $fcat;
$prefix = substr($user,0,1);
system ("$fcat | $cmd '$mailstore/$prefix/user/$user/$cyrfol'");
#print "'$mailstore/$prefix/user/$user/$cyrfol";
}
close MB;

159
imapcreate.pl Normal file
View File

@ -0,0 +1,159 @@
#!/usr/bin/perl -w
#
# imapcreate: create IMAP mailboxes with quotas
# Reads user names from standard input.
# launch without argument for a short help.
#
# originally found on http://cyrus-utils.sourceforge.net
# (could not find any copyright info, thought)
#
# enhanced by Clément "nodens" Hermann <clement.hermann@free.fr>
#
# I'd like to consider this as GPL'd (cf www.gnu.org), but won't add any copyright without the original author's consent.
#
use Getopt::Long;
use Cyrus::IMAP::Admin;
use strict;
my $debug;
my $user;
my $pass;
my $quota;
my @part;
my $useunixhierarchy;
my @mailboxes;
my $delete;
my $cyrus;
sub usage {
print <<EOU;
imapcreate - create IMAP mailboxes with quotas
usage:
imapcreate [-d] [-u user] [-p pass] [-m mailbox1[,mailbox2][,mailbox<n>]]
[-q quota] [-t partition:list] [-s] [-v] <server>
Options:
-t : the partition to use. Default to the \"default\" partition
-q ; the quota, if a quota is needed. It is normally in KiloBytes, but you can use m,M,g or G suffix to use MB or GB instead, e.g 10k, 2048M or 100g
-m : a comma-separated mailbox list
-u : your cyrus admin user (usually cyrus or cyradm)
-p : your cyrus admin password (if not provided, it will be asked for)
-s : use the unix hierarchy separator (see imapd.conf(1))
-d : delete mailboxes instead of creating them
-v : run in debug mode, and print information on stdout
If no password is submitted with -p, we'll prompt for one.
if no mailbox name is specified with -m, read user names from standard input
examples:
imapcreate -u cyradm -m foo,bar,joe -q 50000 -t p1:p2 mail.testing.umanitoba.ca
cat list.txt | imapcreate -u cyradm -p 'cyruspass' -q 50M mail.testing.umanitoba.ca
EOU
exit 1;
}
# Create a mailbox... usage : &CreateMailBox(user,partition[,quota]).
# You have to be authentified already. We use "$cyrus" as the connection name.
# partition can be 'default'
sub CreateMailBox {
my $mbuser = $_[0];
my $mbpart = $_[1];
my $mbquota = $_[2];
print "Creating $mbuser on $mbpart\n" if $debug;
if ($mbpart eq 'default') {
$cyrus->createmailbox($mbuser);
}
else {
$cyrus->createmailbox($mbuser, $mbpart);
}
warn $cyrus->error if $cyrus->error;
# Set the quota
if ($mbquota) {
print "Setting quota for $mbuser to $mbquota\n" if $debug;
$cyrus->setquota($mbuser, 'STORAGE', $mbquota);
warn $cyrus->error if $cyrus->error;
}
}
# Delete a mailbox. Usage: $DeleteMailBox($user)
# Assuming we use $user as the admin.
sub DeleteMailBox {
my $mbuser = $_[0];
my $delacl = "c";
print "Deleting $mbuser\n" if $debug;
$cyrus->setaclmailbox($mbuser, $user, $delacl);
$cyrus->deletemailbox($mbuser);
warn $cyrus->error if $cyrus->error;
}
GetOptions("d|delete" => \$delete, "u|user=s" => \$user, "p|pass=s" => \$pass, "m|mailboxes=s" => \@mailboxes, "q|quota=s" => \$quota,
"t|part=s" => \@part, "s|UnixHierarchy" => \$useunixhierarchy, "v|verbose" => \$debug );
@part = split(/:/, join(':', @part));
push @part, 'default' unless @part;
my $pn = 0;
@mailboxes = split(/,/, join(',', @mailboxes));
my $server = shift(@ARGV) if (@ARGV);
usage unless $server;
# quotas formatting:
if ($quota) {
if ($quota =~ /^(\d+)([mk]?)$/i) {
my $numb = $1;
my $letter = $2;
if ($letter =~ /^m$/i) {
$quota = $numb * 1024;
print "debug: quota=$quota\n" if $debug;
} elsif ($letter =~ /^k$/i) {
$quota = $numb;
print "debug: quota=$quota\n" if $debug;
} else {
die "malformed quota: $quota (must be at least one digit eventually followed by m, M, k or K\n";
# $quota = $numb;
# print "debug: quota=$quota\n" if $debug;
}
} else {
die "malformed quota: $quota (must be at least one digit eventually followed by m, M, k or K\n";
}
}
# Authenticate
$cyrus = Cyrus::IMAP::Admin->new($server);
$cyrus->authenticate(-mechanism => 'login', -user => $user,
-password => $pass);
die $cyrus->error if $cyrus->error;
# if there isn't any mailbox defined yet, get them from standard input
if (! (defined $mailboxes[0])) {
# For all users
while (<>) {
chomp;
my $mbox = $_;
push @mailboxes, $mbox;
}
}
# create/delete mailboxes for each user
foreach my $mailbox (@mailboxes) {
if ($useunixhierarchy) {
$mailbox = 'user/' . $mailbox;
} else {
$mailbox = 'user.' . $mailbox;
}
if ($delete) {
&DeleteMailBox($mailbox)
} else {
# Select the partition
my $pt = $part[$pn];
$pn += 1;
$pn = 0 unless $pn < @part;
&CreateMailBox($mailbox,$pt,$quota)
}
}

36
inboxfer Normal file
View File

@ -0,0 +1,36 @@
#!/usr/bin/perl
#
# Usage: inboxfer inputfile
#
# Purpose: Transfer messages from Berkeley-format inbox to Cyrus inbox
#
# Input: Text file containing one username per line
#
# Warning: Do not use this script to transfer messages into a Cyrus
# mailbox that already contain messages. Existing messages
# will be overwritten.
#
#$Id: inboxfer,v 1.1 2005/04/15 20:24:15 jdennis Exp $
$mailstore = "/var/spool/imap"; # Cyrus mailstore
$oldspool = "/var/spool/mail"; # Old mail spool
$cat = "/bin/cat"; # /usr/bin/cat on Solaris
$formail = "/usr/bin/formail";
$pwd = "/usr/lib/cyrus-imapd";
$cpmsg = "cpmsg";
$cmd = "$formail -n 20 -s $pwd/$cpmsg";
$users = "$ARGV[0]";
if (!$users) { die "Usage: $0 $users\n"; }
open(USERS,"$users") || die "can't open $users";
while (<USERS>) {
chop;
$inbox = "$oldspool/$_";
$prefix = substr($_,0,1);
system("$cat $inbox | $cmd $mailstore/$prefix/user/$_");
}

View File

@ -0,0 +1,3 @@
70b3bba526a8d36d3bb23a87d37e9188 cyrus-imapd-2.2.12.tar.gz
f3d52a0eb84ec6c8a127cd4c1bc6af7b cyrus-imapd-README.HOWTO-recover-mailboxes.db
8f7a26b0556369827bb5c8084a3e3ea1 cyrus_sharedbackup-0.1.tar.gz