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:
parent
f607264efd
commit
38f2261a6f
@ -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
181
README.autocreate-cyrus-2.2
Normal 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
42
README.autosievefolder
Normal 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
32
batchreconstruct
Normal 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
81
bsd2cyrus
Normal 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
26
cpmsg
Normal 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
34
cyrus-deliver-wrapper.c
Normal 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;
|
||||||
|
}
|
12
cyrus-imapd-2.1.15-nobarenewlinescheck.patch
Normal file
12
cyrus-imapd-2.1.15-nobarenewlinescheck.patch
Normal 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;
|
23
cyrus-imapd-2.1.16-getrlimit.patch
Normal file
23
cyrus-imapd-2.1.16-getrlimit.patch
Normal 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 */
|
||||||
|
}
|
77
cyrus-imapd-2.1.3-flock.patch
Normal file
77
cyrus-imapd-2.1.3-flock.patch
Normal 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";
|
14
cyrus-imapd-2.1.9-fdatasync.patch
Normal file
14
cyrus-imapd-2.1.9-fdatasync.patch
Normal 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
|
43
cyrus-imapd-2.2.10-groupcache.patch
Normal file
43
cyrus-imapd-2.2.10-groupcache.patch
Normal 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;
|
||||||
|
}
|
||||||
|
|
491
cyrus-imapd-2.2.10-rmquota+deletemailbox-0.1.diff
Normal file
491
cyrus-imapd-2.2.10-rmquota+deletemailbox-0.1.diff
Normal 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 = "a;
|
||||||
|
+ 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("a, NULL, 0);
|
||||||
|
+ r = quota_read("a, 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("a, NULL);
|
||||||
|
+ r = quota_delete("a, 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 = "a;
|
||||||
|
+ /* 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;
|
||||||
|
}
|
2159
cyrus-imapd-2.2.12-autocreate-0.9.2.diff
Normal file
2159
cyrus-imapd-2.2.12-autocreate-0.9.2.diff
Normal file
File diff suppressed because it is too large
Load Diff
193
cyrus-imapd-2.2.12-autosievefolder-0.6.diff
Normal file
193
cyrus-imapd-2.2.12-autosievefolder-0.6.diff
Normal 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
|
BIN
cyrus-imapd-2.2.12.tar.gz.sig
Normal file
BIN
cyrus-imapd-2.2.12.tar.gz.sig
Normal file
Binary file not shown.
104
cyrus-imapd-2.2.4-OE-seenstate.patch
Normal file
104
cyrus-imapd-2.2.4-OE-seenstate.patch
Normal 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
|
||||||
|
*
|
109
cyrus-imapd-2.2.4-munge8bit.patch
Normal file
109
cyrus-imapd-2.2.4-munge8bit.patch
Normal 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 ‘X’. 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 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’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
33
cyrus-imapd-README.RPM
Normal 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!
|
10
cyrus-imapd-README.contrib
Normal file
10
cyrus-imapd-README.contrib
Normal 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.
|
30
cyrus-imapd-README.groupcache
Normal file
30
cyrus-imapd-README.groupcache
Normal 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
|
||||||
|
}
|
34
cyrus-imapd-acceptinvalidfrom.patch
Normal file
34
cyrus-imapd-acceptinvalidfrom.patch
Normal 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
7
cyrus-imapd-db.cfg
Normal 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
18
cyrus-imapd-gcc4.patch
Normal 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
|
||||||
|
;
|
28
cyrus-imapd-procmail+cyrus.mc
Normal file
28
cyrus-imapd-procmail+cyrus.mc
Normal 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
|
29
cyrus-imapd-sendmail-8.12.9-cyrusv2.m4
Normal file
29
cyrus-imapd-sendmail-8.12.9-cyrusv2.m4
Normal 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
35
cyrus-imapd.cron-daily
Normal 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
242
cyrus-imapd.cvt_cyrusdb_all
Normal 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
|
11
cyrus-imapd.imap-2.2.x-conf
Normal file
11
cyrus-imapd.imap-2.2.x-conf
Normal 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
154
cyrus-imapd.init
Normal 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
7
cyrus-imapd.logrotate
Normal 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
9
cyrus-imapd.magic
Normal 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
3
cyrus-imapd.pam-config
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#%PAM-1.0
|
||||||
|
auth required pam_stack.so service=system-auth
|
||||||
|
account required pam_stack.so service=system-auth
|
30
cyrus-imapd.rpm_set_permissions
Normal file
30
cyrus-imapd.rpm_set_permissions
Normal 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
1266
cyrus-imapd.spec
Normal file
File diff suppressed because it is too large
Load Diff
5
cyrus-imapd.sysconfig
Normal file
5
cyrus-imapd.sysconfig
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Options to cyrus-master
|
||||||
|
CYRUSOPTIONS=""
|
||||||
|
|
||||||
|
# Mailbox list dumps are rotated n times via cron.daily
|
||||||
|
#ROTATE=6
|
66
cyrus-imapd.upd_groupcache
Normal file
66
cyrus-imapd.upd_groupcache
Normal 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
129
cyrus-procmailrc
Normal 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
|
||||||
|
##############################
|
58
cyrus-user-procmailrc.template
Normal file
58
cyrus-user-procmailrc.template
Normal 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
127
cyrus_ldap_quota.pl
Normal 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
46
folderxfer
Normal 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
159
imapcreate.pl
Normal 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
36
inboxfer
Normal 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/$_");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user