gunnar: server/patches/cyrus-imapd KOLAB_cyrus-imapd_2.3.9_Annotations2.patch, NONE, 1.1 KOLAB_cyrus-imapd_2.3.9_Folder-names.patch, NONE, 1.1 KOLAB_cyrus-imapd_2.3.9_Groups.patch, NONE, 1.1 KOLAB_cyrus-imapd_2.3.9_Logging.patch, NONE, 1.1 KOLAB_cyrus-imapd_2.3.9_UID.patch, NONE, 1.1 README_Annotations2.patch, NONE, 1.1 README_Folder-names.patch, NONE, 1.1 README_Groups.patch, NONE, 1.1 README_Logging.patch, NONE, 1.1 README_UID.patch, NONE, 1.1

cvs at kolab.org cvs at kolab.org
Sat Sep 29 14:13:56 CEST 2007


Author: gunnar

Update of /kolabrepository/server/patches/cyrus-imapd
In directory doto:/tmp/cvs-serv11101/cyrus-imapd

Added Files:
	KOLAB_cyrus-imapd_2.3.9_Annotations2.patch 
	KOLAB_cyrus-imapd_2.3.9_Folder-names.patch 
	KOLAB_cyrus-imapd_2.3.9_Groups.patch 
	KOLAB_cyrus-imapd_2.3.9_Logging.patch 
	KOLAB_cyrus-imapd_2.3.9_UID.patch README_Annotations2.patch 
	README_Folder-names.patch README_Groups.patch 
	README_Logging.patch README_UID.patch 
Log Message:
Clean up the patches used by Kolab so that other dirstributions/packagers know what is required to get Kolab to work.

--- NEW FILE: KOLAB_cyrus-imapd_2.3.9_Annotations2.patch ---
Provides a new version of annotation support for the cyrus imapd server [Version: 2.3.9]

diff -r 43265f589d80 imap/annotate.c
--- a/imap/annotate.c	Sat Sep 29 13:49:34 2007 +0200
+++ b/imap/annotate.c	Sat Sep 29 13:56:24 2007 +0200
@@ -40,6 +40,13 @@
  *
  */
 /*
+ * This file contains code Copyright (c) 2006 by Thomas Viehmann.
+ * You may distribute source code or binaries under the conditions
+ * conditions given in the CMU license, provided this note stays intact
+ * in the distributed source. If you want to distribute my code without
+ * this notice, do contact me at <tv at beamnet.de>.
+ */
+/*
  * $Id: KOLAB_cyrus-imapd_2.3.9_Annotations2.patch,v 1.1 2007/09/29 12:13:54 gunnar Exp $
  */
 
