From 8a30bf2e05e741ee6711822be613336548968cef Mon Sep 17 00:00:00 2001 From: Bron Gondwana Date: Wed, 24 Dec 2008 23:26:30 +1100 Subject: [PATCH] Limit User Folders A user managed to synchronise our server with their UWash IMAP server's view of a very busy home directory, creating tens of thousands of folders and showing that there's a DOS risk against mailboxes.db here. This patch creates a new config variable user_folder_limit which, if set, returns IMAP_PERMISSION_DENIED to any further attempts to create a folder if the user has too many folders already. --- imap/mboxlist.c | 20 +++++++++++++++++++- lib/imapoptions | 4 ++++ 2 files changed, 23 insertions(+), 1 deletions(-) diff --git a/imap/mboxlist.c b/imap/mboxlist.c index 0ca5eeb..99696ef 100644 --- a/imap/mboxlist.c +++ b/imap/mboxlist.c @@ -370,6 +370,7 @@ mboxlist_mycreatemailboxcheck(char *name, unsigned long parentpartitionlen = 0; unsigned long parentacllen = 0; int mbtype; + int user_folder_limit; /* Check for invalid name/partition */ if (partition && strlen(partition) > MAX_PARTITION_LEN) { @@ -443,6 +444,23 @@ mboxlist_mycreatemailboxcheck(char *name, break; } } + + /* check the folder limit */ + if (!isadmin && (user_folder_limit = config_getint(IMAPOPT_USER_FOLDER_LIMIT))) { + char buf[MAX_MAILBOX_NAME+1]; + strncpy(buf, mbox, strlen(mbox)); + if (!strncmp(buf, "user.", 5)) { + char *firstdot = strchr(buf+5, '.'); + if (firstdot) *firstdot = '\0'; + if (mboxlist_count_inferiors(buf, isadmin, userid, auth_state) + 1 + >= user_folder_limit) { + syslog(LOG_ERR, "LIMIT: refused to create %s for %s because of limit %d", + mbox, userid, user_folder_limit); + return IMAP_PERMISSION_DENIED; + } + } + } + if (parentlen != 0) { /* check acl */ if (!isadmin && @@ -3455,7 +3473,7 @@ mboxlist_count_addmbox(char *name __attribute__((unused)), { int *count = (int *)rock; - *count++; + (*count)++; return 0; } diff --git a/lib/imapoptions b/lib/imapoptions index 70f40b9..e8e0f6c 100644 --- a/lib/imapoptions +++ b/lib/imapoptions @@ -1144,6 +1144,10 @@ product version in the capabilities */ { "umask", "077", STRING } /* The umask value used by various Cyrus IMAP programs. */ +{ "user_folder_limit", 0, INT } +/* Limit the number of folders a user can create in their INBOX. + Set to 0 (default) for no limit. Only affects folders in user. */ + { "username_tolower", 1, SWITCH } /* Convert usernames to all lowercase before login/authentication. This is useful with authentication backends which ignore case during -- 1.5.6.5