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