autocreatequota - does it really work?
Voutsinas Nikos
nvoutsin at noc.uoa.gr
Fri Nov 15 11:46:00 EST 2002
Let me repost the patch.....
Patch installation: cd into the directory where cyrus-imapd-2.1.10
resides, and then execute:
/usr/local/bin/patch -p0 <edunet-autocreate
PS: Once you have applied the patch, please remove the
int autocreatequota in cmd_create, otherwise you ll get the following
warning
imapd.c: In function `cmd_create':
imapd.c:3550: warning: unused variable `autocreatequota'
diff -Naur cyrus-imapd-2.1.10/imap/imapd.c
cyrus-imapd-2.1.10-autocr/imap/imapd.c
--- cyrus-imapd-2.1.10/imap/imapd.c Wed Nov 6 22:43:20 2002
+++ cyrus-imapd-2.1.10-autocr/imap/imapd.c Fri Nov 15 15:20:53 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,6 +3539,8 @@
/*
* Perform a CREATE command
+ * Autocreatequota functionality
+ * has been removed, due to autocreate_inbox.
*/
void
cmd_create(char *tag, char *name, char *partition, int localonly)
@@ -3529,19 +3570,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-autocr/imap/lmtpd.c
--- cyrus-imapd-2.1.10/imap/lmtpd.c Wed Nov 6 22:43:22 2002
+++ cyrus-imapd-2.1.10-autocr/imap/lmtpd.c Fri Nov 15 15:23:45 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-autocr/imap/mboxlist.c
--- cyrus-imapd-2.1.10/imap/mboxlist.c Wed Nov 6 22:43:22 2002
+++ cyrus-imapd-2.1.10-autocr/imap/mboxlist.c Fri Nov 15 15:27:32 2002
@@ -2724,3 +2724,191 @@
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)
+ {
+#if 0
+ /* Get Partition info from LDAP or return */
+
+ /* NOTICE: Partition info in LDAP should be
+ * used only for initialization as part of
+ * user's profile, since there is no synchronization
+ * mechanism between LDAP and mailboxes.db
+ * Maybe we should remove such, informations from LDAP
+ * immediately after inbox creation.
+ * Althought mailboxes partition or Max-quota
+ * are pretty rarely modified, i am not (yet) convinced....
+ * (BTW see annotatemore, and getannotation)
+ */
+
+ r = ldap_start ();
+ if (r)
+ return IMAP_PARTITION_UNKNOWN;
+
+ partition = get_partition (userid);
+
+ if (partition == NULL)
+ {
+ /* Couldnt get partition info ?...return */
+ syslog (LOG_WARNING,
+ "Could not get imapPartition info for user %s",
userid);
+ return IMAP_PARTITION_UNKNOWN;
+ }
+#endif
+ 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));
+
+ /* Cleanup partition info */
+ free_ldap ();
+ }
+
+ 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-autocr/imap/mboxlist.h
--- cyrus-imapd-2.1.10/imap/mboxlist.h Wed May 29 19:49:16 2002
+++ cyrus-imapd-2.1.10-autocr/imap/mboxlist.h Fri Nov 15 15:30:35 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
More information about the Info-cyrus
mailing list