Compare commits

...

No commits in common. "c8" and "c9-beta" have entirely different histories.
c8 ... c9-beta

30 changed files with 1878 additions and 1301 deletions

View File

@ -1,5 +1,4 @@
b537ecfca22df8a41f53d07d88d9547a1cb63d7d SOURCES/CHANGES.rpm
e39754f688d98ac0040df85e8850a2e330c6235d SOURCES/README.rpm
b3157c127c9cc404ecb2672e0eb4f18cac2a2a73 SOURCES/cassandane-00bfe01.tar.gz
fdbc28a259af65792e23ce8da16faf323039139c SOURCES/cassandane-testdata-20170523.tar.gz
49e3f8bbecd391513b81e3ccf49ea2df84be522f SOURCES/cyrus-imapd-3.0.7.tar.gz
616efd5bc85d00486a80c78a4d6cc12ebe07565f SOURCES/cassandane-693da61.tar.gz
fd08427d105d2306e95528eff407ab1723b31c69 SOURCES/cassandane-testdata-ca669d4b.tar.gz
8edfa3bca1f914ca30856e6f73d07e4de66173ed SOURCES/cyrus-imapd-3.4.1.tar.gz
7eefe4d240d7033b1f460f85038f6607154e58f4 SOURCES/cyrus-manpages-3.2.6.tar.gz

9
.gitignore vendored
View File

@ -1,5 +1,4 @@
SOURCES/CHANGES.rpm
SOURCES/README.rpm
SOURCES/cassandane-00bfe01.tar.gz
SOURCES/cassandane-testdata-20170523.tar.gz
SOURCES/cyrus-imapd-3.0.7.tar.gz
SOURCES/cassandane-693da61.tar.gz
SOURCES/cassandane-testdata-ca669d4b.tar.gz
SOURCES/cyrus-imapd-3.4.1.tar.gz
SOURCES/cyrus-manpages-3.2.6.tar.gz

34
SOURCES/README.rpm Normal file
View File

@ -0,0 +1,34 @@
---------------
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 installed 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 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. When
using a local account, this should be 'passwd cyrus'.
8) Make sure your MTA delivers to Cyrus IMAPd, I recommend LMTP for this.
9) Start Cyrus IMAPd with 'service cyrus-imapd start'
10) Run cyradm and create a user. Usually it's something like this:
'cyradm --user=cyrus --auth=login localhost'
11) If you're using sendmail, be aware that cyrusv2.m4 included in standard
sendmail distribution uses socket /var/imap/socket/lmtp while this rpm
uses /var/lib/imap/socket/lmtp.
12) Check your syslog configuration. This RPM uses the mail facility to log
messages. On busy sites you may want to limit the mail facility to the
info priority with something like 'mail.info /var/log/maillog' in
/etc/syslog.conf.
Enjoy!

View File

