Skip to content

Commit

Permalink
Merge pull request cyrusimap#4720 from cyrusimap/replicaonly
Browse files Browse the repository at this point in the history
Add a 'replicaonly' config option and directory
  • Loading branch information
brong authored Nov 4, 2023
2 parents 7631f5a + 4209f36 commit d6cb484
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 7 deletions.
9 changes: 4 additions & 5 deletions imap/mboxlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -4438,15 +4438,13 @@ EXPORTED int mboxlist_setquotas(const char *root,
r = quota_read(&q, &tid, 1);

if (!r) {
int changed = 0;
int underquota;
quota_t oldquotas[QUOTA_NUMRESOURCES];

/* has it changed? */
for (res = 0 ; res < QUOTA_NUMRESOURCES ; res++) {
oldquotas[res] = q.limits[res];
if (q.limits[res] != newquotas[res]) {
underquota = 0;
int underquota = 0;

/* Prepare a QuotaChange event notification *now*.
*
Expand All @@ -4468,14 +4466,14 @@ EXPORTED int mboxlist_setquotas(const char *root,
}

q.limits[res] = newquotas[res];
changed++;
q.dirty = 1;

mboxevent_extract_quota(quotachange_event, &q, res);
if (underquota)
mboxevent_extract_quota(quotawithin_event, &q, res);
}
}
if (changed) {
if (q.dirty) {
if (quotamodseq)
q.modseq = quotamodseq;
r = quota_write(&q, silent, &tid);
Expand Down Expand Up @@ -4542,6 +4540,7 @@ EXPORTED int mboxlist_setquotas(const char *root,
memcpy(q.limits, newquotas, sizeof(q.limits));
if (quotamodseq)
q.modseq = quotamodseq;
q.dirty = 1;
r = quota_write(&q, silent, &tid);
if (r) goto done;

Expand Down
16 changes: 16 additions & 0 deletions imap/mboxname.c
Original file line number Diff line number Diff line change
Expand Up @@ -3104,9 +3104,22 @@ static modseq_t mboxname_domodseq(const char *fname,
return counters.highestmodseq;
}

static void mboxname_assert_canadd(mbname_t *mbname)
{
assert(!config_getswitch(IMAPOPT_REPLICAONLY));
// add code for suppressing particular users by filename
const char *userid = mbname_userid(mbname);
if (!userid) return;
char *path = strconcat(config_dir, "/replicaonly/", userid, (char *)NULL);
struct stat sbuf;
assert(stat(path, &sbuf) == -1); // file must not exist
free(path);
}

EXPORTED modseq_t mboxname_nextmodseq(const char *mboxname, modseq_t last, int mbtype, int flags)
{
mbname_t *mbname = mbname_from_intname(mboxname);
mboxname_assert_canadd(mbname);
char *fname = mboxname_conf_getpath(mbname, "counters");

modseq_t modseq = mboxname_domodseq(fname, mboxname, last, MBOXMODSEQ, mbtype, flags, 1);
Expand Down Expand Up @@ -3152,6 +3165,7 @@ EXPORTED modseq_t mboxname_readquotamodseq(const char *mboxname)
EXPORTED modseq_t mboxname_nextquotamodseq(const char *mboxname, modseq_t last)
{
mbname_t *mbname = mbname_from_intname(mboxname);
mboxname_assert_canadd(mbname);
char *fname = mboxname_conf_getpath(mbname, "counters");

modseq_t modseq = mboxname_domodseq(fname, mboxname, last, QUOTAMODSEQ, 0, 0, 1);
Expand Down Expand Up @@ -3200,6 +3214,7 @@ EXPORTED modseq_t mboxname_readraclmodseq(const char *mboxname)
EXPORTED modseq_t mboxname_nextraclmodseq(const char *mboxname, modseq_t last)
{
mbname_t *mbname = mbname_from_intname(mboxname);
mboxname_assert_canadd(mbname);
char *fname = mboxname_conf_getpath(mbname, "counters");

modseq_t modseq = mboxname_domodseq(fname, mboxname, last, RACLMODSEQ, 0, 0, 1);
Expand Down Expand Up @@ -3249,6 +3264,7 @@ EXPORTED uint32_t mboxname_nextuidvalidity(const char *mboxname, uint32_t last)
struct mboxname_counters counters;
int fd = -1;
mbname_t *mbname = mbname_from_intname(mboxname);
mboxname_assert_canadd(mbname);
char *fname = mboxname_conf_getpath(mbname, "counters");

/* XXX error handling */
Expand Down
2 changes: 2 additions & 0 deletions imap/quota.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,8 @@ int fixquota_finish(int thisquota)
localq.scanuseds[res]);
if (!flag_reportonly)
localq.useds[res] = localq.scanuseds[res];
// need to bump modseq, we changed something
localq.dirty = 1;
}
}

Expand Down
2 changes: 2 additions & 0 deletions imap/quota.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ struct quota {
char *scanmbox;
quota_t scanuseds[QUOTA_NUMRESOURCES];

/* inforation for changes */
int dirty;
modseq_t modseq;
};

Expand Down
4 changes: 3 additions & 1 deletion imap/quota_db.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,8 @@ EXPORTED int quota_check(const struct quota *q,
EXPORTED void quota_use(struct quota *q,
enum quota_resource res, quota_t delta)
{
if (delta)
q->dirty = 1;
/* prevent underflow */
if ((delta < 0) && (-delta > q->useds[res])) {
syslog(LOG_INFO, "Quota underflow for root %s, resource %s,"
Expand Down Expand Up @@ -458,7 +460,7 @@ EXPORTED int quota_write(struct quota *quota, int silent, struct txn **tid)
qrlen = strlen(quota->root);
if (!qrlen) return IMAP_QUOTAROOT_NONEXISTENT;

if (mboxname_isusermailbox(quota->root, /*isinbox*/0)) {
if (quota->dirty && mboxname_isusermailbox(quota->root, /*isinbox*/0)) {
if (silent)
quota->modseq = mboxname_setquotamodseq(quota->root, quota->modseq);
else
Expand Down
2 changes: 1 addition & 1 deletion imap/user.c
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ static int find_cb(void *rockp __attribute__((unused)),
int r;

root = xstrndup(key, keylen);
r = quota_deleteroot(root, 0);
r = quota_deleteroot(root, 1);
free(root);

return r;
Expand Down
4 changes: 4 additions & 0 deletions lib/imapoptions
Original file line number Diff line number Diff line change
Expand Up @@ -2217,6 +2217,10 @@ If all partitions are over that limit, this feature is not used anymore.
/* If enabled, all IMAP, POP and JMAP connections are read-only,
* no writes allowed. */

{ "replicaonly", 0, SWITCH, "3.9.0" }
/* If enabled, nothing is allowed to increase modseq or uidvalidity,
* no writes allowed at all. */

{ "reject8bit", 0, SWITCH, "2.3.17" }
/* If enabled, lmtpd rejects messages with 8-bit characters in the
headers. */
Expand Down

0 comments on commit d6cb484

Please sign in to comment.