Patch installation: cd into the directory where cyrus-imapd-2.1.10 resides, and then execute:
/usr/local/bin/patch -p0 <edunet-autocreate
diff -Naur cyrus-imapd-2.1.10/imap/imapd.c cyrus-imapd-2.1.10-autocreate/imap/imapd.c --- cyrus-imapd-2.1.10/imap/imapd.c Wed Nov 6 22:43:20 2002 +++ cyrus-imapd-2.1.10-autocreate/imap/imapd.c Fri Nov 15 19:15:41 2002 @@ -139,6 +139,7 @@ void fatal(const char *s, int code); void cmdloop(void); +void autocreate_folders(void); void cmd_login(char *tag, char *user); void cmd_authenticate(char *tag, char *authtype); void cmd_noop(char *tag, char *cmd); @@ -1672,6 +1673,42 @@ } } + +/* + * Autocreate Inboxes and subfolders upon login + */ +void autocreate_folders() +{ + char mailboxname[MAX_MAILBOX_NAME+1]; + sfolder *subfolder; + int i,r=0; + + if (imapd_userisadmin) return; + + /* Exclude Anonymous */ + if(!strcmp(imapd_userid, "anonymous")) return; + + r = (*imapd_namespace.mboxname_tointernal)(&imapd_namespace, + "INBOX", imapd_userid, mailboxname); + + if (!r) r=mboxlist_autocreate_inbox(mailboxname, imapd_userid, +imapd_authstate, 1, 0, 0); + + if (!r) { + subfolder=mboxlist_get_subfolders(); + for(i=0;subfolder[i].folder!=NULL;i++){ + r = (*imapd_namespace.mboxname_tointernal)(&imapd_namespace, +subfolder[i].folder, + imapd_userid, mailboxname); + if (!r) r=mboxlist_autocreate_inbox(mailboxname, imapd_userid, +imapd_authstate, + 0, subfolder[i].sub, 0); + } + + /* Free ... subfolders ???? */ + free_subfolder(subfolder); + + } +return; +} + /* * Perform a LOGIN command */ @@ -1804,6 +1841,7 @@ mboxname_hiersep_tointernal(&imapd_namespace, imapd_userid); freebuf(&passwdbuf); + autocreate_folders(); return; } @@ -1924,6 +1962,7 @@ /* Translate any separators in userid */ mboxname_hiersep_tointernal(&imapd_namespace, imapd_userid); + autocreate_folders(); return; } @@ -3500,13 +3539,14 @@ /* * Perform a CREATE command + * Autocreatequota functionality + * has been removed, due to autocreate_inbox. */ void cmd_create(char *tag, char *name, char *partition, int localonly) { int r = 0; char mailboxname[MAX_MAILBOX_NAME+1]; - int autocreatequota; if (partition && !imapd_userisadmin) { r = IMAP_PERMISSION_DENIED; @@ -3529,19 +3569,6 @@ imapd_userisadmin, imapd_userid, imapd_authstate, localonly, localonly); - - if (r == IMAP_PERMISSION_DENIED && !strcasecmp(name, "INBOX") && - (autocreatequota = config_getint("autocreatequota", 0))) { - - /* Auto create */ - r = mboxlist_createmailbox(mailboxname, 0, - partition, 1, imapd_userid, - imapd_authstate, 0, 0); - - if (!r && autocreatequota > 0) { - (void) mboxlist_setquota(mailboxname, autocreatequota, 0); - } - } } if (imapd_mailbox) { diff -Naur cyrus-imapd-2.1.10/imap/lmtpd.c cyrus-imapd-2.1.10-autocreate/imap/lmtpd.c --- cyrus-imapd-2.1.10/imap/lmtpd.c Wed Nov 6 22:43:22 2002 +++ cyrus-imapd-2.1.10-autocreate/imap/lmtpd.c Fri Nov 15 19:15:14 2002 @@ -1380,6 +1380,10 @@ int r; int sl = strlen(BB); + sfolder *subfolder; + char mailboxname[MAX_MAILBOX_NAME+1]; + int i; + /* check to see if mailbox exists and we can append to it */ if (!strncmp(user, BB, sl) && user[sl] == '+') { /* special shared folder address */ @@ -1405,6 +1409,21 @@ - don't care about message size (1 msg over quota allowed) */ r = append_check(buf, MAILBOX_FORMAT_NORMAL, authstate, 0, quotacheck > 0 ? 0 : quotacheck); + + if (r == IMAP_MAILBOX_NONEXISTENT ) { + r=mboxlist_autocreate_inbox(buf, (char *)user, authstate, 1, 0, 1); + + if (!r) { + subfolder=mboxlist_get_subfolders(); + for(i=0;subfolder[i].folder!=NULL;i++){ + r = (*lmtpd_namespace.mboxname_tointernal)(&lmtpd_namespace, +subfolder[i].folder, + user, mailboxname); + if (!r) r=mboxlist_autocreate_inbox(mailboxname, (char *)user, + authstate, 0, +subfolder[i].sub, 1); + } + free_subfolder(subfolder); + } + } } } diff -Naur cyrus-imapd-2.1.10/imap/mboxlist.c cyrus-imapd-2.1.10-autocreate/imap/mboxlist.c --- cyrus-imapd-2.1.10/imap/mboxlist.c Wed Nov 6 22:43:22 2002 +++ cyrus-imapd-2.1.10-autocreate/imap/mboxlist.c Fri Nov 15 19:15:14 2002 @@ -2724,3 +2724,161 @@ mboxlist_closesubs(subs); return r; } + +/* + * Autocreate INBOX upon Login + */ + +int +mboxlist_autocreate_inbox (const char *mailboxname, char *userid, + struct auth_state *auth_state, int isinbox, + int sub_flag, int islmtp) +{ + char *partition = NULL; + int autocreatequota; + int r = 0; + + if (isinbox) + { + + if (islmtp) + { + if (!config_getswitch ("createonpost", 0)) + return IMAP_MAILBOX_NONEXISTENT; + } + else + { + r = mboxlist_lookup (mailboxname, NULL, NULL, NULL); + switch (r) + { + case IMAP_MAILBOX_NONEXISTENT: + break; + case 0: + return IMAP_MAILBOX_EXISTS; + break; + default: + return r; + break; + } + } + + autocreatequota = config_getint ("autocreatequota", 0); + if (autocreatequota) + { + r = mboxlist_createmailbox (mailboxname, MAILBOX_FORMAT_NORMAL, + partition, 1, userid, auth_state, 0, 0); + if (!r) + { + r = mboxlist_changesub (mailboxname, userid, + auth_state, 1, islmtp == 1 ? 1 : 0); + if (!r && autocreatequota > 0) + { + r = mboxlist_setquota (mailboxname, autocreatequota, 0); + } + } + syslog (LOG_NOTICE, "User %s, INBOX autocreate in partition-%s: %s", + userid, partition, + r == 0 ? "succeeded" : error_message (r)); + + } + + return r; + } + else + { + r = mboxlist_createmailbox (mailboxname, MAILBOX_FORMAT_NORMAL, + NULL, 1, userid, auth_state, 0, 0); + if (!r && sub_flag) + { + r = mboxlist_changesub (mailboxname, userid, + auth_state, 1, islmtp == 1 ? 1 : 0); + } + syslog (LOG_INFO, "User %s, %s autocreate: %s", userid, mailboxname, + r == 0 ? "succeeded" : error_message (r)); + return r; + } +} + +#define SEPERATOR "|" +#define SUBFLAG "SUB:" + +/* + * Retrive INBOX subfolders to create upon Login + */ +sfolder * +mboxlist_get_subfolders () +{ + char *autofolders; + char *p, *q; + char *name; + int sub_flag = 0, len = 0, i = 0; + + sfolder *subfolder = 0; + + autofolders = (char *) xstrdup (config_getstring ("autocreatefolders", "")); + p = strtok (autofolders, SEPERATOR); + while (p) + { + while (*p && isspace ((int) *p)) + p++; + if (!strncmp (p, SUBFLAG, strlen (SUBFLAG))) + { + sub_flag = 1; + p += strlen (SUBFLAG); + while (*p && isspace ((int) *p)) + p++; + } + for (q = p + strlen (p) - 1; q > p && isspace ((int) *q); q--) + { + *q = '\0'; + } + if (strlen (p) == 0) + { + p = strtok (NULL, SEPERATOR); + continue; + } + + len = strlen ("INBOX.") + strlen (p); + name = xmalloc ((len + 1) * sizeof (char)); + memcpy (name, "INBOX.", strlen ("INBOX.")); + memcpy (name + strlen ("INBOX."), p, strlen (p)); + name[len] = NULL; + i++; + + subfolder = xrealloc (subfolder, i * sizeof (sfolder)); + subfolder[i - 1].folder = xstrdup (name); + subfolder[i - 1].sub = sub_flag; + + free (name); + name = NULL; + sub_flag = 0; + p = strtok (NULL, SEPERATOR); + } + /* Null termination */ + subfolder = xrealloc (subfolder, (i + 1) * sizeof (sfolder)); + subfolder[i].folder = NULL; + subfolder[i].sub = 0; + + free (autofolders); + autofolders = NULL; + + return subfolder; +} + + +/* + * Free sfolder structs + */ +void +free_subfolder (sfolder * subfolder) +{ + int i; + + for (i = 0; subfolder[i].folder != NULL; i++) + { + free (subfolder[i].folder); + } + + free (subfolder); + subfolder = NULL; +} diff -Naur cyrus-imapd-2.1.10/imap/mboxlist.h cyrus-imapd-2.1.10-autocreate/imap/mboxlist.h --- cyrus-imapd-2.1.10/imap/mboxlist.h Wed May 29 19:49:16 2002 +++ cyrus-imapd-2.1.10-autocreate/imap/mboxlist.h Fri Nov 15 19:15:14 2002 @@ -82,6 +82,12 @@ char acls[1]; }; +/* INBOX subfolders to create upon Login */ +typedef struct { + char *folder; + int sub; +}sfolder; + /* Lookup 'name' in the mailbox list. */ int mboxlist_lookup(const char *name, char **pathp, char **aclp, void *tid); @@ -188,5 +194,18 @@ /* done with database stuff */ void mboxlist_done(void); + +/* Autocreate INBOXes upon Login */ +int mboxlist_autocreate_inbox(const char *mailboxname, char *userid, + struct auth_state *auth_state, int isinbox, int sub_flag, int +islmtp); +/* + * Retrive INBOX subfolders to create upon Login + */ +sfolder *mboxlist_get_subfolders(void); + +/* + * Free sfolder structs + */ +void free_subfolder(sfolder *subfolder); #endif