@ -1,30 +0,0 @@
diff --git a/imap/httpd.c b/imap/httpd.c
index 5dcf38dc4..d2fdeb945 100644
--- a/imap/httpd.c
+++ b/imap/httpd.c
@@ -1729,6 +1729,25 @@ static int examine_request(struct transaction_t *txn)
txn->auth_chal.scheme = NULL;
}
+ /* Drop auth credentials, if not a backend in a Murder */
+ else if (!config_mupdate_server || !config_getstring(IMAPOPT_PROXYSERVERS)) {
+ syslog(LOG_DEBUG, "drop auth creds");
+
+ free(httpd_userid);
+ httpd_userid = NULL;
+
+ free(httpd_extrafolder);
+ httpd_extrafolder = NULL;
+
+ free(httpd_extradomain);
+ httpd_extradomain = NULL;
+
+ if (httpd_authstate) {
+ auth_freestate(httpd_authstate);
+ httpd_authstate = NULL;
+ }
+ }
+
/* Perform proxy authorization, if necessary */
else if (saslprops.authid &&
(hdr = spool_getheader(txn->req_hdrs, "Authorize-As")) &&

View File

@ -1,13 +0,0 @@
diff --git a/imap/lmtp_sieve.c b/imap/lmtp_sieve.c
index 4c3bbc3..d0abdd3 100644
--- a/imap/lmtp_sieve.c
+++ b/imap/lmtp_sieve.c
@@ -999,7 +999,7 @@ static int autosieve_createfolder(const char *userid, const struct auth_state *a
if (createsievefolder) {
/* Folder is already in internal namespace format */
r = mboxlist_createmailbox(internalname, 0, NULL,
- 1, userid, auth_state, 0, 0, 0, 1, NULL);
+ 0, userid, auth_state, 0, 0, 0, 1, NULL);
if (!r) {
mboxlist_changesub(internalname, userid, auth_state, 1, 1, 1);
syslog(LOG_DEBUG, "autosievefolder: User %s, folder %s creation succeeded",

View File

@ -1,23 +0,0 @@
From 725e1efbd923c6d15ba639e17bfd0baabc619daa Mon Sep 17 00:00:00 2001
From: Pavel Zhukov <pzhukov@redhat.com>
Date: Mon, 1 Oct 2018 15:55:35 +0200
Subject: [PATCH] Close file descriptior in case of error
Make static code analizers happy.
If stat() failed for some reason it may lead backup fd unclosed.
---
backup/lcb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/backup/lcb.c b/backup/lcb.c
index 8c4a0e31a..9a04b08f2 100644
--- a/backup/lcb.c
+++ b/backup/lcb.c
@@ -182,6 +182,7 @@ HIDDEN int backup_real_open(struct backup **backupp,
if (r) {
syslog(LOG_ERR, "IOERROR: (f)stat %s: %m", backup->data_fname);
r = IMAP_IOERROR;
+ close(fd);
goto error;
}

View File

@ -1,38 +0,0 @@
From 5d00f649b4d2a599905d1b9290c91a769909741d Mon Sep 17 00:00:00 2001
From: Pavel Zhukov <pzhukov@redhat.com>
Date: Mon, 24 Sep 2018 17:24:48 +0200
Subject: [PATCH] Close backup on failure.
Static analizers report this as memory leak issue.
---
backup/ctl_backups.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/backup/ctl_backups.c b/backup/ctl_backups.c
index 3d817e743..e532eedb7 100644
--- a/backup/ctl_backups.c
+++ b/backup/ctl_backups.c
@@ -955,6 +955,7 @@ static int lock_run_pipe(const char *userid, const char *fname,
if (r) {
printf("NO failed (%s)\n", error_message(r));
+ r = backup_close(&backup);
return EC_SOFTWARE; // FIXME would something else be more appropriate?
}
@@ -993,6 +994,7 @@ static int lock_run_sqlite(const char *userid, const char *fname,
fprintf(stderr, "unable to lock %s: %s\n",
userid ? userid : fname,
error_message(r));
+ r = backup_close(&backup);
return EC_SOFTWARE;
}
@@ -1053,6 +1055,7 @@ static int lock_run_exec(const char *userid, const char *fname,
fprintf(stderr, "unable to lock %s: %s\n",
userid ? userid : fname,
error_message(r));
+ r = backup_close(&backup);
return EC_SOFTWARE;
}

View File

@ -1,26 +0,0 @@
diff --git a/imap/httpd.c b/imap/httpd.c
index dc53f8c..24b65e5 100644
--- a/imap/httpd.c
+++ b/imap/httpd.c
@@ -2202,7 +2202,7 @@ EXPORTED time_t calc_compile_time(const char *time, const char *date)
memset(&tm, 0, sizeof(struct tm));
tm.tm_isdst = -1;
sscanf(time, "%02d:%02d:%02d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
- sscanf(date, "%s %2d %4d", month, &tm.tm_mday, &tm.tm_year);
+ sscanf(date, "%3s %2d %4d", month, &tm.tm_mday, &tm.tm_year);
tm.tm_year -= 1900;
for (tm.tm_mon = 0; tm.tm_mon < 12; tm.tm_mon++) {
if (!strcmp(month, monthname[tm.tm_mon])) break;
diff --git a/imap/ical_support.c b/imap/ical_support.c
index 1d7550a..e1bda50 100644
--- a/imap/ical_support.c
+++ b/imap/ical_support.c
@@ -458,7 +458,7 @@ const char *get_icalcomponent_errstr(icalcomponent *ical)
/* Check if this is an empty property error */
if (sscanf(errstr,
- "No value for %s property", propname) == 1) {
+ "No value for %255s property", propname) == 1) {
/* Empty LOCATION is OK */
if (!strcasecmp(propname, "LOCATION")) continue;
if (!strcasecmp(propname, "COMMENT")) continue;

View File

@ -9,4 +9,4 @@ ConditionPathExists=!/etc/pki/cyrus-imapd/cyrus-imapd-ca.pem
Type=oneshot
Group=mail
RemainAfterExit=no
ExecStart=/usr/bin/sscg --package cyrus-imapd --cert-file /etc/pki/cyrus-imapd/cyrus-imapd.pem --cert-key-file /etc/pki/cyrus-imapd/cyrus-imapd-key.pem --ca-file /etc/pki/cyrus-imapd/cyrus-imapd-ca.pem --cert-key-mode=0640
ExecStart=/usr/bin/sscg --package cyrus-imapd --cert-file /etc/pki/cyrus-imapd/cyrus-imapd.pem --cert-key-file /etc/pki/cyrus-imapd/cyrus-imapd-key.pem --ca-file /etc/pki/cyrus-imapd/cyrus-imapd-ca.pem --cert-key-mode=0640

View File

@ -1,17 +0,0 @@
diff --git a/imap/cyr_expire.c b/imap/cyr_expire.c
index bcb40ea..747414a 100644
--- a/imap/cyr_expire.c
+++ b/imap/cyr_expire.c
@@ -628,9 +628,10 @@ int main(int argc, char *argv[])
}
if (do_user)
- mboxlist_usermboxtree(do_user, expire, &erock, MBOXTREE_DELETED);
+ mboxlist_usermboxtree(do_user, expire, &erock, MBOXTREE_DELETED|MBOXTREE_TOMBSTONES);
else
- mboxlist_allmbox(find_prefix, expire, &erock, 0);
+ mboxlist_allmbox(find_prefix, expire, &erock,
+ MBOXTREE_TOMBSTONES);
syslog(LOG_NOTICE, "Expired %lu and expunged %lu out of %lu "
"messages from %lu mailboxes",

View File

@ -1,66 +0,0 @@
diff --git a/Cassandane/Instance.pm b/cassandane/Cassandane/Instance.pm
index 1561143..c60396e 100644
--- a/Cassandane/Instance.pm
+++ b/Cassandane/Instance.pm
@@ -166,7 +166,7 @@ sub get_version
my $cyrus_master;
foreach my $d (qw( bin sbin libexec libexec/cyrus-imapd lib cyrus/bin ))
{
- my $try = "$cyrus_destdir$cyrus_prefix/$d/master";
+ my $try = "$cyrus_destdir$cyrus_prefix/$d/cyrus-master";
if (-x $try) {
$cyrus_master = $try;
last;
diff --git a/Cassandane/Instance.pm b/Cassandane/Instance.pm
index c60396e..7b2883a 100644
--- a/Cassandane/Instance.pm
+++ b/Cassandane/Instance.pm
@@ -546,7 +546,7 @@ sub _pid_file
{
my ($self, $name) = @_;
- $name ||= 'master';
+ $name ||= 'cyrus-master';
return $self->{basedir} . "/run/$name.pid";
}
@@ -569,7 +569,7 @@ sub _list_pid_files
closedir(RUNDIR);
@pidfiles = sort { $a cmp $b } @pidfiles;
- @pidfiles = ( 'master', grep { $_ ne 'master' } @pidfiles );
+ @pidfiles = ( 'cyrus-master', grep { $_ ne 'cyrus-master' } @pidfiles );
return @pidfiles;
}
@@ -877,7 +877,7 @@ sub _start_master
# Now start the master process.
my @cmd =
(
- 'master',
+ 'cyrus-master',
# The following is added automatically by _fork_command:
# '-C', $self->_imapd_conf(),
'-l', '255',
@@ -886,7 +886,7 @@ sub _start_master
'-M', $self->_master_conf(),
);
if (get_verbose) {
- my $logfile = $self->{basedir} . '/conf/master.log';
+ my $logfile = $self->{basedir} . '/conf/cyrus-master.log';
xlog "_start_master: logging to $logfile";
push(@cmd, '-L', $logfile);
}
diff --git a/Cassandane/Instance.pm b/Cassandane/Instance.pm
index 7b2883a..0c1e5fb 100644
--- a/Cassandane/Instance.pm
+++ b/Cassandane/Instance.pm
@@ -1301,7 +1301,7 @@ sub send_sighup
return if ($self->{_stopped});
xlog "sighup";
- my $pid = $self->_read_pid_file('master') or return;
+ my $pid = $self->_read_pid_file('cyrus-master') or return;
kill(SIGHUP, $pid) or die "Can't send signal SIGHUP to pid $pid: $!";
return 1;
}

View File

@ -1,73 +0,0 @@
From acfc393638ad1b81a4234173b060bb63907ee52c Mon Sep 17 00:00:00 2001
From: Pavel Zhukov <pzhukov@redhat.com>
Date: Mon, 1 Oct 2018 15:51:01 +0200
Subject: [PATCH] Replace simple return with cleanup flow
Make cleanup more consistence to prevent leaks of memory pointed by
filter/base/res
---
ptclient/ldap.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/ptclient/ldap.c b/ptclient/ldap.c
index 0b82d2c6b..65bae7bd6 100644
--- a/ptclient/ldap.c
+++ b/ptclient/ldap.c
@@ -1388,13 +1388,14 @@ static int ptsmodule_make_authstate_group(
if (strncmp(canon_id, "group:", 6)) { // Sanity check
*reply = "not a group identifier";
- return PTSM_FAIL;
+ rc = PTSM_FAIL;
+ goto done;
}
rc = ptsmodule_connect();
if (rc != PTSM_OK) {
*reply = "ptsmodule_connect() failed";
- return rc;
+ goto done;;
}
rc = ptsmodule_expand_tokens(ptsm->group_filter, canon_id+6, NULL, &filter);
@@ -1425,17 +1426,19 @@ static int ptsmodule_make_authstate_group(
if (rc != LDAP_SUCCESS) {
syslog(LOG_DEBUG, "(groups) Result from domain query not OK");
- return rc;
+ goto done;
} else {
syslog(LOG_DEBUG, "(groups) Result from domain query OK");
}
if (ldap_count_entries(ptsm->ld, res) < 1) {
syslog(LOG_ERR, "(groups) No domain %s found", domain);
- return PTSM_FAIL;
+ rc = PTSM_FAIL;
+ goto done;
} else if (ldap_count_entries(ptsm->ld, res) > 1) {
syslog(LOG_ERR, "(groups) Multiple domains %s found", domain);
- return PTSM_FAIL;
+ rc = PTSM_FAIL;
+ goto done;
} else {
syslog(LOG_DEBUG, "(groups) Domain %s found", domain);
if ((entry = ldap_first_entry(ptsm->ld, res)) != NULL) {
@@ -1452,7 +1455,7 @@ static int ptsmodule_make_authstate_group(
}
if (rc != PTSM_OK) {
- return rc;
+ goto done;
} else {
base = xstrdup(ptsm->group_base);
syslog(LOG_DEBUG, "Continuing with ptsm->group_base: %s", ptsm->group_base);
@@ -1462,7 +1465,7 @@ static int ptsmodule_make_authstate_group(
} else {
rc = ptsmodule_expand_tokens(ptsm->group_base, canon_id, NULL, &base);
if (rc != PTSM_OK)
- return rc;
+ goto done;
}
syslog(LOG_DEBUG, "(groups) about to search %s for %s", base, filter);

View File

@ -1,102 +0,0 @@
diff --git a/ptclient/ldap.c b/ptclient/ldap.c
index 7e48879..dafa724 100644
--- a/ptclient/ldap.c
+++ b/ptclient/ldap.c
@@ -932,7 +932,7 @@ static int ptsmodule_get_dn(
{
rc = ptsmodule_expand_tokens(ptsm->filter, canon_id, NULL, &filter);
if (rc != PTSM_OK)
- return rc;
+ goto done;
if (ptsm->domain_base_dn && ptsm->domain_base_dn[0] != '\0' && (strrchr(canon_id, '@') != NULL)) {
syslog(LOG_DEBUG, "Attempting to get domain for %s from %s", canon_id, ptsm->domain_base_dn);
@@ -955,19 +955,23 @@ static int ptsmodule_get_dn(
ldap_unbind(ptsm->ld);
ptsm->ld = NULL;
syslog(LOG_ERR, "LDAP not available: %s", ldap_err2string(rc));
- return PTSM_RETRY;
+ rc = PTSM_RETRY;
+ goto done;
}
syslog(LOG_ERR, "LDAP search for domain failed: %s", ldap_err2string(rc));
- return PTSM_FAIL;
+ rc = PTSM_FAIL;
+ goto done;
}
if (ldap_count_entries(ptsm->ld, res) < 1) {
syslog(LOG_ERR, "No domain %s found", domain);
- return PTSM_FAIL;
+ rc = PTSM_FAIL;
+ goto done;
} else if (ldap_count_entries(ptsm->ld, res) > 1) {
syslog(LOG_ERR, "Multiple domains %s found", domain);
- return PTSM_FAIL;
+ rc = PTSM_FAIL;
+ goto done;
} else {
if ((entry = ldap_first_entry(ptsm->ld, res)) != NULL) {
if ((vals = ldap_get_values(ptsm->ld, entry, ptsm->domain_result_attribute)) != NULL) {
@@ -982,7 +986,7 @@ static int ptsmodule_get_dn(
}
if (rc != PTSM_OK) {
- return rc;
+ goto done;
} else {
base = xstrdup(ptsm->base);
syslog(LOG_DEBUG, "Continuing with ptsm->base: %s", ptsm->base);
@@ -993,23 +997,23 @@ static int ptsmodule_get_dn(
} else {
rc = ptsmodule_expand_tokens(ptsm->base, canon_id, NULL, &base);
if (rc != PTSM_OK)
- return rc;
+ goto done;
}
rc = ldap_search_st(ptsm->ld, base, ptsm->scope, filter, attrs, 0, &(ptsm->timeout), &res);
if (rc != LDAP_SUCCESS) {
syslog(LOG_DEBUG, "Searching %s with %s failed", base, base);
- free(filter);
- free(base);
if (rc == LDAP_SERVER_DOWN) {
ldap_unbind(ptsm->ld);
ptsm->ld = NULL;
- return PTSM_RETRY;
+ rc = PTSM_RETRY;
+ goto done;
}
- return PTSM_FAIL;
+ rc = PTSM_FAIL;
+ goto done;
}
free(filter);
@@ -1035,6 +1039,13 @@ static int ptsmodule_get_dn(
}
return (*ret ? PTSM_OK : PTSM_FAIL);
+
+ done:
+ if (filter)
+ free(filter);
+ if (base)
+ free(base);
+ return rc;
}
@@ -1344,7 +1355,7 @@ static int ptsmodule_make_authstate_group(
rc = ptsmodule_connect();
if (rc != PTSM_OK) {
*reply = "ptsmodule_connect() failed";
- goto done;;
+ goto done;
}
rc = ptsmodule_expand_tokens(ptsm->group_filter, canon_id+6, NULL, &filter);

View File

@ -1,68 +0,0 @@
diff --git a/lib/imapoptions b/lib/imapoptions
index 37f8371..898b943 100644
--- a/lib/imapoptions
+++ b/lib/imapoptions
@@ -2207,12 +2207,12 @@ product version in the capabilities
{ "tls_cert_file", NULL, STRING, "2.5.0", "tls_server_cert" }
/* Deprecated in favor of \fItls_server_cert\fR. */
-{ "tls_cipher_list", "DEFAULT", STRING, "2.5.0", "tls_ciphers" }
+{ "tls_cipher_list", "PROFILE=SYSTEM", STRING, "2.5.0", "tls_ciphers" }
/* Deprecated in favor of \fItls_ciphers\fR. */
-{ "tls_ciphers", "DEFAULT", STRING }
+{ "tls_ciphers", "PROFILE=SYSTEM", STRING }
/* The list of SSL/TLS ciphers to allow. The format of the string
- (and definition of "DEFAULT") is described in \fBciphers(1)\fR.
+ (and definition of "PROFILE=SYSTEM") is described in \fBciphers(1)\fR.
.PP
See also Mozilla's server-side TLS recommendations:
.PP
diff --git a/doc/html/_sources/imap/reference/manpages/configs/imapd.conf.txt b/doc/html/_sources/imap/reference/manpages/configs/imapd.conf.txt
index c45d94b..495a2c7 100644
--- a/doc/html/_sources/imap/reference/manpages/configs/imapd.conf.txt
+++ b/doc/html/_sources/imap/reference/manpages/configs/imapd.conf.txt
@@ -4298,7 +4298,7 @@ FIELD DESCRIPTIONS
.. startblob tls_cipher_list
- ``tls_cipher_list:`` DEFAULT
+ ``tls_cipher_list:`` PROFILE=SYSTEM
Deprecated in favor of *tls_ciphers*.
@@ -4307,10 +4307,10 @@ FIELD DESCRIPTIONS
.. startblob tls_ciphers
- ``tls_ciphers:`` DEFAULT
+ ``tls_ciphers:`` PROFILE=SYSTEM
The list of SSL/TLS ciphers to allow. The format of the string
- (and definition of "DEFAULT") is described in **ciphers(1)**.
+ (and definition of "PROFILE=SYSTEM") is described in **ciphers(1)**.
See also Mozilla's server-side TLS recommendations:
diff --git a/doc/text/imap/reference/manpages/configs/imapd.conf.txt b/doc/text/imap/reference/manpages/configs/imapd.conf.txt
index 1801cd7..7c77154 100644
--- a/doc/text/imap/reference/manpages/configs/imapd.conf.txt
+++ b/doc/text/imap/reference/manpages/configs/imapd.conf.txt
@@ -2675,14 +2675,14 @@ FIELD DESCRIPTIONS
Deprecated in favor of *tls_server_cert*.
- "tls_cipher_list:" DEFAULT
+ "tls_cipher_list:" PROFILE=SYSTEM
Deprecated in favor of *tls_ciphers*.
- "tls_ciphers:" DEFAULT
+ "tls_ciphers:" PROFILE=SYSTEM
The list of SSL/TLS ciphers to allow. The format of the string
- (and definition of "DEFAULT") is described in **ciphers(1)**.
+ (and definition of "PROFILE=SYSTEM") is described in **ciphers(1)**.
See also Mozilla's server-side TLS recommendations:

View File

@ -1,409 +0,0 @@
#!/bin/bash
# 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
#
# v1.0.13, Jul 15 2005 Simon Matter <simon.matter@invoca.ch>
# - don't use flat in the two step conversion, use skiplist instead
#
# v1.0.14, Jul 18 2005 Simon Matter <simon.matter@invoca.ch>
# - replace the order of the magic files in the file call to make
# sure skiplist is detected correctly.
#
# v1.0.15, Aug 17 2005 Simon Matter <simon.matter@invoca.ch>
# - add functionality to export all berkeley db files to skiplist
#
# v1.1.0, Aug 18 2005 Simon Matter <simon.matter@invoca.ch>
# - fix export functionality, try to recover Berkeley databases
# as much as possible before any conversion.
#
# v1.1.1, Dec 05 2005 Simon Matter <simon.matter@invoca.ch>
# - run db_checkpoint in background with a timeout to prevent
# that cyrus-imapd doesn't start at all if it hangs.
#
# v1.1.2, Dec 06 2005 Simon Matter <simon.matter@invoca.ch>
# - make handling of db_checkpoint more robust
#
# v1.2.0, Jan 12 2006 Simon Matter <simon.matter@invoca.ch>
# - adopt for cyrus-imapd-2.3
#
# v1.2.1, Jan 13 2006 Simon Matter <simon.matter@invoca.ch>
# - code cleanup
#
# v1.2.2, Nov 29 2007 Simon Matter <simon.matter@invoca.ch>
# - add ability to handle "@include" options in imapd.conf, patch
# provided by Tim Bannister
#
# v1.2.3, Feb 07 2008 Simon Matter <simon.matter@invoca.ch>
# - add ability to handle tabs in imapd.conf, patch provided
# by Franz Knipp
# - disable default values for some config options like sievedir
#
# v1.2.4, Apr 23 2008 Simon Matter <simon.matter@invoca.ch>
# - add support for statuscache.db
#
# v1.3.0, Sep 29 2008 Simon Matter <simon.matter@invoca.ch>
# - add multi-instance support
#
# v1.3.1, Oct 09 2008 Simon Matter <simon.matter@invoca.ch>
# - improve variable handling
#
# v1.3.2, May 26 2009 Simon Matter <simon.matter@invoca.ch>
# - add some sanity checks to multi-instance support
#
# v1.3.3, May 27 2009 Simon Matter <simon.matter@invoca.ch>
# - make some cosmetic changes
#
# v1.3.4, Dec 22 2009 Simon Matter <simon.matter@invoca.ch>
# - add support for user_deny.db
VERSION=1.3.4
PIDFILE=/var/run/cyrus-master${INSTANCE}.pid
# instance config
CYRUSCONF=/etc/cyrus${INSTANCE}.conf
IMAPDCONF=/etc/imapd${INSTANCE}.conf
# make sure what we have is a valid instance
# and that config files are present
if [ -n "$INSTANCE" ]; then
[ -L /etc/rc.d/init.d/${BASENAME} ] || exit 0
fi
[ -f $CYRUSCONF ] || exit 0
[ -f $IMAPDCONF ] || exit 0
if [ -f $PIDFILE ]; then
read CYRUS_PID < $PIDFILE
if [ -n "$CYRUS_PID" ]; then
if ps -p $CYRUS_PID > /dev/null 2>&1; then
echo "ERROR: cyrus-master is running, unable to convert mailboxes!"
exit 1
fi
fi
fi
if [ ! -f $IMAPDCONF ]; then
echo "ERROR: configuration file '${IMAPDCONF}' not found, exiting!"
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 ; INSTANCE=$INSTANCE $0 $*"
fi
# special function for migration
EXPORT=$1
# files get mode 0600
umask 166
# show version info in log files
echo "cvt_cyrusdb_all version: $VERSION"
# expand_config <path>
# handle "@include" sections from imapd style config file
expand_config() {
while read line; do
if printf "%s\n" "${line}" | grep -q '^@include:'; then
expand_config "$( printf "%s\n" "${line}" | cut -d : -f 2- | sed -e 's/^[\t ]*//' )"
else
printf "%s\n" "${line}"
fi
done < $1
}
# get_config <config> [<default>]
# extracts config option from config file
get_config() {
searchstr=$1
if config="$(expand_config $IMAPDCONF | egrep "^${searchstr}:")"; then
CFGVAL="$(printf "%s\n" "$config" | cut -d : -f 2- | sed -e 's/^[\t ]*//')"
else
if [ -z "$2" ]; then
echo "ERROR: config option '$1' not found in ${IMAPDCONF}, exiting!" 1>&2
return 1
fi
CFGVAL="$2"
fi
echo "get_config ${1}: $CFGVAL" 1>&2
echo "$CFGVAL"
}
# where to find files and directories
data_dir=/usr/share/cyrus-imapd/rpm
lib_dir=/usr/lib/cyrus-imapd
system_magic=$(file --version | awk '/magic file/ {print $4}')
cyrus_magic=${data_dir}/magic
cvt_cyrusdb=${lib_dir}/cvt_cyrusdb
sievec=${lib_dir}/sievec
masssievec=${lib_dir}/masssievec
imap_prefix=$(get_config configdirectory) || exit 1
sieve_dir=$(get_config sievedir) || exit 1
db_cfg=${data_dir}/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
duplicate_db=$(get_config duplicate_db $duplicate_db) || exit 1
mboxlist_db=$(get_config mboxlist_db $mboxlist_db) || exit 1
seenstate_db=$(get_config seenstate_db $seenstate_db) || exit 1
subscription_db=$(get_config subscription_db $subscription_db) || exit 1
tlscache_db=$(get_config tlscache_db $tlscache_db) || exit 1
annotation_db=$(get_config annotation_db $annotation_db) || exit 1
mboxkey_db=$(get_config mboxkey_db $mboxkey_db) || exit 1
ptscache_db=$(get_config ptscache_db $ptscache_db) || exit 1
quota_db=$(get_config quota_db $quota_db) || exit 1
statuscache_db=$(get_config statuscache_db $statuscache_db) || exit 1
userdeny_db=$(get_config userdeny_db $userdeny_db) || exit 1
# remember current db backend config
{
echo "duplicate_db=${duplicate_db}"
echo "mboxlist_db=${mboxlist_db}"
echo "seenstate_db=${seenstate_db}"
echo "subscription_db=${subscription_db}"
echo "tlscache_db=${tlscache_db}"
echo "annotation_db=${annotation_db}"
echo "mboxkey_db=${mboxkey_db}"
echo "ptscache_db=${ptscache_db}"
echo "quota_db=${quota_db}"
echo "statuscache_db=${statuscache_db}"
echo "userdeny_db=${userdeny_db}"
echo "sieve_version=${sieve_version}"
} | sort > $db_current
# file_type <file>
file_type() {
this_type=$(file -b -m "${cyrus_magic}:${system_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}.skiplist"
if [ "$old_db" = "skiplist" ]; then
cp -a "$target" "${target}.skiplist"
else
$cvt_cyrusdb -C $IMAPDCONF "$target" "$old_db" "${target}.skiplist" skiplist
fi
RETVAL=$?
ERRVAL=$(( $ERRVAL + $RETVAL ))
if [ $RETVAL -eq 0 ]; then
rm -f "$target"
if [ -s "${target}.skiplist" ]; then
if [ "$new_db" = "skiplist" ]; then
cp -a "${target}.skiplist" "$target"
else
$cvt_cyrusdb -C $IMAPDCONF "${target}.skiplist" skiplist "$target" "$new_db"
fi
fi
RETVAL=$?
ERRVAL=$(( $ERRVAL + $RETVAL ))
if [ $RETVAL -eq 0 ]; then
rm -f "${target}.skiplist"
else
echo "ERROR: unable to convert ${target}.skiplist from skiplist to $new_db"
fi
else
echo "ERROR: unable to convert $target from $old_db to skiplist"
fi
fi
fi
}
# cvt_to_utf8 <file>
cvt_to_utf8() {
target="$1"
if [ -s "$target" ]; then
if ! $sievec -C $IMAPDCONF "$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
# make sure our Berkeley databases are in a sane state
# wait for db_checkpoint to end successfully or kill it after a timeout
db_checkpoint -v -1 -h ${imap_prefix}/db &
DB_CHECK_PID=$!
CNT=0
while [ $CNT -lt 60 ]; do
if ! kill -0 $DB_CHECK_PID > /dev/null 2>&1; then
break
fi
sleep 1
let CNT+=1
done
if kill -0 $DB_CHECK_PID > /dev/null 2>&1; then
kill -USR1 $DB_CHECK_PID > /dev/null 2>&1
sleep 1
kill -KILL $DB_CHECK_PID > /dev/null 2>&1
wait $DB_CHECK_PID > /dev/null 2>&1
fi
# do a normal recovery
db_recover -v -h ${imap_prefix}/db
RETVAL=$?
if [ $RETVAL -ne 0 ]; then
# try a catastrophic recovery instead of normal recovery
db_recover -v -c -h ${imap_prefix}/db
RETVAL=$?
ERRVAL=$(( $ERRVAL + $RETVAL ))
if [ $RETVAL -ne 0 ]; then
echo "ERROR: catastrophic recovery of Berkeley databases failed"
fi
fi
if [ "$EXPORT" = "export" ]; then
# convert all db files to portable format for migration
# TODO: quota_db, we don't touch it for now
cvt_file ${imap_prefix}/deliver.db "skiplist"
cvt_file ${imap_prefix}/mailboxes.db "skiplist"
cvt_file ${imap_prefix}/tls_sessions.db "skiplist"
cvt_file ${imap_prefix}/annotations.db "skiplist"
cvt_file ${imap_prefix}/ptclient/ptscache.db "skiplist"
cvt_file ${imap_prefix}/statuscache.db "skiplist"
cvt_file ${imap_prefix}/user_deny.db "flat"
rm -vf ${imap_prefix}/db/log.*
rm -vf ${imap_prefix}/db/__db.*
else
# always convert db files which have been converted to skiplist
# TODO: quota_db, we don't touch it for now
cvt_file ${imap_prefix}/deliver.db "$duplicate_db"
cvt_file ${imap_prefix}/mailboxes.db "$mboxlist_db"
cvt_file ${imap_prefix}/tls_sessions.db "$tlscache_db"
cvt_file ${imap_prefix}/annotations.db "$annotation_db"
cvt_file ${imap_prefix}/ptclient/ptscache.db "$ptscache_db"
cvt_file ${imap_prefix}/statuscache.db "$statuscache_db"
cvt_file ${imap_prefix}/user_deny.db "$userdeny_db"
# do we have to convert all 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
$masssievec $sievec $IMAPDCONF
# convert all db files left
find ${imap_prefix}/user/ -name "*.seen" -type f | while read db_file trash; do
cvt_file "$db_file" "$seenstate_db"
done
find ${imap_prefix}/user/ -name "*.sub" -type f | while read db_file trash; do
cvt_file "$db_file" "$subscription_db"
done
find ${imap_prefix}/user/ -name "*.mboxkey" -type f | while read db_file trash; do
cvt_file "$db_file" "$mboxkey_db"
done
fi
fi
# update the config cache file so we can check whether something has changed
if [ $ERRVAL -eq 0 ]; then
mv -f $db_current $db_cache
else
rm -f $db_cache
rm -f $db_current
fi
exit $ERRVAL

View File

@ -8,7 +8,8 @@ After=cyrus-imapd-init.service
[Service]
Type=simple
EnvironmentFile=/etc/sysconfig/cyrus-imapd
ExecStart=/usr/libexec/cyrus-imapd/cyrus-master $CYRUSOPTIONS
ExecStart=/usr/libexec/cyrus-imapd/master $CYRUSOPTIONS
ExecReload=/bin/kill -HUP $MAINPID
PrivateTmp=true
# Cyrus may spawn many processes in normal operation. These figures are higher

View File

@ -0,0 +1,5 @@
#Type Name ID GECOS Home directory Shell
g saslauth 76
g mail 12
u cyrus 76:mail "Cyrus IMAP Server" /var/lib/imap /sbin/nologin
m cyrus saslauth

View File

@ -1,14 +1,14 @@
diff --git a/utils/annotator.pl b/utils/annotator.pl
index 94b84a2..0208831 100755
index 265c73f..8af3d58 100755
--- a/utils/annotator.pl
+++ b/utils/annotator.pl
@@ -140,6 +140,8 @@ GetOptions(
xlog "annotator $$ starting";
Cassandane::AnnotatorDaemon->run(
pid_file => $pidfile,
- port => $port
pid_file => $pidfile,
- port => $port
+ port => $port,
+ user => (getpwuid($<))[0],
+ group => (getgrgid($())[0],
+ user => (getpwuid($<))[0],
+ group => (getgrgid($())[0],
);
xlog "annotator $$ exiting";

View File

@ -1,8 +1,8 @@
diff --git a/Cassandane/Util/Log.pm b/Cassandane/Util/Log.pm
index 9cd93d5..8d3b3c1 100644
index 17d2cc7..11b747f 100644
--- a/Cassandane/Util/Log.pm
+++ b/Cassandane/Util/Log.pm
@@ -52,16 +52,12 @@ our @EXPORT = qw(
@@ -51,9 +51,6 @@ our @EXPORT = qw(
my $verbose = 0;
@ -11,11 +11,31 @@ index 9cd93d5..8d3b3c1 100644
-
sub xlog
{
my ($pkg, $file, $line) = caller;
$pkg =~ s/^Cassandane:://;
my $msg = "=====> " . $pkg . "[" . $line . "] " . join(' ', @_);
my $id;
@@ -70,7 +67,6 @@ sub xlog
$msg .= "($id) " if $id;
$msg .= join(' ', @_);
print STDERR "$msg\n";
- syslog(LOG_ERR, "$msg");
}
sub set_verbose
diff --git a/Cassandane/Instance.pm b/Cassandane/Instance.pm
index bdfa44f..e852599 100644
--- a/Cassandane/Instance.pm
+++ b/Cassandane/Instance.pm
@@ -2030,12 +2030,8 @@ sub setup_syslog_replacement
{
my ($self) = @_;
- if (not(-e 'utils/syslog.so') || not(-e 'utils/syslog_probe')) {
- xlog "utils/syslog.so not found (do you need to run 'make'?)";
- xlog "tests will not examine syslog output";
- $self->{have_syslog_replacement} = 0;
- return;
- }
+ $self->{have_syslog_replacement} = 0;
+ return;
$self->{syslog_fname} = "$self->{basedir}/conf/log/syslog";
$self->{have_syslog_replacement} = 1;

View File

@ -0,0 +1,78 @@
diff --git a/Cassandane/Cyrus/Flags.pm b/Cassandane/Cyrus/Flags.pm
index a61d256..eedaf40 100644
--- a/Cassandane/Cyrus/Flags.pm
+++ b/Cassandane/Cyrus/Flags.pm
@@ -239,6 +239,73 @@ sub test_seen_otheruser
$self->check_messages(\%msg);
}
+# https://github.com/cyrusimap/cyrus-imapd/issues/3240
+sub test_seen_sharedmb_nosharedseen
+ :UnixHierarchySep :AltNamespace
+{
+ my ($self) = @_;
+
+ my $folder = 'shared';
+
+ # shared mailbox with sharedseen=false
+ my $admintalk = $self->{adminstore}->get_client();
+ $admintalk->create($folder);
+ $self->assert_str_equals('ok', $admintalk->get_last_completion_response());
+ $admintalk->setacl('shared', 'cassandane' => 'lrswipkxtecdan');
+ $self->assert_str_equals('ok', $admintalk->get_last_completion_response());
+ $admintalk->setmetadata($folder,
+ '/shared/vendor/cmu/cyrus-imapd/sharedseen' => 'false'
+ );
+ $self->assert_str_equals('ok', $admintalk->get_last_completion_response());
+
+
+ # add some messages
+ my $talk = $self->{store}->get_client();
+ $self->{store}->set_folder("Shared Folders/$folder");
+ $self->{store}->_select();
+ $self->assert_num_equals(1, $talk->uid());
+ $self->{store}->set_fetch_attributes(qw(uid flags));
+
+ xlog $self, "Add two messages";
+ my %msg;
+ $msg{A} = $self->make_message('Message A');
+ $msg{A}->set_attributes(id => 1,
+ uid => 1,
+ flags => []);
+ $msg{B} = $self->make_message('Message B');
+ $msg{B}->set_attributes(id => 2,
+ uid => 2,
+ flags => []);
+ $self->check_messages(\%msg);
+
+ # fiddle with seen flag, making sure we get both the expected results
+ # and the expected untagged fetch response
+ xlog $self, "Set \\Seen on message A";
+ my $res = $talk->store('1', '+flags', '(\\Seen)');
+ $self->assert_deep_equals({ '1' => { 'flags' => [ '\\Seen' ] }}, $res);
+ $msg{A}->set_attribute(flags => ['\\Seen']);
+ $self->check_messages(\%msg);
+
+ xlog $self, "Clear \\Seen on message A";
+ $res = $talk->store('1', '-flags', '(\\Seen)');
+ $self->assert_deep_equals({ '1' => { 'flags' => [] }}, $res);
+ $msg{A}->set_attribute(flags => []);
+ $self->check_messages(\%msg);
+
+ xlog $self, "Set \\Seen on message A again";
+ $res = $talk->store('1', '+flags', '(\\Seen)');
+ $self->assert_deep_equals({ '1' => { 'flags' => [ '\\Seen' ] }}, $res);
+ $msg{A}->set_attribute(flags => ['\\Seen']);
+ $self->check_messages(\%msg);
+
+ # seen flag should survive a reconnect
+ xlog $self, "Reconnect, \\Seen should still be on message A";
+ $self->{store}->disconnect();
+ $self->{store}->connect();
+ $self->{store}->_select();
+ $self->check_messages(\%msg);
+}
+
#
# Test that
# - the \Flagged flag can be set

View File

@ -1,27 +1,40 @@
diff --git a/imap/http_dav.c b/imap/http_dav.c
index 91bbc28b6b..a6fa5c8345 100644
index d5f7c114a2..abc6da42ca 100644
--- a/imap/http_dav.c
+++ b/imap/http_dav.c
@@ -5494,7 +5494,7 @@ EXPORTED int meth_propfind(struct transaction_t *txn, void *params)
@@ -6108,7 +6108,7 @@ EXPORTED int meth_propfind(struct transaction_t *txn, void *params)
xmlDocPtr indoc = NULL, outdoc = NULL;
xmlNodePtr root, cur = NULL, props = NULL;
xmlNsPtr ns[NUM_NAMESPACE];
- struct hash_table ns_table = { 0, NULL, NULL };
+ struct hash_table ns_table = HASH_TABLE_INITIALIZER;
struct propfind_ctx fctx;
struct propfind_entry_list *elist = NULL;
@@ -7900,7 +7900,7 @@ int meth_report(struct transaction_t *txn, void *params)
memset(&fctx, 0, sizeof(struct propfind_ctx));
@@ -8083,7 +8083,7 @@ int meth_report(struct transaction_t *txn, void *params)
xmlNodePtr inroot = NULL, outroot = NULL, cur, prop = NULL, props = NULL;
const struct report_type_t *report = NULL;
xmlNsPtr ns[NUM_NAMESPACE];
- struct hash_table ns_table = { 0, NULL, NULL };
+ struct hash_table ns_table = HASH_TABLE_INITIALIZER;
struct propfind_ctx fctx;
struct propfind_entry_list *elist = NULL;
memset(&fctx, 0, sizeof(struct propfind_ctx));
diff --git a/imap/jmap_mail.c b/imap/jmap_mail.c
index 7f2d9cb563..84845d273b 100644
--- a/imap/jmap_mail.c
+++ b/imap/jmap_mail.c
@@ -4334,7 +4334,7 @@ static void _email_querychanges_collapsed(jmap_req_t *req,
memset(&touched_ids, 0, sizeof(hash_table));
construct_hash_table(&touched_ids, mdcount + 1, 0);
- hashu64_table touched_cids = HASH_TABLE_INITIALIZER;
+ hashu64_table touched_cids = HASHU64_TABLE_INITIALIZER;
memset(&touched_cids, 0, sizeof(hashu64_table));
construct_hashu64_table(&touched_cids, mdcount + 1, 0);
diff --git a/lib/hash.c b/lib/hash.c
index 9703142c3b..84f2e80d28 100644
index 639b6997e6..593f1bf968 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -43,10 +43,11 @@ EXPORTED hash_table *construct_hash_table(hash_table *table, size_t size, int us
@ -47,74 +60,26 @@ index 9703142c3b..84f2e80d28 100644
bucket *ptr, *newptr;
bucket **prev;
@@ -153,9 +154,14 @@ EXPORTED void *hash_insert(const char *key, void *data, hash_table *table)
@@ -159,7 +160,7 @@ EXPORTED void *hash_lookup(const char *key, hash_table *table)
if (!table->size)
return NULL;
EXPORTED void *hash_lookup(const char *key, hash_table *table)
{
- unsigned val = strhash(key) % table->size;
+ unsigned val;
bucket *ptr;
+ if (!table->size)
+ return NULL;
+
- val = strhash(key) % table->size;
+ val = strhash_seeded(table->seed, key) % table->size;
+
if (!(table->table)[val])
return NULL;
@@ -178,8 +184,7 @@ EXPORTED void *hash_lookup(const char *key, hash_table *table)
@@ -183,7 +184,7 @@ EXPORTED void *hash_lookup(const char *key, hash_table *table)
* since it will leak memory until you get rid of the entire hash table */
EXPORTED void *hash_del(const char *key, hash_table *table)
{
- unsigned val = strhash(key) % table->size;
- void *data;
+ unsigned val = strhash_seeded(table->seed, key) % table->size;
bucket *ptr, *last = NULL;
if (!(table->table)[val])
@@ -200,15 +205,10 @@ EXPORTED void *hash_del(const char *key, hash_table *table)
int cmpresult = strcmp(key, ptr->key);
if (!cmpresult)
{
+ void *data = ptr->data;
if (last != NULL )
{
- data = ptr -> data;
last -> next = ptr -> next;
- if(!table->pool) {
- free(ptr->key);
- free(ptr);
- }
- return data;
}
/*
@@ -221,15 +221,15 @@ EXPORTED void *hash_del(const char *key, hash_table *table)
else
{
- data = ptr->data;
(table->table)[val] = ptr->next;
- if(!table->pool) {
- free(ptr->key);
- free(ptr);
- }
- return data;
}
- } else if (cmpresult < 0) {
+ if(!table->pool) {
+ free(ptr->key);
+ free(ptr);
+ }
+ return data;
+ }
+ if (cmpresult < 0) {
/* its not here! */
return NULL;
}
diff --git a/lib/hash.h b/lib/hash.h
index 8051ac1760..cfa7da1ffa 100644
index e49037d614..e476de77da 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -3,10 +3,11 @@

View File

@ -1,27 +1,3 @@
diff --git a/doc/examples/cyrus_conf/prefork.conf b/doc/examples/cyrus_conf/prefork.conf
index 4ce2c0f..3b1e6d7 100644
--- a/doc/examples/cyrus_conf/prefork.conf
+++ b/doc/examples/cyrus_conf/prefork.conf
@@ -19,15 +19,15 @@ SERVICES {
# nntps cmd="nntpd -s" listen="nntps" prefork=1
# these are only necessary if using HTTP for CalDAV, CardDAV, or RSS
-# http cmd="httpd" listen="http" prefork=3
-# https cmd="httpd -s" listen="https" prefork=1
+ http cmd="httpd" listen="http" prefork=3
+ https cmd="httpd -s" listen="https" prefork=1
# at least one LMTP is required for delivery
# lmtp cmd="lmtpd" listen="lmtp" prefork=0
- lmtpunix cmd="lmtpd" listen="/var/imap/socket/lmtp" prefork=1
+ lmtpunix cmd="lmtpd" listen="/run/cyrus/socket/lmtp" prefork=1
# this is only necessary if using notifications
-# notify cmd="notifyd" listen="/var/imap/socket/notify" proto="udp" prefork=1
+# notify cmd="notifyd" listen="/run/cyrus/socket/notify" proto="udp" prefork=1
}
EVENTS {
diff --git a/doc/examples/imapd_conf/normal.conf b/doc/examples/imapd_conf/normal.conf
index 95b54e9..3935b77 100644
--- a/doc/examples/imapd_conf/normal.conf
@ -67,8 +43,8 @@ index 95b54e9..3935b77 100644
-#
-# Allowed values: caldav, carddav, domainkey, ischedule, rss
-httpmodules: caldav carddav
+# Enable supported modules
+httpmodules: caldav carddav
+# Fedora default: enable all modules besides admin and tzdist
+httpmodules: caldav carddav domainkey freebusy ischedule rss webdav
# If enabled, the partitions will also be hashed, in addition to the
# hashing done on configuration directories. This is recommended if one
@ -112,3 +88,18 @@ index 95b54e9..3935b77 100644
# File containing the global certificate used for ALL services (imap,
# pop3, lmtp, sieve)
#tls_server_cert: /etc/ssl/certs/ssl-cert-snakeoil.pem
diff --git a/doc/examples/cyrus_conf/prefork.conf b/doc/examples/cyrus_conf/prefork.conf
index 186fe66..ab97848 100644
--- a/doc/examples/cyrus_conf/prefork.conf
+++ b/doc/examples/cyrus_conf/prefork.conf
@@ -19,8 +19,8 @@ SERVICES {
# nntps cmd="nntpd -s" listen="nntps" prefork=1
# these are only necessary if using HTTP for CalDAV, CardDAV, or RSS
-# http cmd="httpd" listen="http" prefork=3
-# https cmd="httpd -s" listen="https" prefork=1
+ http cmd="httpd" listen="http" prefork=3
+ https cmd="httpd -s" listen="https" prefork=1
# at least one LMTP is required for delivery
# lmtp cmd="lmtpd" listen="lmtp" prefork=0

View File

@ -0,0 +1,25 @@
commit a8ccdaf109b85cedfd609678d95f7b7d5fdb91f5
Author: ellie timoney <ellie@fastmail.com>
Date: Mon Jun 7 12:00:27 2021 +1000
lmtpd: shared mailboxes don't have conversations to lock
Fixes #3488
diff --git a/imap/lmtpd.c b/imap/lmtpd.c
index 498bb8765..dc9ca21bc 100644
--- a/imap/lmtpd.c
+++ b/imap/lmtpd.c
@@ -843,8 +843,10 @@ int deliver(message_data_t *msgdata, char *authuser,
// lock conversations for the duration of delivery, so nothing else can read
// the state of any mailbox while the delivery is half done
struct conversations_state *state = NULL;
- r = conversations_open_user(mbname_userid(mbname), 0/*shared*/, &state);
- if (r) goto setstatus;
+ if (mbname_userid(mbname)) {
+ r = conversations_open_user(mbname_userid(mbname), 0/*shared*/, &state);
+ if (r) goto setstatus;
+ }
/* local mailbox */
mydata.cur_rcpt = n;

View File

@ -1,13 +0,0 @@
diff --git a/perl/sieve/managesieve/Makefile.PL.in b/perl/sieve/managesieve/Makefile.PL.in
index 2bb715d..422504d 100644
--- a/perl/sieve/managesieve/Makefile.PL.in
+++ b/perl/sieve/managesieve/Makefile.PL.in
@@ -69,7 +69,7 @@ WriteMakefile(
'ABSTRACT' => 'Cyrus Sieve management interface',
'VERSION_FROM' => "@top_srcdir@/perl/sieve/managesieve/managesieve.pm", # finds $VERSION
'MYEXTLIB' => '../lib/.libs/libisieve.a @top_builddir@/perl/.libs/libcyrus.a @top_builddir@/perl/.libs/libcyrus_min.a',
- 'LIBS' => ["$LIB_SASL @SSL_LIBS@ @LIB_UUID@ @ZLIB@"],
+ 'LIBS' => ["$LIB_SASL @SSL_LIBS@ @LIB_UUID@ @ZLIB@ -lsqlite3 -lpq -lmariadb"],
'CCFLAGS' => '@GCOV_CFLAGS@',
'DEFINE' => '-DPERL_POLLUTE', # e.g., '-DHAVE_SOMETHING'
'INC' => "-I@top_srcdir@/lib -I@top_srcdir@/perl/sieve -I@top_srcdir@/perl/sieve/lib @SASLFLAGS@ @SSL_CPPFLAGS@",

View File

@ -0,0 +1,26 @@
diff --git a/perl/sieve/managesieve/Makefile.PL.in b/perl/sieve/managesieve/Makefile.PL.in
index 7180b98..d589ebe 100644
--- a/perl/sieve/managesieve/Makefile.PL.in
+++ b/perl/sieve/managesieve/Makefile.PL.in
@@ -69,7 +69,7 @@ WriteMakefile(
'ABSTRACT' => 'Cyrus Sieve management interface',
'VERSION_FROM' => "@top_srcdir@/perl/sieve/managesieve/managesieve.pm", # finds $VERSION
'MYEXTLIB' => '../lib/.libs/libisieve.a @top_builddir@/perl/.libs/libcyrus.a @top_builddir@/perl/.libs/libcyrus_min.a',
- 'LIBS' => ["$LIB_SASL @SSL_LIBS@ @LIB_UUID@ @LIB_REGEX@ @ZLIB@ @SQLITE_LIBADD@ @MYSQL_LIBADD@ @PGSQL_LIBADD@"],
+ 'LIBS' => ["$LIB_SASL @SSL_LIBS@ @LIB_UUID@ @LIB_REGEX@ @ZLIB@ @SQLITE_LIBADD@ @MYSQL_LIBADD@ @PGSQL_LIBADD@ -lpcreposix"],
'CCFLAGS' => '@GCOV_CFLAGS@',
'DEFINE' => '-DPERL_POLLUTE', # e.g., '-DHAVE_SOMETHING'
'INC' => "-I@top_srcdir@/lib -I@top_srcdir@/perl/sieve -I@top_srcdir@/perl/sieve/lib @SASLFLAGS@ @SSL_CPPFLAGS@",
diff --git a/perl/imap/Makefile.PL.in b/perl/imap/Makefile.PL.in
index 71416cc..f76cda6 100644
--- a/perl/imap/Makefile.PL.in
+++ b/perl/imap/Makefile.PL.in
@@ -91,7 +91,7 @@ WriteMakefile(
'LD' => $Config{ld} . ' @GCOV_LDFLAGS@',
'OBJECT' => 'IMAP.o',
'MYEXTLIB' => '@top_builddir@/perl/.libs/libcyrus.a @top_builddir@/perl/.libs/libcyrus_min.a',
- 'LIBS' => [ "$LIB_SASL @SSL_LIBS@ @LIB_UUID@ @ZLIB@ @GCOV_LIBS@ @LIBCAP_LIBS@"],
+ 'LIBS' => [ "$LIB_SASL @SSL_LIBS@ @LIB_UUID@ @ZLIB@ @GCOV_LIBS@ @LIBCAP_LIBS@ -lpcreposix"],
'DEFINE' => '-DPERL_POLLUTE', # e.g., '-DHAVE_SOMETHING'
'INC' => "-I@top_srcdir@ -I@top_srcdir@/com_err/et @SASLFLAGS@ @SSL_CPPFLAGS@ @GCOV_CFLAGS@ -I@top_srcdir@/perl/imap",
'EXE_FILES' => [cyradm],

View File

@ -0,0 +1,13 @@
diff --git a/imap/imapd.c b/imap/imapd.c
index 3cc75f5..a22a356 100644
--- a/imap/imapd.c
+++ b/imap/imapd.c
@@ -8022,7 +8022,7 @@ static void cmd_reconstruct(const char *tag, const char *name, int recursive)
fclose(stdout);
fclose(stderr);
- ret = snprintf(buf, sizeof(buf), "%s/quota", SBIN_DIR);
+ ret = snprintf(buf, sizeof(buf), "%s/cyr_quota", SBIN_DIR);
if(ret < 0 || ret >= (int) sizeof(buf)) {
/* in child, so fatailing won't disconnect our user */
fatal("quota buffer not sufficiently big", EX_CONFIG);

View File

@ -0,0 +1,60 @@
From 6dc8b483b5045a94e72e631a8faee388713c3c05 Mon Sep 17 00:00:00 2001
From: Bron Gondwana <brong@fastmail.fm>
Date: Wed, 21 Sep 2022 16:08:07 +1000
Subject: [PATCH] index: track changes for modseq bump when setting seen on
shared folders
---
imap/index.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/imap/index.c b/imap/index.c
index af06e94e6..5c96216ad 100644
--- a/imap/index.c
+++ b/imap/index.c
@@ -4778,6 +4778,7 @@ static int index_storeflag(struct index_state *state,
int dirty = 0;
modseq_t oldmodseq;
struct index_map *im = &state->map[msgno-1];
+ int seen_dirty = 0;
int r;
memset(modified_flags, 0, sizeof(struct index_modified_flags));
@@ -4803,6 +4804,7 @@ static int index_storeflag(struct index_state *state,
im->isseen = new;
state->seen_dirty = 1;
dirty++;
+ seen_dirty = 1;
}
}
@@ -4925,6 +4927,7 @@ static int index_storeflag(struct index_state *state,
else
system_flags &= ~FLAG_SEEN;
}
+
/* add back the internal tracking flags */
system_flags |= keep;
@@ -4942,6 +4945,18 @@ static int index_storeflag(struct index_state *state,
r = msgrecord_set_userflags(msgrec, user_flags);
if (r) return r;
+ // patch back in seen state for non-internal-seen
+ if (seen_dirty && !state->internalseen) {
+ if (im->isseen) {
+ modified_flags->added_system_flags |= FLAG_SEEN;
+ modified_flags->added_flags++;
+ }
+ else {
+ modified_flags->removed_system_flags |= FLAG_SEEN;
+ modified_flags->removed_flags++;
+ }
+ }
+
/* if it's silent and unchanged, update the seen value, but
* not if qresync is enabled - RFC 4551 says that the MODSEQ
* must always been told, and we prefer just to tell flags
--
2.43.0

View File

@ -1,8 +1,8 @@
diff --git a/imap/squatter.c b/imap/squatter.c
index 97daa73..d7ffbd0 100644
index 4419379..d00f003 100644
--- a/imap/squatter.c
+++ b/imap/squatter.c
@@ -332,8 +332,13 @@ static void expand_mboxnames(strarray_t *sa, int nmboxnames,
@@ -408,8 +408,13 @@ static void expand_mboxnames(strarray_t *sa, int nmboxnames,
else {
/* Translate any separators in mailboxname */
char *intname = mboxname_from_external(mboxnames[i], &squat_namespace, NULL);
@ -17,4 +17,4 @@ index 97daa73..d7ffbd0 100644
+ }
free(intname);
}
}

View File

@ -1,25 +0,0 @@
diff --git a/tools/vzic/Makefile b/tools/vzic/Makefile
index 8ae6afa..3882998 100644
--- a/tools/vzic/Makefile
+++ b/tools/vzic/Makefile
@@ -45,17 +45,17 @@ LIBICAL_LDADD = -lical
GLIB_CFLAGS = `pkg-config --cflags glib-2.0`
GLIB_LDADD = `pkg-config --libs glib-2.0`
-CFLAGS = -g -I../.. -DOLSON_DIR=\"$(OLSON_DIR)\" -DPRODUCT_ID='"$(PRODUCT_ID)"' -DTZID_PREFIX='"$(TZID_PREFIX)"' $(GLIB_CFLAGS) $(LIBICAL_CFLAGS)
+CFLAGS += -I../.. -DOLSON_DIR=\"$(OLSON_DIR)\" -DPRODUCT_ID='"$(PRODUCT_ID)"' -DTZID_PREFIX='"$(TZID_PREFIX)"' $(GLIB_CFLAGS) $(LIBICAL_CFLAGS)
OBJECTS = vzic.o vzic-parse.o vzic-dump.o vzic-output.o
all: vzic
vzic: $(OBJECTS)
- $(CC) $(OBJECTS) $(GLIB_LDADD) -o vzic
+ $(CC) $(LDFLAGS) $(OBJECTS) $(GLIB_LDADD) -o vzic
test-vzic: test-vzic.o
- $(CC) test-vzic.o $(LIBICAL_LDADD) -o test-vzic
+ $(CC) $(LDFLAGS) test-vzic.o $(LIBICAL_LDADD) -o test-vzic
# Dependencies.
$(OBJECTS): vzic.h

File diff suppressed because it is too large Load Diff