Le 15/05/2019 à 16:17, Xavier a écrit : > Le 15/05/2019 à 16:13, Anthony Prades a écrit : >> On 5/15/19 4:10 PM, Xavier wrote: >>> I can't reproduce this exact issue. After the upgrade process (with >>> actual Buster packages), sieve rules are inoperative, but lmtpd won't >>> segfault: >>> * Starting with a fresh stretch install, I create mailboxes with and >>> without dot in names. >>> * In imapd.conf unixhierarchysep is set to yes and altnamespace to no >>> * I create a vacation rule and check that mails are sent back to the >>> sender. >>> * I upgrade to buster. >>> * Then sieve rules will never fire, but lmtpd won't crash. >>> >>> I haven't got anything special in the logs regarding sieve. Sieve >>> scripts are simply ignored. >>> >>> Then I tested your .postinst script, nothing changes. New sieve scripts >>> are also ignored. >> >> Hi, >> >> Do you reproduce on a fresh buster install ? >> >> Anthony > > This is the next try, but we have another problem to solve today > (urgent). We will try tomorrow ;-) > > Cheers, > Xavier
Hi all, I took a look on 3.0.9 changes. All changes are related to bug fixes (including this one) & documentation except the support of Clamav 0.101.x. We have Clamav 0.101.2 in Buster! So I think it would be safe to upgrade Cyrus-Imapd in Buster @nthykier, do you think I can fill a pre-approval-unblock ? Attached the diff without doc changes
diff --git a/Makefile.am b/Makefile.am index df77bbf92..fef9554f0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -121,7 +121,7 @@ EXTRA_DIST = \ if COM_ERR COMPILE_ET_DEP = com_err/et/compile_et -BUILT_SOURCES += com_err/et/compile_et +BUILT_SOURCES += com_err/et/compile_et com_err/et/libcyrus_com_err.la lib_LTLIBRARIES += com_err/et/libcyrus_com_err.la endif # COM_ERR @@ -879,6 +879,7 @@ imap_cyr_sphinxmgr_SOURCES = imap/cli_fatal.c imap/cyr_sphinxmgr.c imap/mutex_fa imap_cyr_sphinxmgr_LDADD = $(LD_UTILITY_ADD) imap_cyr_virusscan_SOURCES = imap/cli_fatal.c imap/cyr_virusscan.c imap/mutex_fake.c +imap_cyr_virusscan_CFLAGS = $(AM_CFLAGS) $(CLAMAV_CFLAGS) $(CFLAG_VISIBILITY) imap_cyr_virusscan_LDADD = $(LD_UTILITY_ADD) $(CLAMAV_LIBS) imap_ctl_zoneinfo_SOURCES = imap/cli_fatal.c imap/ctl_zoneinfo.c imap/mutex_fake.c imap/zoneinfo_db.c diff --git a/backup/ctl_backups.c b/backup/ctl_backups.c index cbc37e5b7..77607ca34 100644 --- a/backup/ctl_backups.c +++ b/backup/ctl_backups.c @@ -898,6 +898,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? } @@ -934,6 +935,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; } @@ -994,6 +996,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; } diff --git a/backup/lcb.c b/backup/lcb.c index f01371283..354d25d21 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; } diff --git a/configure.ac b/configure.ac index 965b2594f..18049eca5 100644 --- a/configure.ac +++ b/configure.ac @@ -112,10 +112,6 @@ AC_ARG_WITH(cyrus-user, cyrus_user="$withval",cyrus_user="cyrus") AC_SUBST(cyrus_user) AC_DEFINE_UNQUOTED(CYRUS_USER, "$cyrus_user",[What user will we run as?]) -AC_ARG_WITH(cyrus-group, - [AS_HELP_STRING([--with-cyrus-group=GROUPID], [use GROUPID cyrus group])], - cyrus_group="$withval",cyrus_group="mail") -AC_SUBST(cyrus_group) dnl allow users to override $sysconfdir, but retain old default (/etc) dnl if not specified @@ -2254,6 +2250,7 @@ Cyrus Server configured components calalarmd: $enable_calalarmd objectstore: $enable_objectstore backup: $enable_backup + com_err: $with_com_err External dependencies: ldap: $have_ldap diff --git a/imap/conversations.c b/imap/conversations.c index 56eccff63..46042e3cb 100644 --- a/imap/conversations.c +++ b/imap/conversations.c @@ -1842,7 +1842,6 @@ EXPORTED int conversations_update_record(struct conversations_state *cstate, int *delta_counts = NULL; int i; modseq_t modseq = 0; - const struct index_record *record = NULL; int r = 0; if (old && new) { @@ -1864,21 +1863,15 @@ EXPORTED int conversations_update_record(struct conversations_state *cstate, } } + const struct index_record *record = new ? new : old; if (new && !old) { /* add the conversation */ r = mailbox_cacherecord(mailbox, new); /* make sure it's loaded */ if (r) return r; r = message_update_conversations(cstate, new, &conv); if (r) return r; - record = new; - /* possible if silent (i.e. replica) */ - if (!record->cid) return 0; } - else { - record = new ? new : old; - /* skip out on non-CIDed records */ - if (!record->cid) return 0; - + else if (record->cid) { r = conversation_load(cstate, record->cid, &conv); if (r) return r; if (!conv) { @@ -1893,6 +1886,24 @@ EXPORTED int conversations_update_record(struct conversations_state *cstate, } } + // always update the GUID information first, as it's used for search + // even if conversations have not been set on this email + if (new) { + if (!old) { + r = conversations_set_guid(cstate, mailbox, new, /*add*/1); + if (r) return r; + } + } + else { + if (old) { + r = conversations_set_guid(cstate, mailbox, old, /*add*/0); + if (r) return r; + } + } + + // the rest is bookkeeping for CIDs only + if (!record->cid) return 0; + if (cstate->counted_flags) delta_counts = xzmalloc(sizeof(int) * cstate->counted_flags->count); @@ -1928,10 +1939,6 @@ EXPORTED int conversations_update_record(struct conversations_state *cstate, } delta_num_records--; modseq = MAX(modseq, old->modseq); - if (!new) { - r = conversations_set_guid(cstate, mailbox, old, /*add*/0); - if (r) return r; - } } if (new) { @@ -1953,10 +1960,6 @@ EXPORTED int conversations_update_record(struct conversations_state *cstate, } delta_num_records++; modseq = MAX(modseq, new->modseq); - if (!old) { - r = conversations_set_guid(cstate, mailbox, new, /*add*/1); - if (r) return r; - } } /* XXX - combine this with the earlier cache parsing */ diff --git a/imap/cyr_virusscan.c b/imap/cyr_virusscan.c index 863a85870..8f578855e 100644 --- a/imap/cyr_virusscan.c +++ b/imap/cyr_virusscan.c @@ -193,8 +193,17 @@ int clamav_scanfile(void *state, const char *fname, int r; /* scan file */ +#if LIBCLAMAV_MAJORVER < 9 r = cl_scanfile(fname, virname, NULL, st->av_engine, CL_SCAN_STDOPT); +#else + static struct cl_scan_options options; + + memset(&options, 0, sizeof(struct cl_scan_options)); + options.parse |= ~0; /* enable all parsers */ + + r = cl_scanfile(fname, virname, NULL, st->av_engine, &options); +#endif switch (r) { case CL_CLEAN: diff --git a/imap/idle.c b/imap/idle.c index e1239cea0..bf1bf0ac4 100644 --- a/imap/idle.c +++ b/imap/idle.c @@ -116,11 +116,14 @@ EXPORTED void idle_init(void) struct sockaddr_un local; int fdflags; int s; + int r; if (!idle_enabled()) return; - assert(idle_make_client_address(&local)); - assert(idle_make_server_address(&idle_remote)); + r = idle_make_client_address(&local); + assert(r); + r = idle_make_server_address(&idle_remote); + assert(r); idle_method_desc = "poll"; diff --git a/imap/ipurge.c b/imap/ipurge.c index 4b1a49b69..80c51716b 100644 --- a/imap/ipurge.c +++ b/imap/ipurge.c @@ -233,7 +233,7 @@ static int usage(const char *name) /* we don't check what comes in on matchlen and category, should we? */ static int purge_me(struct findall_data *data, void *rock __attribute__((unused))) { - if (!data) return 0; + if (!data || !data->mbname) return 0; struct mailbox *mailbox = NULL; int r; mbox_stats_t stats; diff --git a/imap/lmtp_sieve.c b/imap/lmtp_sieve.c index 4c3bbc3b7..9ba030f38 100644 --- a/imap/lmtp_sieve.c +++ b/imap/lmtp_sieve.c @@ -414,7 +414,7 @@ static int sieve_redirect(void *ac, /* if we have a msgid, we can track our redirects */ if (m->id) { snprintf(buf, sizeof(buf), "%s-%s", m->id, rc->addr); - sievedb = make_sieve_db(mbname_userid(sd->mbname)); + sievedb = make_sieve_db(mbname_recipient(sd->mbname, ((deliver_data_t *) mc)->ns)); dkey.id = buf; dkey.to = sievedb; @@ -496,7 +496,7 @@ static int sieve_reject(void *ac, body = msg_getheader(md, "original-recipient"); origreceip = body ? body[0] : NULL; if ((res = send_rejection(md->id, md->return_path, - origreceip, mbname_userid(sd->mbname), + origreceip, mbname_recipient(sd->mbname, ((deliver_data_t *) mc)->ns), rc->msg, md->data)) == 0) { snmp_increment(SIEVE_REJECT, 1); syslog(LOG_INFO, "sieve rejected: %s to: %s", @@ -735,7 +735,7 @@ static int send_response(void *ac, while (waitpid(sm_pid, &sm_stat, 0) < 0); if (sm_stat == 0) { /* sendmail exit value */ - sievedb = make_sieve_db(mbname_userid(sdata->mbname)); + sievedb = make_sieve_db(mbname_recipient(sdata->mbname, ((deliver_data_t *) mc)->ns)); dkey.id = outmsgid; dkey.to = sievedb; diff --git a/imap/mbexamine.c b/imap/mbexamine.c index 670b27d4f..25cf003ed 100644 --- a/imap/mbexamine.c +++ b/imap/mbexamine.c @@ -216,11 +216,6 @@ static int do_examine(struct findall_data *data, void *rock __attribute__((unuse r = mailbox_open_irl(name, &mailbox); if (r) return r; - if (chdir(mailbox_datapath(mailbox, 0)) == -1) { - r = IMAP_IOERROR; - goto done; - } - printf(" Mailbox Header Info:\n"); printf(" Path to mailbox: %s\n", mailbox_datapath(mailbox, 0)); printf(" Mailbox ACL: %s\n", mailbox->acl); /* xxx parse */ @@ -352,7 +347,6 @@ static int do_examine(struct findall_data *data, void *rock __attribute__((unuse printf("Desired message not found\n"); } - done: mailbox_close(&mailbox); return r; @@ -384,11 +378,6 @@ static int do_quota(struct findall_data *data, void *rock __attribute__((unused) r = mailbox_open_irl(name, &mailbox); if (r) return r; - if (chdir(mailbox_datapath(mailbox, 0)) == -1) { - r = IMAP_IOERROR; - goto done; - } - struct mailbox_iter *iter = mailbox_iter_init(mailbox, 0, ITER_SKIP_EXPUNGED); const message_t *msg; while ((msg = mailbox_iter_step(iter))) { diff --git a/lib/charset.c b/lib/charset.c index 0fa6c1415..6c5eaa3e6 100644 --- a/lib/charset.c +++ b/lib/charset.c @@ -2766,19 +2766,25 @@ static char *qp_encode(const char *data, size_t len, int isheader, unsigned char this = data[n]; unsigned char next = (n < len - 1) ? data[n+1] : '\0'; - if (cnt >= BASE64_MAX_LINE_LEN) { - if (isheader) { - /* split encoded token with fold */ - buf_appendcstr(&buf, "?="); - buf_appendcstr(&buf, "\r\n "); - buf_appendcstr(&buf, "=?UTF-8?Q?"); + /* Insert line break before exceeding line length limits */ + if (isheader) { + /* RFC2047 forbids splitting multi-octet characters */ + int needbytes; + if (this < 0x80) needbytes = 0; + else if (this < 0xc0) needbytes = 0; // UTF-8 continuation + else if (this < 0xe0) needbytes = 3; + else if (this < 0xf0) needbytes = 6; + else if (this < 0xf8) needbytes = 9; + else needbytes = 0; // impossible UTF-8 encoding + if (cnt + needbytes >= BASE64_MAX_LINE_LEN) { + buf_appendcstr(&buf, "?=\r\n =?UTF-8?Q?"); cnt = 11; } - else { - /* add soft line break to body */ - buf_appendcstr(&buf, "=\r\n"); - cnt = 0; - } + } + else if (cnt >= BASE64_MAX_LINE_LEN) { + /* add soft line break to body */ + buf_appendcstr(&buf, "=\r\n"); + cnt = 0; } if ((QPSAFECHAR[this] diff --git a/lib/util.c b/lib/util.c index 62ad7bdea..5f3cb1933 100644 --- a/lib/util.c +++ b/lib/util.c @@ -593,6 +593,7 @@ static int cap_setuid(int uid, int is_master) EXPORTED int become_cyrus(int is_master) { struct passwd *p; + struct group *g; uid_t newuid; gid_t newgid; int result; @@ -601,6 +602,7 @@ EXPORTED int become_cyrus(int is_master) if (uid) return cap_setuid(uid, is_master); const char *cyrus = cyrus_user(); + const char *mail = cyrus_group(); p = getpwnam(cyrus); if (p == NULL) { @@ -612,6 +614,15 @@ EXPORTED int become_cyrus(int is_master) newuid = p->pw_uid; newgid = p->pw_gid; + if (mail != NULL) { + g = getgrnam(mail); + if (g == NULL) { + syslog(LOG_ERR, "no entry in /etc/group for group %s", mail); + return -1; + } + newgid = g->gr_gid; + } + if (newuid == geteuid() && newuid == getuid() && newgid == getegid() && @@ -651,6 +662,13 @@ EXPORTED const char *cyrus_user(void) return cyrus; } +EXPORTED const char *cyrus_group(void) +{ + const char *mail = getenv("CYRUS_GROUP"); + if (!mail) mail = config_getstring(IMAPOPT_CYRUS_GROUP); + return mail; +} + static int cmdtime_enabled = 0; static struct timeval cmdtime_start, cmdtime_end, nettime_start, nettime_end; static double totaltime, cmdtime, nettime, search_maxtime; diff --git a/lib/util.h b/lib/util.h index 8233cfd1d..d55c56811 100644 --- a/lib/util.h +++ b/lib/util.h @@ -206,6 +206,7 @@ enum { extern int set_caps(int stage, int is_master); extern int become_cyrus(int is_master); extern const char *cyrus_user(void); +extern const char *cyrus_group(void); /* Some systems have very inefficient implementations of isdigit, * and we use it in a lot of inner loops diff --git a/perl/imap/IMAP/Admin.pm b/perl/imap/IMAP/Admin.pm index e2ef12cc8..1ca412a10 100644 --- a/perl/imap/IMAP/Admin.pm +++ b/perl/imap/IMAP/Admin.pm @@ -575,7 +575,11 @@ sub listquotaroot { $self->addcallback({-trigger => 'QUOTAROOT', -callback => sub { my %d = @_; - return unless $d{-text} =~ /^\S+ (\S+)/; + return unless ( $d{-text} =~ /^\"[^\"]+\" \"([^\"]+)\"/ or + $d{-text} =~ /^\"[^\"]+\" (\S+)/ or + $d{-text} =~ /[^\"]\S+ \"([^\"]+)\"/ or + $d{-text} =~ /^[^\"]\S+ (\S+)/ + ); ${$d{-rock}} = $1; }, -rock => \$qr}, @@ -583,7 +587,7 @@ sub listquotaroot { -callback => sub { my %d = @_; return unless - $d{-text} =~ s/^\S+ \((\S+) (\S+) (\S+)\)//; + $d{-text} =~ s/\((\S+) (\S+) (\S+)\)$//; push @{$d{-rock}}, $1, [$2, $3]; }, -rock => \@info}); diff --git a/ptclient/ldap.c b/ptclient/ldap.c index e6cbc5d71..5d324e5f2 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, "collecting all domains from %s", ptsm->domain_base_dn); @@ -948,15 +948,18 @@ static int ptsmodule_get_dn( syslog(LOG_ERR, "LDAP not available: %s", ldap_err2string(rc)); ldap_unbind(ptsm->ld); ptsm->ld = NULL; - 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 found"); - return PTSM_FAIL; + rc = PTSM_FAIL; + goto done; } else if (ldap_count_entries(ptsm->ld, res) >= 1) { int count_matches = 0; char *temp_base = NULL; @@ -976,10 +979,12 @@ static int ptsmodule_get_dn( if (count_matches > 1) { syslog(LOG_ERR, "LDAP search for %s failed because it matches multiple accounts.", canon_id); - return PTSM_FAIL; + rc = PTSM_FAIL; + goto done; } else if (count_matches == 0) { syslog(LOG_ERR, "LDAP search for %s failed because it does not match any account in all domains.", canon_id); - return PTSM_FAIL; + rc = PTSM_FAIL; + goto done; } syslog(LOG_DEBUG, "we have found %s in %s", canon_id, base); @@ -1006,19 +1011,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) { @@ -1033,7 +1042,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); @@ -1044,23 +1053,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); + syslog(LOG_DEBUG, "Searching %s with %s failed", base, filter); 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); @@ -1086,6 +1095,13 @@ static int ptsmodule_get_dn( } return (*ret ? PTSM_OK : PTSM_FAIL); + + done: + if (filter) + free(filter); + if (base) + free(base); + return rc; } @@ -1320,11 +1336,15 @@ static int ptsmodule_make_authstate_filter( syslog(LOG_ERR, "No values for attribute '%s' on entry '%s'", ptsm->member_attribute, errdn); + *reply = "no values"; + rc = PTSM_FAIL; + ldap_value_free(vals); + vals = NULL; + goto done; } else if (ldap_count_values(vals) > 1) { syslog(LOG_ERR, "Too many values for attribute '%s' on entry '%s'", ptsm->member_attribute, errdn); - } else { *reply = "too many values"; rc = PTSM_FAIL; ldap_value_free(vals); @@ -1388,13 +1408,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 +1446,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 +1475,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 +1485,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); diff --git a/ptclient/ptdump.c b/ptclient/ptdump.c index fb59a894f..6676e3884 100644 --- a/ptclient/ptdump.c +++ b/ptclient/ptdump.c @@ -71,11 +71,11 @@ static int dump_cb(void *rockp __attribute__((unused)), int main(int argc, char *argv[]) { struct db *ptdb; - char fnamebuf[1024]; extern char *optarg; int opt; int r; - char *alt_config = NULL; + const char *fname; + char *alt_config = NULL, *tofree = NULL; while ((opt = getopt(argc, argv, "C:")) != EOF) { switch (opt) { @@ -95,15 +95,21 @@ int main(int argc, char *argv[]) cyrus_init(alt_config, "ptdump", 0, 0); /* open database */ - strcpy(fnamebuf, config_dir); - strcat(fnamebuf, PTS_DBFIL); - r = cyrusdb_open(config_ptscache_db, fnamebuf, CYRUSDB_CREATE, &ptdb); + fname = config_getstring(IMAPOPT_PTSCACHE_DB_PATH); + if (!fname) { + tofree = strconcat(config_dir, PTS_DBFIL, NULL); + fname = tofree; + } + + r = cyrusdb_open(config_ptscache_db, fname, CYRUSDB_CREATE, &ptdb); if(r != CYRUSDB_OK) { - fprintf(stderr,"error opening %s (%s)", fnamebuf, + fprintf(stderr,"error opening %s (%s)", fname, cyrusdb_strerror(r)); exit(1); } + if (tofree) free(tofree); + /* iterate through db, wiping expired entries */ cyrusdb_foreach(ptdb, "", 0, NULL, dump_cb, ptdb, NULL); diff --git a/ptclient/ptexpire.c b/ptclient/ptexpire.c index e8eeaa7f9..96abfca43 100644 --- a/ptclient/ptexpire.c +++ b/ptclient/ptexpire.c @@ -102,11 +102,11 @@ static int expire_cb(void *rockp, int main(int argc, char *argv[]) { struct db *ptdb; - char fnamebuf[1024]; extern char *optarg; int opt; int r; - char *alt_config = NULL; + const char *fname; + char *alt_config = NULL, *tofree = NULL; if ((geteuid()) == 0 && (become_cyrus(/*is_master*/0) != 0)) { fatal("must run as the Cyrus user", EC_USAGE); @@ -142,15 +142,21 @@ int main(int argc, char *argv[]) syslog(LOG_DEBUG, "ptexpire.c %s", PACKAGE_VERSION); /* open database */ - strcpy(fnamebuf, config_dir); - strcat(fnamebuf, PTS_DBFIL); - r = cyrusdb_open(config_ptscache_db, fnamebuf, CYRUSDB_CREATE, &ptdb); + fname = config_getstring(IMAPOPT_PTSCACHE_DB_PATH); + if (!fname) { + tofree = strconcat(config_dir, PTS_DBFIL, NULL); + fname = tofree; + } + + r = cyrusdb_open(config_ptscache_db, fname, CYRUSDB_CREATE, &ptdb); if(r != CYRUSDB_OK) { - syslog(LOG_ERR, "error opening %s (%s)", fnamebuf, + syslog(LOG_ERR, "error opening %s (%s)", fname, cyrusdb_strerror(r)); exit(1); } + if (tofree) free(tofree); + /* iterate through db, wiping expired entries */ cyrusdb_foreach(ptdb, "", 0, expire_p, expire_cb, ptdb, NULL); diff --git a/ptclient/ptloader.c b/ptclient/ptloader.c index b425afd79..ef6877f97 100644 --- a/ptclient/ptloader.c +++ b/ptclient/ptloader.c @@ -119,9 +119,6 @@ struct auth_state *ptsmodule_make_authstate(const char *identifier, /* config.c info (libimap) */ const int config_need_data = 0; -/* Globals */ -#define DB (config_ptscache_db) - static char ptclient_debug = 0; struct db *ptsdb = NULL; @@ -129,8 +126,9 @@ int service_init(int argc, char *argv[], char **envp __attribute__((unused))) { int r; int opt; - char fnamebuf[1024]; extern char *optarg; + const char *fname; + char *tofree = NULL; if (geteuid() == 0) fatal("must run as the Cyrus user", EC_USAGE); setproctitle_init(argc, argv, envp); @@ -155,15 +153,21 @@ int service_init(int argc, char *argv[], char **envp __attribute__((unused))) } } - strcpy(fnamebuf, config_dir); - strcat(fnamebuf, PTS_DBFIL); - r = cyrusdb_open(DB, fnamebuf, CYRUSDB_CREATE, &ptsdb); + fname = config_getstring(IMAPOPT_PTSCACHE_DB_PATH); + if (!fname) { + tofree = strconcat(config_dir, PTS_DBFIL, NULL); + fname = tofree; + } + + r = cyrusdb_open(config_ptscache_db, fname, CYRUSDB_CREATE, &ptsdb); if (r != 0) { - syslog(LOG_ERR, "DBERROR: opening %s: %s", fnamebuf, + syslog(LOG_ERR, "DBERROR: opening %s: %s", fname, cyrusdb_strerror(ret)); fatal("can't read pts database", EC_TEMPFAIL); } + if (tofree) free(tofree); + ptsmodule_init(); return 0;