@@ -92,6 +99,8 @@ int (*proxy_store_func)(const char *serv
 int (*proxy_store_func)(const char *server, const char *mbox_pat,
 			struct entryattlist *entryatts) = NULL;
 
+void init_annotation_definitions();
+
 /* String List Management */
 /*
  * Append 's' to the strlist 'l'.  Possibly include metadata.
@@ -238,6 +247,8 @@ void annotatemore_init(int myflags,
     if (store_func) {
 	proxy_store_func = store_func;
     }
+    
+    init_annotation_definitions();
 }
 
 void annotatemore_open(char *fname)
@@ -1797,6 +1808,224 @@ const struct annotate_st_entry mailbox_r
     { NULL, 0, ANNOTATION_PROXY_T_INVALID, 0, 0, NULL, NULL }
 };
 
+struct annotate_st_entry_list *server_entries_list = NULL;
+struct annotate_st_entry_list *mailbox_rw_entries_list = NULL;
+
+enum {
+  ANNOTATION_SCOPE_SERVER = 1,
+  ANNOTATION_SCOPE_MAILBOX = 2
+};
+
+const struct annotate_attrib annotation_scope_names[] =
+{
+    { "server", ANNOTATION_SCOPE_SERVER },
+    { "mailbox", ANNOTATION_SCOPE_MAILBOX },
+    { NULL, 0 }
+};
+
+const struct annotate_attrib annotation_proxy_type_names[] =
+{
+    { "proxy", PROXY_ONLY },
+    { "backend", BACKEND_ONLY },
+    { "proxy_and_backend", PROXY_AND_BACKEND },
+    { NULL, 0 }
+};
+
+const struct annotate_attrib attribute_type_names[] = 
+{
+    { "content-type", ATTRIB_TYPE_CONTENTTYPE },
+    { "string", ATTRIB_TYPE_STRING },
+    { "boolean", ATTRIB_TYPE_BOOLEAN },
+    { "uint", ATTRIB_TYPE_UINT },
+    { "int", ATTRIB_TYPE_INT },
+    { NULL, 0 }
+};
+
+#define ANNOT_DEF_MAXLINELEN 1024
+
+int table_lookup(const struct annotate_attrib *table,
+                                  char* name,
+                                  size_t namelen,
+                                  char* errmsg) 
+/* search in table for the value given by name and namelen (name is null-terminated,
+   but possibly more than just the key). errmsg is used to hint the user where we failed */
+{
+  char errbuf[ANNOT_DEF_MAXLINELEN*2];
+  int entry;
+  
+  for (entry = 0; table[entry].name &&
+                  (strncasecmp(table[entry].name, name, namelen)
+                   || table[entry].name[namelen] != '\0'); entry++);
+
+  if (! table[entry].name) {
+    sprintf(errbuf, "invalid %s at '%s'", errmsg, name);
+    fatal(errbuf, EC_CONFIG);
+  }
+  return table[entry].entry;
+}
+
+char *consume_comma(char* p)
+  /* advance beyond the next ',', skipping whitespace, fail if next non-space is no comma */
+{
+  char errbuf[ANNOT_DEF_MAXLINELEN*2];
+
+  for (; *p && isspace(*p); p++);  
+  if (*p != ',') {
+    sprintf(errbuf, "',' expected, '%s' found parsing annotation definition",
+            p);
+    fatal(errbuf, EC_CONFIG);
+  }
+  p++;
+  for (; *p && isspace(*p); p++);  
+  
+  return p;
+}
+
+int parse_table_lookup_bitmask(const struct annotate_attrib *table,
+                               char** s,
+                               char* errmsg) 
+  /* parses strings of the form value1 [ value2 [ ... ]]
+     value1 is mapped via table to ints and the result ored
+     whitespace is allowed between value names and punctuation
+     the field must end in '\0' or ','
+     s is advanced to '\0' or ','
+     on error errmsg is used to identify item to be parsed
+   */
+{
+  char errbuf[ANNOT_DEF_MAXLINELEN*2];
+  int result = 0;
+  char *p, *p2;
+
+  p = *s;
+  do {
+    p2 = p;
+    for (; *p && (isalnum(*p) || *p=='.' || *p=='-' || *p=='_' || *p=='/');p++);
+    result |= table_lookup(table, p2, p-p2, errmsg);
+    for (; *p && isspace(*p); p++);
+  } while (*p && *p != ',');
+
+  *s = p;
+  return result;
+}
+
+void init_annotation_definitions()
+{
+  char *p, *p2, *tmp;
+  const char *filename;
+  char aline[ANNOT_DEF_MAXLINELEN];
+  char errbuf[ANNOT_DEF_MAXLINELEN*2];
+  struct annotate_st_entry_list *se, *me;
+  struct annotate_st_entry *ae;
+  int i;
+  FILE* f;
+
+  /* NOTE: we assume # static entries > 0 */
+  server_entries_list = xmalloc(sizeof(struct annotate_st_entry_list));
+  mailbox_rw_entries_list = xmalloc(sizeof(struct annotate_st_entry_list));
+  se = server_entries_list;
+  me = mailbox_rw_entries_list;
+  /* copy static entries into list */
+  for (i = 0; server_entries[i].name;i++) {
+    se->entry = &server_entries[i];
+    if (server_entries[i+1].name) {
+      se->next = xmalloc(sizeof(struct annotate_st_entry_list));
+      se = se->next;
+    }
+  }
+  /* copy static entries into list */
+  for (i = 0; mailbox_rw_entries[i].name;i++) {
+    me->entry = &mailbox_rw_entries[i];
+    if (mailbox_rw_entries[i+1].name) {
+      me->next = xmalloc(sizeof(struct annotate_st_entry_list));
+      me = me->next;
+    }
+  }
+
+  /* parse config file */
+  filename = config_getstring(IMAPOPT_ANNOTATION_DEFINITIONS);
+
+  if (! filename) {
+    se->next = NULL;
+    me->next = NULL;
+    return;
+  }
+  
+  f = fopen(filename,"r");
+  if (! f) {
+    sprintf(errbuf, "could not open annotation definiton %s", filename);
+    fatal(errbuf, EC_CONFIG);
+  }
+  
+  while (fgets(aline, sizeof(aline), f)) {
+    // remove leading space, skip blank lines and comments
+    for (p = aline; *p && isspace(*p); p++);
+    if (!*p || *p == '#') continue;
+
+    // note, we only do the most basic validity checking and may
+    // be more restrictive than neccessary
+
+    ae = xmalloc(sizeof(struct annotate_st_entry));
+
+    p2 = p;
+    for (; *p && (isalnum(*p) || *p=='.' || *p=='-' || *p=='_' || *p=='/');p++);
+    // TV-TODO: should test for empty
+    ae->name = xstrndup(p2, p-p2);
+
+    p = consume_comma(p);
+  
+    p2 = p;
+    for (; *p && (isalnum(*p) || *p=='.' || *p=='-' || *p=='_' || *p=='/');p++);
+
+    if (table_lookup(annotation_scope_names, p2, p-p2,
+                     "annotation scope")==ANNOTATION_SCOPE_SERVER) {
+      se->next = xmalloc(sizeof(struct annotate_st_entry_list));
+      se = se->next;
+      se->entry = ae;
+    }
+    else {
+      me->next = xmalloc(sizeof(struct annotate_st_entry_list));
+      me = me->next;      
+      me->entry = ae;
+    }
+    
+    p = consume_comma(p);
+    p2 = p;
+    for (; *p && (isalnum(*p) || *p=='.' || *p=='-' || *p=='_' || *p=='/');p++);
+    ae->type = table_lookup(attribute_type_names, p2, p-p2,
+                                  "attribute type");
+  
+    p = consume_comma(p);
+    ae->proxytype = parse_table_lookup_bitmask(annotation_proxy_type_names,
+                                               &p,
+                                               "annotation proxy type");
+
+    p = consume_comma(p);
+    ae->attribs = parse_table_lookup_bitmask(annotation_attributes,
+                                             &p,
+                                             "annotation attributes");
+    
+    p = consume_comma(p);
+    p2 = p;
+    for (; *p && (isalnum(*p) || *p=='.' || *p=='-' || *p=='_' || *p=='/');p++);
+    tmp = xstrndup(p2, p-p2);
+    ae->acl = cyrus_acl_strtomask(tmp);
+    free(tmp);
+
+    for (; *p && isspace(*p); p++);
+    if (*p) {
+      sprintf(errbuf, "junk at end of line: '%s'", p);
+      fatal(errbuf, EC_CONFIG);
+    }
+    
+    ae->set = annotation_set_todb;
+    ae->rock = NULL;
+  }
+
+  fclose(f);
+  se->next = NULL;
+  me->next = NULL;
+}
+
 int annotatemore_store(char *mailbox,
 		       struct entryattlist *l,
 		       struct namespace *namespace,
@@ -1808,7 +2037,7 @@ int annotatemore_store(char *mailbox,
     struct entryattlist *e = l;
     struct attvaluelist *av;
     struct storedata sdata;
-    const struct annotate_st_entry *entries;
+    const struct annotate_st_entry_list *entries, *currententry;
     time_t now = time(0);
 
     memset(&sdata, 0, sizeof(struct storedata));
@@ -1819,45 +2048,45 @@ int annotatemore_store(char *mailbox,
 
     if (!mailbox[0]) {
 	/* server annotations */
-	entries = server_entries;
+	entries = server_entries_list;
     }
     else {
 	/* mailbox annotation(s) */
-	entries = mailbox_rw_entries;
+	entries = mailbox_rw_entries_list;
     }
 
     /* Build a list of callbacks for storing the annotations */
     while (e) {
-	int entrycount, attribs;
+	int attribs;
 	struct annotate_st_entry_list *nentry = NULL;
 
 	/* See if we support this entry */
-	for (entrycount = 0;
-	     entries[entrycount].name;
-	     entrycount++) {
-	    if (!strcmp(e->entry, entries[entrycount].name)) {
+	for (currententry = entries;
+	     currententry;
+	     currententry = currententry->next) {
+	    if (!strcmp(e->entry, currententry->entry->name)) {
 		break;
 	    }
 	}
-	if (!entries[entrycount].name) {
+	if (!currententry) {
 	    /* unknown annotation */
 	    return IMAP_PERMISSION_DENIED;
 	}
 
 	/* Add this entry to our list only if it
 	   applies to our particular server type */
-	if ((entries[entrycount].proxytype != PROXY_ONLY)
+	if ((currententry->entry->proxytype != PROXY_ONLY)
 	    || proxy_store_func) {
 	    nentry = xzmalloc(sizeof(struct annotate_st_entry_list));
 	    nentry->next = sdata.entry_list;
-	    nentry->entry = &(entries[entrycount]);
+	    nentry->entry = currententry->entry;
 	    nentry->shared.modifiedsince = now;
 	    nentry->priv.modifiedsince = now;
 	    sdata.entry_list = nentry;
 	}
 
 	/* See if we are allowed to set the given attributes. */
-	attribs = entries[entrycount].attribs;
+	attribs = currententry->entry->attribs;
 	av = e->attvalues;
 	while (av) {
 	    const char *value;
@@ -1867,7 +2096,7 @@ int annotatemore_store(char *mailbox,
 		    goto cleanup;
 		}
 		value = annotate_canon_value(av->value,
-					     entries[entrycount].type);
+					     currententry->entry->type);
 		if (!value) {
 		    r = IMAP_ANNOTATION_BADVALUE;
 		    goto cleanup;
@@ -1893,7 +2122,7 @@ int annotatemore_store(char *mailbox,
 		    goto cleanup;
 		}
 		value = annotate_canon_value(av->value,
-					     entries[entrycount].type);
+					     currententry->entry->type);
 		if (!value) {
 		    r = IMAP_ANNOTATION_BADVALUE;
 		    goto cleanup;
diff -r 43265f589d80 lib/imapoptions
--- a/lib/imapoptions	Sat Sep 29 13:49:34 2007 +0200
+++ b/lib/imapoptions	Sat Sep 29 13:56:24 2007 +0200
@@ -152,6 +152,9 @@ are listed with ``<none>''.
    user on their mailboxes?  In a large organization this can cause
    support problems, but it's enabled by default. */
 
+{ "annotation_definitions", NULL, STRING }
+/* File containing annotation definitions. */
+
 { "auth_mech", "unix", STRINGLIST("unix", "pts", "krb", "krb5")}
 /* The authorization mechanism to use. */
 

--- NEW FILE: KOLAB_cyrus-imapd_2.3.9_Folder-names.patch ---
Modifies the set of accepted characters in folder names for the cyrus imapd server [Version: 2.3.9]

diff -r 575b237ded7b imap/mboxname.c
--- a/imap/mboxname.c	Sat Sep 29 13:40:37 2007 +0200
+++ b/imap/mboxname.c	Sat Sep 29 13:41:01 2007 +0200
@@ -649,8 +649,13 @@ int mboxname_netnewscheck(char *name)
 /*
  * Apply site policy restrictions on mailbox names.
  * Restrictions are hardwired for now.
- */
+
+ * original definition 
 #define GOODCHARS " +,-.0123456789:=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"
+ */
+
+#define GOODCHARS " #$%'()*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~"
+
 int mboxname_policycheck(char *name)
 {
     unsigned i;

--- NEW FILE: KOLAB_cyrus-imapd_2.3.9_Groups.patch ---
Allows to use a file other than /etc/groups for group definitions within the cyrus imapd server [Version: 2.3.9]

diff -r 719114a03da4 lib/auth_unix.c
--- a/lib/auth_unix.c	Sat Sep 29 13:38:16 2007 +0200
+++ b/lib/auth_unix.c	Sat Sep 29 13:39:58 2007 +0200
@@ -48,12 +48,133 @@
 #include <stdlib.h>
 #include <pwd.h>
 #include <grp.h>
+#include <stdio.h>
 #include <ctype.h>
 #include <string.h>
 
 #include "auth.h"
 #include "libcyr_cfg.h"
 #include "xmalloc.h"
+
+#ifdef __FreeBSD__
+/*
+ * __getgrent.c - This file is part of the libc-8086/grp package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf at linux.mit.edu>.
+ * 
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public
+ *  License along with this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+static struct group *__getgrent(int grp_fd, char *line_buff, char **members)
+{
+    short line_index;
+    short buff_size;
+    static struct group group;
+    register char *ptr;
+    char *field_begin;
+    short member_num;
+    char *endptr;
+    int line_len;
+
+    /* We use the restart label to handle malformatted lines */
+    restart:
+    line_index = 0;
+    buff_size = 256;
+
+    line_buff = realloc(line_buff, buff_size);
+    while (1) {
+        if ((line_len = read(grp_fd, line_buff + line_index,
+                        buff_size - line_index)) <= 0) {
+            return NULL;
+        }
+        field_begin = strchr(line_buff, '\n');
+        if (field_begin != NULL) {
+            lseek(grp_fd,
+                    (long) (1 + field_begin -
+                            (line_len + line_index + line_buff)), SEEK_CUR);
+            *field_begin = '\0';
+            if (*line_buff == '#' || *line_buff == ' '
+                    || *line_buff == '\n' || *line_buff == '\t')
+                goto restart;
+            break;
+        } else {
+            /* Allocate some more space */
+            line_index = buff_size;
+            buff_size += 256;
+            line_buff = realloc(line_buff, buff_size);
+        }
+    }
+
+    /* Now parse the line */
+    group.gr_name = line_buff;
+    ptr = strchr(line_buff, ':');
+    if (ptr == NULL)
+        goto restart;
+    *ptr++ = '\0';
+
+    group.gr_passwd = ptr;
+    ptr = strchr(ptr, ':');
+    if (ptr == NULL)
+        goto restart;
+    *ptr++ = '\0';
+
+    field_begin = ptr;
+    ptr = strchr(ptr, ':');
+    if (ptr == NULL)
+        goto restart;
+    *ptr++ = '\0';
+
+    group.gr_gid = (gid_t) strtoul(field_begin, &endptr, 10);
+    if (*endptr != '\0')
+        goto restart;
+
+    member_num = 0;
+    field_begin = ptr;
+
+    if (members != NULL)
+        free(members);
+    members = (char **) malloc((member_num + 1) * sizeof(char *));
+    for ( ; field_begin && *field_begin != '\0'; field_begin = ptr) {
+        if ((ptr = strchr(field_begin, ',')) != NULL)
+            *ptr++ = '\0';
+        members[member_num++] = field_begin;
+        members = (char **) realloc(members,
+                (member_num + 1) * sizeof(char *));
+    }
+    members[member_num] = NULL;
+
+    group.gr_mem = members;
+    return &group;
+}
+    
+static char *line_buff = NULL;
+static char **members  = NULL;
+
+struct group *fgetgrent(FILE *file)
+{
+    if (file == NULL) {
+        errno = EINTR;
+        return NULL;
+    }
+    return __getgrent(fileno(file), line_buff, members);
+}
+#endif /* __FreeBSD__ */
 
 struct auth_state {
     char userid[81];
@@ -142,6 +263,25 @@ static char allowedchars[256] = {
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
+static struct group* fgetgrnam(const char* name)
+{
+    struct group *grp;
+    FILE *groupfile;
+
+    groupfile = fopen("/etc/imapd.group", "r");
+    if (!groupfile) groupfile = fopen("/etc/group", "r");
+    if (groupfile) {
+       while ((grp = fgetgrent(groupfile))) {
+         if (strcasecmp(grp->gr_name, name) == 0) {
+           fclose(groupfile);
+           return grp;
+         }
+       }
+    } 
+    if (groupfile) fclose(groupfile);
+    return NULL;
+} 
+
 /*
  * Convert 'identifier' into canonical form.
  * Returns a pointer to a static buffer containing the canonical form
@@ -177,7 +317,7 @@ size_t len;
      */
     
     if (!strncmp(retbuf, "group:", 6)) {
-	grp = getgrnam(retbuf+6);
+	grp = fgetgrnam(retbuf+6);
 	if (!grp) return 0;
 	strcpy(retbuf+6, grp->gr_name);
 	return retbuf;
@@ -224,6 +364,7 @@ static struct auth_state *mynewstate(con
     struct passwd *pwd;
     struct group *grp;
     char **mem;
+    FILE *groupfile;
 
     identifier = mycanonifyid(identifier, 0);
     if (!identifier) return 0;
@@ -240,20 +381,23 @@ static struct auth_state *mynewstate(con
 
     pwd = getpwnam(identifier);
 	
-    setgrent();
-    while ((grp = getgrent())) {
-	for (mem = grp->gr_mem; *mem; mem++) {
-	    if (!strcmp(*mem, identifier)) break;
-	}
-
-	if (*mem || (pwd && pwd->pw_gid == grp->gr_gid)) {
-	    newstate->ngroups++;
-	    newstate->group = (char **)xrealloc((char *)newstate->group,
-						newstate->ngroups * sizeof(char *));
-	    newstate->group[newstate->ngroups-1] = xstrdup(grp->gr_name);
-	}
-    }
-    endgrent();
+    groupfile = fopen("/etc/imapd.group", "r");
+    if (!groupfile) groupfile = fopen("/etc/group", "r");
+    if (groupfile) {
+       while ((grp = fgetgrent(groupfile))) {
+         for (mem = grp->gr_mem; *mem; mem++) {
+            if (!strcasecmp(*mem, identifier)) break;
+         }
+
+         if (*mem || (pwd && pwd->pw_gid == grp->gr_gid)) {
+            newstate->ngroups++;
+            newstate->group = (char **)xrealloc((char *)newstate->group,
+                                                newstate->ngroups * sizeof(char *));
+            newstate->group[newstate->ngroups-1] = xstrdup(grp->gr_name);
+         }
+       }
+       fclose(groupfile);
+    } 
     return newstate;
 }
 

--- NEW FILE: KOLAB_cyrus-imapd_2.3.9_Logging.patch ---
Provides improved logging for the cyrus imapd server [Version: 2.3.9]

diff -r 2b4b67cfafb7 imap/append.c
--- a/imap/append.c	Sat Sep 29 13:40:19 2007 +0200
+++ b/imap/append.c	Sat Sep 29 13:40:37 2007 +0200
@@ -653,6 +653,9 @@ int append_fromstage(struct appendstate 
 
     /* ok, we've successfully added a message */
     as->quota_used += message_index.size;
+
+    syslog(LOG_DEBUG, "append_fromstage: message %d added to %s",
+	   message_index.uid, mailbox->name );
 
     return 0;
 }
diff -r 2b4b67cfafb7 imap/imapd.c
--- a/imap/imapd.c	Sat Sep 29 13:40:19 2007 +0200
+++ b/imap/imapd.c	Sat Sep 29 13:40:37 2007 +0200
@@ -3514,6 +3514,8 @@ void cmd_close(char *tag)
     else {
 	prot_printf(imapd_out, "%s OK %s\r\n", tag,
 		    error_message(IMAP_OK_COMPLETED));
+	syslog(LOG_DEBUG, "cmd_expunge: user %s, mailbox %s, sequence %s",
+	       imapd_userid, imapd_mailbox->name, "''");
     }
 }    
 
diff -r 2b4b67cfafb7 imap/mailbox.c
--- a/imap/mailbox.c	Sat Sep 29 13:40:19 2007 +0200
+++ b/imap/mailbox.c	Sat Sep 29 13:40:37 2007 +0200
@@ -2457,6 +2457,8 @@ int mailbox_expunge(struct mailbox *mail
 	*(fname->tail)++ = '/';
 	fname->len++;
 	for (msgno = 0; msgno < numdeleted; msgno++) {
+	    syslog(LOG_DEBUG, "mailbox_expunge: removing mail %s:%d",
+		   mailbox->name, deleted[msgno]);
 	    mailbox_message_get_fname(mailbox, deleted[msgno],
 				      fname->tail,
 				      sizeof(fname->buf) - fname->len);

--- NEW FILE: KOLAB_cyrus-imapd_2.3.9_UID.patch ---
Allows login by uid rather than the mail address on the cyrus imapd server [Version: 2.3.9]

diff -r db07337ac0c3 configure
--- a/configure	Sat Sep 29 13:41:01 2007 +0200
+++ b/configure	Sat Sep 29 13:41:15 2007 +0200
@@ -18094,7 +18094,7 @@ done
 done
 
 IMAP_COM_ERR_LIBS="${COM_ERR_LIBS}"
-IMAP_LIBS="${LIB_SASL} ${LIBS}"
+IMAP_LIBS="${LIB_SASL} -lldap -llber ${LIBS}"
 
 
 
diff -r db07337ac0c3 imap/global.c
--- a/imap/global.c	Sat Sep 29 13:41:01 2007 +0200
+++ b/imap/global.c	Sat Sep 29 13:41:15 2007 +0200
@@ -52,6 +52,9 @@
 #include <netinet/in.h>
 #include <sys/stat.h>
 
+#include <ldap.h>
+#include <lber.h>
+
 #if HAVE_UNISTD_H
 # include <unistd.h>
 #endif
@@ -362,6 +365,18 @@ char *canonify_userid(char *user, char *
     char *domain = NULL;
     int len = strlen(user);
     char buf[81];
+    const char *uri;
+    const char *base;
+    const char *binddn;
+    const char *bindpw;
+    struct timeval timeout;
+    char filter[255];
+    LDAP *handle;
+    LDAPMessage *res;
+    LDAPMessage *entry;
+    char ** vals;
+
+    int rc;
 
     /* check for domain */
     if (config_virtdomains &&
@@ -380,6 +395,47 @@ char *canonify_userid(char *user, char *
     }
 
     if (config_virtdomains) {
+        if (config_virtdomains == IMAP_ENUM_VIRTDOMAINS_LDAP) {
+           uri = config_getstring(IMAPOPT_LDAP_URI);
+           base = config_getstring(IMAPOPT_LDAP_BASE);
+           binddn = config_getstring(IMAPOPT_LDAP_BIND_DN);
+           bindpw = config_getstring(IMAPOPT_LDAP_PASSWORD);
+           timeout.tv_sec = config_getint(IMAPOPT_LDAP_TIME_LIMIT);
+           timeout.tv_usec = 0;
+           sprintf(filter, "(uid=%s)", user);
+           rc = ldap_initialize(&handle, uri);
+           if (rc != LDAP_SUCCESS) {
+                syslog(LOG_ERR, "ldap_initialize failed (%s)", uri);
+           } else {
+	        rc = ldap_simple_bind_s(handle, binddn, bindpw);
+	        if (rc != LDAP_SUCCESS) {
+                     syslog(LOG_ERR, "ldap_simple_bind() failed %d (%s)", rc, ldap_err2string(rc));
+	        } else {
+	             rc = ldap_search_st(handle, base, LDAP_SCOPE_SUBTREE, filter, NULL, 0, &timeout, &res);
+                     if (rc != LDAP_SUCCESS) {
+                          syslog(LOG_ERR, "ldap_search_st failed %d (%s)", rc, ldap_err2string(rc));
+                     } else {
+	                  if ( (entry = ldap_first_entry(handle, res)) != NULL ) {
+			       // read mail attribute from entry
+			       if ( (vals = ldap_get_values(handle, entry, "mail")) ) {
+  				    if (strchr(vals[0], '@')) {
+				        static char buf[81]; /* same size as in auth_canonifyid */
+					strncpy( buf, vals[0], sizeof(buf) );
+					buf[80] = '\0'; /* make sure it's null-terminated */
+					ldap_value_free( vals );
+				        ldap_msgfree( res );
+					ldap_unbind_s(handle); /* also frees handle */
+				        return auth_canonifyid( buf, 0) ;
+				    }
+				    ldap_value_free( vals );
+			       }			       	
+   	                  }
+			  ldap_msgfree( res );
+                     }
+                }
+		ldap_unbind_s(handle); /* also frees handle */
+           }
+        }
 	if (domain) {
 	    if (config_defdomain && !strcasecmp(config_defdomain, domain+1)) {
 		*domain = '\0'; /* trim the default domain */
@@ -392,7 +448,7 @@ char *canonify_userid(char *user, char *
 		user = buf;
 	    }
 	}
-	else if (config_virtdomains != IMAP_ENUM_VIRTDOMAINS_USERID) {
+	else if (config_virtdomains != IMAP_ENUM_VIRTDOMAINS_USERID && config_virtdomains != IMAP_ENUM_VIRTDOMAINS_LDAP) {
 	    socklen_t salen;
 	    int error;
 	    struct sockaddr_storage localaddr;
diff -r db07337ac0c3 lib/imapoptions
--- a/lib/imapoptions	Sat Sep 29 13:41:01 2007 +0200
+++ b/lib/imapoptions	Sat Sep 29 13:41:15 2007 +0200
@@ -1014,7 +1014,7 @@ are listed with ``<none>''.
    mailbox hierarchy.  The default is to use the netnews separator
    character '.'. */
 
-{ "virtdomains", "off", ENUM("off", "userid", "on") }
+{ "virtdomains", "off", ENUM("off", "userid", "ldap", "on") }
 /* Enable virtual domain support.  If enabled, the user's domain will
    be determined by splitting a fully qualified userid at the last '@'
    or '%' symbol.  If the userid is unqualified, and the virtdomains
diff -r db07337ac0c3 lib/imapopts.c
--- a/lib/imapopts.c	Sat Sep 29 13:41:01 2007 +0200
+++ b/lib/imapopts.c	Sat Sep 29 13:41:15 2007 +0200
@@ -216,7 +216,7 @@ struct imapopt_s imapopts[] =
   { IMAPOPT_USERPREFIX, "userprefix", 0, {(void *)("Other Users")}, OPT_STRING, {  { NULL, IMAP_ENUM_ZERO } } },
   { IMAPOPT_UNIX_GROUP_ENABLE, "unix_group_enable", 0, {(void*)1}, OPT_SWITCH, {  { NULL, IMAP_ENUM_ZERO } } },
   { IMAPOPT_UNIXHIERARCHYSEP, "unixhierarchysep", 0, {(void*)0}, OPT_SWITCH, {  { NULL, IMAP_ENUM_ZERO } } },
-  { IMAPOPT_VIRTDOMAINS, "virtdomains", 0, {(void *)(IMAP_ENUM_VIRTDOMAINS_OFF)}, OPT_ENUM, { { "off" , IMAP_ENUM_VIRTDOMAINS_OFF }, { "userid" , IMAP_ENUM_VIRTDOMAINS_USERID }, { "on" , IMAP_ENUM_VIRTDOMAINS_ON },  { NULL, IMAP_ENUM_ZERO } } },
+  { IMAPOPT_VIRTDOMAINS, "virtdomains", 0, {(void *)(IMAP_ENUM_VIRTDOMAINS_OFF)}, OPT_ENUM, { { "off" , IMAP_ENUM_VIRTDOMAINS_OFF }, { "userid" , IMAP_ENUM_VIRTDOMAINS_USERID }, { "ldap" , IMAP_ENUM_VIRTDOMAINS_LDAP }, { "on" , IMAP_ENUM_VIRTDOMAINS_ON },  { NULL, IMAP_ENUM_ZERO } } },
 
   { IMAPOPT_LAST, NULL, 0, { NULL }, OPT_NOTOPT, {  { NULL, IMAP_ENUM_ZERO } } }
 
diff -r db07337ac0c3 lib/imapopts.h
--- a/lib/imapopts.h	Sat Sep 29 13:41:01 2007 +0200
+++ b/lib/imapopts.h	Sat Sep 29 13:41:15 2007 +0200
@@ -217,6 +217,7 @@ enum enum_value {
 
   IMAP_ENUM_VIRTDOMAINS_ON,
   IMAP_ENUM_VIRTDOMAINS_USERID,
+  IMAP_ENUM_VIRTDOMAINS_LDAP,
   IMAP_ENUM_VIRTDOMAINS_OFF = 0,
   IMAP_ENUM_SIEVE_EXTENSIONS_COPY = (1<<11),
   IMAP_ENUM_SIEVE_EXTENSIONS_SUBADDRESS = (1<<10),

--- NEW FILE: README_Annotations2.patch ---
DESCRIPTION:

There is an imap extension for adding "annotations" (eg. metadata) to
imap folders in the form of key/value pairs. The key is typically
something like /vendor/<vendorname>/<attributename>. Cyrus imapd only
supports a few special annotation keys for internal use (such as being
able to mark a folder for indexing etc.). The patch extends cyrus imapd
to allow arbitrary annotations on IMAP folders.

IMPACT:

The annotation patch is critical to kolab. Without the patch, the clients
will not know which folder is for calender, tasks etc.

REFERENCES:

Kolab bug tracker merge: 

https://intevation.de/roundup/kolab/merge4

Wiki page:

http://wiki.kolab.org/index.php/Template:Patches_cyrus

Mercurial patch repository:

http://hg.pardus.de/cgi-bin/hg.cgi/kolab/patches/cyrus-imapd/summary

HISTORY

The patch has been submitted upstream and the original version was rejected.

https://bugzilla.andrew.cmu.edu/show_bug.cgi?id=2458

A new version of the patch has been provided recently by Thomas Viemann 
(http://vman.de/cyrus/).

It looked as though upstream would accept the patch but so far nothing has 
happened. Another status inquiry on 2007-05-21.

--- NEW FILE: README_Folder-names.patch ---
DESCRIPTION:

Specifies the allowed characters in IMAP folder names.

IMPACT:

Without this patch some folder names will not work.

REFERENCES:

Kolab bug tracker merge: 

https://intevation.de/roundup/kolab/merge34

Wiki page:

http://wiki.kolab.org/index.php/Template:Patches_cyrus

Mercurial patch repository:

http://hg.pardus.de/cgi-bin/hg.cgi/kolab/patches/cyrus-imapd/summary

HISTORY

This patch hardwires the acceptable characters for folder names. 
This is something that will probably not be accepted upstream and 
the patch was never submitted. It would be good if this would be 
rewritten to make the acceptable characters a configuration option.


--- NEW FILE: README_Groups.patch ---
DESCRIPTION:

Plain cyrus imapd reads groups from /etc/group, and OpenPKG includes
a patch that allows us to use a private file (for example 
/kolab/etc/imapd/groupfile) for this instead of the system one. Groups 
in cyrus can be used in ACLs. To cater for MS windows users who are not 
used to "case matters", the kolab developers patched the openpkg patch 
to use case-insignificant string comparison when looking up groups.

IMPACT:

Groups won't work for the Kolab server if this patch is missing.

REFERENCES:

Kolab bug tracker merge: 

https://intevation.de/roundup/kolab/merge6

Wiki page:

http://wiki.kolab.org/index.php/Template:Patches_cyrus

Mercurial patch repository:

http://hg.pardus.de/cgi-bin/hg.cgi/kolab/patches/cyrus-imapd/summary

HISTORY

The patch has been submitted upstream but upstream never reacted.
Another status inquiry on 2007-05-21.

https://bugzilla.andrew.cmu.edu/show_bug.cgi?id=2632
--- NEW FILE: README_Logging.patch ---
DESCRIPTION:

Logs IMAP expunge events.

IMPACT:

Not absolutely required for the Kolab server. Just adds some more information
to your logs.

REFERENCES:

Kolab bug tracker merge: 

https://intevation.de/roundup/kolab/merge13

Wiki page:

http://wiki.kolab.org/index.php/Template:Patches_cyrus

Mercurial patch repository:

http://hg.pardus.de/cgi-bin/hg.cgi/kolab/patches/cyrus-imapd/summary

HISTORY

The patch has been submitted upstream on 2007-05-21.

https://bugzilla.andrew.cmu.edu/show_bug.cgi?id=2964
--- NEW FILE: README_UID.patch ---
DESCRIPTION:

Allows to use the uid instead of the mail address for logging into
the cyrus imap server.

IMPACT:

Without this patch users will be unable to use the UID for logging in.

REFERENCES:

Kolab bug tracker merge: 

https://intevation.de/roundup/kolab/merge5

Wiki page:

http://wiki.kolab.org/index.php/Template:Patches_cyrus

Mercurial patch repository:

http://hg.pardus.de/cgi-bin/hg.cgi/kolab/patches/cyrus-imapd/summary

HISTORY

This has been specifically written for Kolab and is not compatible
with upstream. It needs to be rewritten to a general LDAP filter
support if it should be integrated upstream.




More information about the commits mailing list