diff -Naur cyrus-imapd-2.1.12/imap/imapd.c cyrus-imapd-2.1.12.autocreate/imap/imapd.c --- cyrus-imapd-2.1.12/imap/imapd.c 2003-01-11 20:45:14.000000000 +0200 +++ cyrus-imapd-2.1.12.autocreate/imap/imapd.c 2003-04-21 21:18:18.000000000 +0300 @@ -143,6 +143,8 @@ void shut_down(int code); void fatal(const char *s, int code); +void autocreate_inbox(void); + void cmdloop(void); void cmd_login(char *tag, char *user); void cmd_authenticate(char *tag, char *authtype); @@ -1691,6 +1693,48 @@ } } + +/* + * Autocreate Inbox and subfolders upon login + */ +void autocreate_inbox() +{ + char inboxname[MAX_MAILBOX_NAME+1]; + int autocreatequota; + int r; + + /* + * Exlude admin's accounts + */ + if (imapd_userisadmin || imapd_userisproxyadmin) + return; + + /* + * Exclude anonymous + */ + if (!strcmp(imapd_userid, "anonymous")) + return; + + + if ((autocreatequota = config_getint("autocreatequota", 0))) { + /* This is actyally not required + as long as the lenght of userid is ok */ + r = (*imapd_namespace.mboxname_tointernal) (&imapd_namespace, + "INBOX", imapd_userid, inboxname); + if (!r) + r = mboxlist_lookup(inboxname, NULL, NULL, NULL); + + if (r == IMAP_MAILBOX_NONEXISTENT) + mboxlist_autocreateinbox(&imapd_namespace, imapd_userid, + imapd_authstate, inboxname, autocreatequota); + } +} + + + + + + /* * Perform a LOGIN command */ @@ -1823,6 +1867,9 @@ mboxname_hiersep_tointernal(&imapd_namespace, imapd_userid); freebuf(&passwdbuf); + + autocreate_inbox(); + return; } @@ -1943,6 +1990,9 @@ /* Translate any separators in userid */ mboxname_hiersep_tointernal(&imapd_namespace, imapd_userid); + + autocreate_inbox(); + return; } diff -Naur cyrus-imapd-2.1.12/imap/lmtpd.c cyrus-imapd-2.1.12.autocreate/imap/lmtpd.c --- cyrus-imapd-2.1.12/imap/lmtpd.c 2002-11-28 19:47:15.000000000 +0200 +++ cyrus-imapd-2.1.12.autocreate/imap/lmtpd.c 2003-04-21 21:18:18.000000000 +0300 @@ -148,6 +148,8 @@ struct lmtp_func mylmtp = { &deliver, &verify_user, &shut_down, &spoolfile, &removespool, 0, 1, 0 }; +static int autocreate_inbox(char *rcpt_userid); + static void logdupelem(); static void usage(); static void setup_sieve(); @@ -1372,6 +1374,50 @@ exit(code); } + + +/* + * Autocreate Inbox and subfolders upon login + */ +int autocreate_inbox(char *rcpt_userid) +{ + struct auth_state *authstate; + char inboxname[MAX_MAILBOX_NAME+1]; + int rcptisadmin ; + int autocreatequota; + int r; + + /* + * Exclude anonymous + */ + if (!strcmp(rcpt_userid, "anonymous")) + return IMAP_MAILBOX_NONEXISTENT; + + /* + * Check for autocreatequota and createonpost + */ + if (!(autocreatequota = config_getint("autocreatequota", 0)) || + !(config_getswitch("createonpost", 0))) + return IMAP_MAILBOX_NONEXISTENT; + + /* + * Exclude admin's accounts + */ + authstate = auth_newstate(rcpt_userid, NULL); + rcptisadmin = authisa(authstate, "imap", "admins"); + if (rcptisadmin) + return IMAP_MAILBOX_NONEXISTENT; + + r = (*lmtpd_namespace.mboxname_tointernal) (&lmtpd_namespace, + "INBOX", rcpt_userid, inboxname); + if (!r) + r = mboxlist_autocreateinbox(&lmtpd_namespace, rcpt_userid, + authstate, inboxname, autocreatequota); + return r; +} + + + static int verify_user(const char *user, long quotacheck, struct auth_state *authstate) { @@ -1405,6 +1451,8 @@ - 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 = autocreate_inbox(buf+5); } } diff -Naur cyrus-imapd-2.1.12/imap/mboxlist.c cyrus-imapd-2.1.12.autocreate/imap/mboxlist.c --- cyrus-imapd-2.1.12/imap/mboxlist.c 2003-01-08 19:40:17.000000000 +0200 +++ cyrus-imapd-2.1.12.autocreate/imap/mboxlist.c 2003-04-21 21:18:18.000000000 +0300 @@ -2724,3 +2724,147 @@ mboxlist_closesubs(subs); return r; } + +#define SEP '|' + +int mboxlist_autocreateinbox(struct namespace *namespace, + char *userid, + struct auth_state *auth_state, + char *mailboxname, int autocreatequota) { + char name [MAX_MAILBOX_NAME+1]; + char folder [MAX_MAILBOX_NAME+1]; + char *partition = NULL; + const char *crt ; + const char *sub ; + char *p, *q, *next_crt, *next_sub; + int len; + int r = 0; + int numcrt = 0; + int numsub = 0; + +#if 0 + /* + * Get Partition info or return. + * (Here you should propably use + * you own "get_partition(char *userid)" + * function. Otherwise all new INBOXes will be + * created into whatever partition has been declared + * as default in your imapd.conf) + */ + + partition = get_partition(userid); + + if (partition == NULL) { + /* + * Couldnt get partition info + */ + syslog(LOG_WARNING, + "Could not get imapPartition info for user %s", userid); + return IMAP_PARTITION_UNKNOWN; + } +#endif + + + r = mboxlist_createmailbox(mailboxname, MAILBOX_FORMAT_NORMAL, NULL, + 1, userid, auth_state, 0, 0); + + if (!r && autocreatequota > 0) + r = mboxlist_setquota(mailboxname, autocreatequota, 0); + + if (!r) + r = mboxlist_changesub(mailboxname, userid, + auth_state, 1, 1); + + syslog(r == 0 ? LOG_NOTICE : LOG_ERR, + "User %s, INBOX autocreate in partition-%s: %s", userid, + partition == NULL ? "default" : partition, + r == 0 ? "succeeded" : error_message(r)); + + if (r) return r; + + /* INBOX's subfolders */ + + if ((crt=config_getstring("autocreateinboxfolders", ""))); + sub=config_getstring("autosubscribeinboxfolders", ""); + + /* Roll through crt */ + next_crt = (char *)crt; + while (*next_crt) { + for (p = next_crt ; isspace((int) *p) || *p == SEP ; p++); + for (next_crt = p ; *next_crt && *next_crt != SEP ; next_crt++); + for (q = next_crt ; q > p && (isspace((int) *q) || *q == SEP); q--); + + if (!*p) continue; + + len = q - p + 1; + + /* First time we check for length */ + if (len > sizeof(folder) - 5) + r = IMAP_MAILBOX_BADNAME; + + if (!r) { + strncpy(folder, p, len); + folder[len] = '\0'; + + strlcpy(name, namespace->prefix[NAMESPACE_INBOX], sizeof(name)); + len = strlcat(name, folder, sizeof(name)); + + /* Second time we check length */ + /* + * The second check is not needed, because strlcat always + * returns a number <= len. (christos) + */ + /* + if (len > sizeof(name)) + r = IMAP_MAILBOX_BADNAME; + */ + } + + if (!r) + r = (namespace->mboxname_tointernal) (namespace, name, userid, + mailboxname); + if (!r) + r = mboxlist_createmailbox(mailboxname, MAILBOX_FORMAT_NORMAL, NULL, + 1, userid, auth_state, 0, 0); + if (!r) numcrt++; + + syslog(r == 0 ? LOG_DEBUG : LOG_ERR, + "User %s, %s autocreate: %s", userid, mailboxname, + r == 0 ? "succeeded" : error_message(r)); + if (r) { + r=0; + continue; + } + + /* Roll through sub */ + next_sub = (char *)sub; + while (*next_sub) { + for (p = next_sub ; isspace((int) *p) || *p == SEP ; p++); + for (next_sub = p ; *next_sub && *next_sub != SEP ; next_sub++); + for (q = next_sub ; q > p && (isspace((int) *q) || *q == SEP) ; q--); + if (!*p ) continue; + + len = q - p + 1; + + if (strncmp(folder, p, len)) + continue; + + r = mboxlist_changesub(mailboxname, userid, auth_state, 1, 1); + + if (!r) numsub++; + + syslog(r == 0 ? LOG_DEBUG : LOG_ERR, + "User %s, %s subscribe: %s", userid, mailboxname, + r == 0 ? "succeeded" : error_message(r)); + + break; + } + } + + if (*crt) + syslog(LOG_INFO, + "User %s, Inbox subfolders, created %d, subscribed %d", userid, + numcrt,numsub); + + return r; +} diff -Naur cyrus-imapd-2.1.12/imap/mboxlist.h cyrus-imapd-2.1.12.autocreate/imap/mboxlist.h --- cyrus-imapd-2.1.12/imap/mboxlist.h 2002-05-29 19:49:16.000000000 +0300 +++ cyrus-imapd-2.1.12.autocreate/imap/mboxlist.h 2003-04-21 21:18:18.000000000 +0300 @@ -189,4 +189,9 @@ /* done with database stuff */ void mboxlist_done(void); +int mboxlist_autocreateinbox(struct namespace *namespace, + char *userid, + struct auth_state *auth_state, + char *mailboxname, int autocreatequota); + #endif diff -Naur cyrus-imapd-2.1.12/imap/pop3d.c cyrus-imapd-2.1.12.autocreate/imap/pop3d.c --- cyrus-imapd-2.1.12/imap/pop3d.c 2003-01-10 23:53:08.000000000 +0200 +++ cyrus-imapd-2.1.12.autocreate/imap/pop3d.c 2003-04-21 21:18:18.000000000 +0300 @@ -138,6 +138,8 @@ static int apop_enabled(void); static char popd_apop_chal[45 + MAXHOSTNAMELEN + 1]; /* */ +static int autocreate_inbox(char *inboxname); + static void cmd_auth(); static void cmd_capa(); static void cmd_pass(); @@ -1316,6 +1318,44 @@ } } + + +/* + * Autocreate Inbox and subfolders upon login + */ +int autocreate_inbox(char *inboxname) +{ + struct auth_state *authstate; + int userisadmin ; + int autocreatequota; + int r; + + /* + * Exclude anonymous + */ + if (!strcmp(popd_userid, "anonymous")) + return IMAP_MAILBOX_NONEXISTENT; + + /* + * Check for autocreatequota + */ + if (!(autocreatequota = config_getint("autocreatequota", 0))) + return IMAP_MAILBOX_NONEXISTENT; + + /* + * Exclude admin's accounts + */ + authstate = auth_newstate(popd_userid, NULL); + userisadmin = authisa(authstate, "imap", "admins"); + if (userisadmin) + return IMAP_MAILBOX_NONEXISTENT; + + r = mboxlist_autocreateinbox(&popd_namespace, popd_userid, + authstate, inboxname, autocreatequota); + return r; +} + + /* * Complete the login process by opening and locking the user's inbox */ @@ -1334,6 +1374,14 @@ strcpy(inboxname, "user."); strcat(inboxname, popd_userid); r = mailbox_open_header(inboxname, 0, &mboxstruct); + + + + /* Try once again after autocreate_inbox */ + if (r == IMAP_MAILBOX_NONEXISTENT && + !(r = autocreate_inbox(inboxname))) + r = mailbox_open_header(inboxname, 0, &mboxstruct); + if (r) { free(popd_userid); popd_userid = 0;