Branch '2.3-stable' - 2 commits - imapd/imapd.spec imapd/patches

Christoph Wickert wickert at kolabsys.com
Sat Sep 17 15:51:33 CEST 2011


 imapd/imapd.spec                                                                                    |   11 
 imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_Cyradm_Annotations.patch                  |   82 ++
 imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_Folder-names.patch                        |   17 
 imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_Groups2.patch                             |  233 ++++++
 imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_Logging.patch                             |   39 +
 imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_UID.patch                                 |  117 +++
 imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_cross-domain-acls.patch                   |  375 ++++++++++
 imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_timsieved_starttls-sendcaps.patch         |   21 
 imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_workaround-for-missing-user_deny.db.patch |   42 +
 imapd/patches/cyrus-imapd-2.3.17/series                                                             |    9 
 10 files changed, 944 insertions(+), 2 deletions(-)

New commits:
commit 894ec6f5bf3bab26068cd806bd14501129b1dc61
Author: Christoph Wickert <wickert at kolabsys.com>
Date:   Sat Sep 17 15:51:26 2011 +0200

    imapd: Bring back the workaround for missing user_deny.db (bugzilla.kolabsys.com #72)

diff --git a/imapd/imapd.spec b/imapd/imapd.spec
index 9d5c1f2..14c78d4 100644
--- a/imapd/imapd.spec
+++ b/imapd/imapd.spec
@@ -32,8 +32,7 @@ Class:        BASE
 Group:        Mail
 License:      BSD
 Version:      2.3.17
-Release:      20110909_kolab1
-
+Release:      20110909_kolab2
 #   package options
 %option       with_fsl             yes
 %option       with_group           no
@@ -76,6 +75,7 @@ Patch4:       patches/cyrus-imapd-%{version}/KOLAB_cyrus-imapd-%{version}_Loggin
 Patch5:       patches/cyrus-imapd-%{version}/KOLAB_cyrus-imapd-%{version}_UID.patch
 Patch6:       patches/cyrus-imapd-%{version}/KOLAB_cyrus-imapd-%{version}_Folder-names.patch
 Patch7:       patches/cyrus-imapd-%{version}/KOLAB_cyrus-imapd-%{version}_timsieved_starttls-sendcaps.patch
+Patch8:       patches/cyrus-imapd-%{version}/KOLAB_cyrus-imapd-%{version}_workaround-for-missing-user_deny.db.patch
 
 #   build information
 Prefix:       %{l_prefix}
@@ -160,6 +160,10 @@ AutoReqProv:  no
      %patch -p1 -P 7
 %endif
 
+    #   kolab/issue4729 (Kolab 2.3.0 lacks /kolab/var/imapd/user_deny.db)
+    #   bugzilla.kolabsys.com #72 (user_deny.db not found)
+%patch -p1 -P 8
+
     #   add optional DRAC file support
 %if "%{with_drac}" == "yes"
     %{l_shtool} subst -e 's;@DRACLIBS@;-ldrac;g' contrib/drac_auth.patch
@@ -430,6 +434,9 @@ AutoReqProv:  no
 
 
 %changelog
+* Sat Sep 17 2011 Christoph Wickert <wickert at kolabsys.com> - 2.3.17-20110909_kolab2
+- Bring back the workaround for missing user_deny.db (bugzilla.kolabsys.com #72)
+
 * Fri Sep 09 2011 Christoph Wickert <wickert at kolabsys.com> - 2.3.17-20110909_kolab1
 - Update to 2.3.17, fixes CVE-2011-3208
 


commit 7a5433de527d0f039fdf14a3b59dfef8c4e0e7c4
Author: Christoph Wickert <wickert at kolabsys.com>
Date:   Sat Sep 17 15:49:37 2011 +0200

    imapd: Add missing patches for 2.3.17

diff --git a/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_Cyradm_Annotations.patch b/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_Cyradm_Annotations.patch
new file mode 100644
index 0000000..08cbe6b
--- /dev/null
+++ b/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_Cyradm_Annotations.patch
@@ -0,0 +1,82 @@
+Allows to use arbitrary annotations with the cyradm tool.
+
+diff -r 69927cac0b1b doc/man/cyradm.1.html
+--- a/doc/man/cyradm.1.html	Fri Dec 04 10:32:26 2009 +0100
++++ b/doc/man/cyradm.1.html	Fri Dec 04 10:32:33 2009 +0100
+@@ -220,6 +220,13 @@
+ <dd>
+ <p>Sets an email address to which messages injected into the server via NNTP 
+ will be sent.</p>
++</dd>
++</li>
++<dt><strong><a NAME="item__2fexplicit_2fannotation"><code>/explicit/annotation</code></a></strong>
++
++<dd>
++<p>Sets the annotation <em>/explicit/annotation</em>
++on <em>mailbox</em> to <em>value</em>.</p>
+ </dd>
+ <dt><strong><a name="sharedseen" class="item"><code>sharedseen</code></a></strong></dt>
+ 
+diff -r 69927cac0b1b perl/imap/IMAP/Admin.pm
+--- a/perl/imap/IMAP/Admin.pm	Fri Dec 04 10:32:26 2009 +0100
++++ b/perl/imap/IMAP/Admin.pm	Fri Dec 04 10:32:33 2009 +0100
+@@ -797,11 +797,11 @@
+     return undef;
+   }
+ 
+-  if(!exists($values{$entry})) {
+-    $self->{error} = "Unknown parameter $entry";
++  if(exists($values{$entry})) {
++    $entry = $values{$entry};    
++  } else {
++    $self->{error} = "Unknown parameter $entry" unless substr($entry,0,1) eq "/";
+   }
+-
+-  $entry = $values{$entry};
+ 
+   my ($rc, $msg);
+ 
+diff -r 69927cac0b1b perl/imap/IMAP/Shell.pm
+--- a/perl/imap/IMAP/Shell.pm	Fri Dec 04 10:32:26 2009 +0100
++++ b/perl/imap/IMAP/Shell.pm	Fri Dec 04 10:32:33 2009 +0100
+@@ -127,7 +127,7 @@
+ 		  [\&_sc_info, '[mailbox]',
+ 		   'display mailbox/server metadata'],
+ 		mboxcfg =>
+-		  [\&_sc_mboxcfg, 'mailbox [comment|condstore|expire|news2mail|sharedseen|sieve|squat] value',
++		  [\&_sc_mboxcfg, 'mailbox [comment|condstore|news2mail|expire|sieve|squat|/<explicit annotation>] value',
+ 		   'configure mailbox'],
+ 		mboxconfig => 'mboxcfg',
+ 		reconstruct =>
+@@ -1437,7 +1437,7 @@
+   while (defined ($opt = shift(@argv))) {
+     last if $opt eq '--';
+     if ($opt =~ /^-/) {
+-      die "usage: mboxconfig mailbox [comment|condstore|expire|news2mail|sharedseen|sieve|squat] value\n";
++      die "usage: mboxconfig mailbox [comment|condstore|expire|news2mail|sharedseen|sieve|squat|/<explicit annotation>] value\n";
+     }
+     else {
+       push(@nargv, $opt);
+@@ -1446,7 +1446,7 @@
+   }
+   push(@nargv, @argv);
+   if (@nargv < 2) {
+-    die "usage: mboxconfig mailbox [comment|condstore|expire|news2mail|sharedseen|sieve|squat] value\n";
++    die "usage: mboxconfig mailbox [comment|condstore|expire|news2mail|sharedseen|sieve|squat|/<explicit annotation>] value\n";
+   }
+   if (!$cyrref || !$$cyrref) {
+     die "mboxconfig: no connection to server\n";
+diff -r 69927cac0b1b perl/imap/cyradm.sh
+--- a/perl/imap/cyradm.sh	Fri Dec 04 10:32:26 2009 +0100
++++ b/perl/imap/cyradm.sh	Fri Dec 04 10:32:33 2009 +0100
+@@ -241,6 +241,10 @@
+ 
+ Indicates that the mailbox should have a squat index created for it.
+ 
++=item C</explicit/annotation>
++
++Sets the annotation I</explicit/annotation> on I<mailbox> to I<value>. 
++
+ =back 
+ 
+ =item C<renamemailbox> [C<--partition> I<partition>] I<oldname> I<newname>
diff --git a/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_Folder-names.patch b/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_Folder-names.patch
new file mode 100644
index 0000000..2f8689a
--- /dev/null
+++ b/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_Folder-names.patch
@@ -0,0 +1,17 @@
+Modifies the set of accepted characters in folder names for the cyrus imapd server [Version: 2.3.9]
+
+diff -r 17e54b46d7b6 imap/mboxname.c
+--- a/imap/mboxname.c	Mon Oct 27 18:44:56 2008 +0100
++++ b/imap/mboxname.c	Mon Oct 27 18:47:11 2008 +0100
+@@ -713,8 +713,10 @@
+ /*
+  * Apply site policy restrictions on mailbox names.
+  * Restrictions are hardwired for now.
++ * original definition 
++#define GOODCHARS " #$'+,-.0123456789:=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"
+  */
+-#define GOODCHARS " #$'+,-.0123456789:=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"
++#define GOODCHARS " #$%'()*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~"
+ int mboxname_policycheck(char *name)
+ {
+     unsigned i;
diff --git a/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_Groups2.patch b/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_Groups2.patch
new file mode 100644
index 0000000..0cb71d8
--- /dev/null
+++ b/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_Groups2.patch
@@ -0,0 +1,233 @@
+diff -r 37030bf2b2bb lib/auth_unix.c
+--- a/lib/auth_unix.c	Fri Dec 04 10:25:24 2009 +0100
++++ b/lib/auth_unix.c	Fri Dec 04 10:32:19 2009 +0100
+@@ -46,6 +46,7 @@
+ #include <stdlib.h>
+ #include <pwd.h>
+ #include <grp.h>
++#include <stdio.h>
+ #include <ctype.h>
+ #include <string.h>
+ 
+@@ -54,6 +55,126 @@
+ #include "xmalloc.h"
+ #include "util.h"
+ 
++#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
++/*
++ * __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];
+     char **group;
+@@ -141,6 +262,25 @@
+     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 (strcmp(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
+@@ -176,7 +316,7 @@
+      */
+     
+     if (!strncmp(retbuf, "group:", 6)) {
+-	grp = getgrnam(retbuf+6);
++	grp = fgetgrnam(retbuf+6);
+ 	if (!grp) return NULL;
+ 	if (strlen(grp->gr_name) >= sizeof(retbuf)-6)
+ 		return NULL;
+@@ -224,11 +364,12 @@
+     struct auth_state *newstate;
+     struct passwd *pwd;
+     struct group *grp;
+-#if defined(HAVE_GETGROUPLIST) && defined(__GLIBC__)
++#if 0 && defined(HAVE_GETGROUPLIST) && defined(__GLIBC__)
+     gid_t gid, *groupids = NULL;
+     int ret, ngroups = 10;
+ #else
+     char **mem;
++    FILE *groupfile;
+ #endif
+ 
+     identifier = mycanonifyid(identifier, 0);
+@@ -246,7 +387,7 @@
+ 
+     pwd = getpwnam(identifier);
+ 
+-#if defined(HAVE_GETGROUPLIST) && defined(__GLIBC__)
++#if 0 && defined(HAVE_GETGROUPLIST) && defined(__GLIBC__)
+     gid = pwd ? pwd->pw_gid : (gid_t) -1;
+ 
+     /* get the group ids */
+@@ -284,20 +425,23 @@
+     if (groupids) free(groupids);
+ 
+ #else /* !HAVE_GETGROUPLIST */
+-    setgrent();
+-    while ((grp = getgrent())) {
+-	for (mem = grp->gr_mem; *mem; mem++) {
+-	    if (!strcmp(*mem, identifier)) break;
+-	}
++    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 (!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();
++         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);
++    } 
+ #endif /* HAVE_GETGROUPLIST */
+ 
+     return newstate;
diff --git a/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_Logging.patch b/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_Logging.patch
new file mode 100644
index 0000000..fd7a765
--- /dev/null
+++ b/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_Logging.patch
@@ -0,0 +1,39 @@
+Provides improved logging for the cyrus imapd server [Version: 2.3.9]
+
+diff -r e17e42827afc imap/append.c
+--- a/imap/append.c	Wed Dec 23 20:17:41 2009 +0100
++++ b/imap/append.c	Wed Dec 23 20:49:56 2009 +0100
+@@ -654,6 +654,9 @@
+     /* 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 e17e42827afc imap/imapd.c
+--- a/imap/imapd.c	Wed Dec 23 20:17:41 2009 +0100
++++ b/imap/imapd.c	Wed Dec 23 20:49:56 2009 +0100
+@@ -3638,6 +3638,8 @@
+     if ((cmd[0] == 'C') && (imapd_mailbox->myrights & ACL_EXPUNGE)) {
+ 	if (!mailbox_expunge(imapd_mailbox, NULL, NULL, 0)) {
+ 	    sync_log_mailbox(imapd_mailbox->name);
++	    syslog(LOG_DEBUG, "cmd_expunge: user %s, mailbox %s, sequence %s",
++		   imapd_userid, imapd_mailbox->name, "''");
+ 	}
+     }
+ 
+diff -r e17e42827afc imap/mailbox.c
+--- a/imap/mailbox.c	Wed Dec 23 20:17:41 2009 +0100
++++ b/imap/mailbox.c	Wed Dec 23 20:49:56 2009 +0100
+@@ -2575,6 +2575,8 @@
+ 	*(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);
diff --git a/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_UID.patch b/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_UID.patch
new file mode 100644
index 0000000..ecc960d
--- /dev/null
+++ b/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_UID.patch
@@ -0,0 +1,117 @@
+Allows login by uid rather than the mail address on the cyrus imapd server [Version: 2.3.9]
+
+diff -r 2ebe14b7db9d configure
+--- a/configure	Mon Oct 27 18:47:12 2008 +0100
++++ b/configure	Mon Oct 27 18:48:18 2008 +0100
+@@ -19667,7 +19667,7 @@
+ done
+ 
+ IMAP_COM_ERR_LIBS="${COM_ERR_LIBS}"
+-IMAP_LIBS="${LIB_SASL} ${LIBS} ${SQL_LIBS}"
++IMAP_LIBS="${LIB_SASL} -lldap -llber ${LIBS} ${SQL_LIBS}"
+ 
+ 
+ 
+diff -r 2ebe14b7db9d imap/global.c
+--- a/imap/global.c	Mon Oct 27 18:47:12 2008 +0100
++++ b/imap/global.c	Mon Oct 27 18:48:18 2008 +0100
+@@ -52,6 +52,9 @@
+ #include <sys/types.h>
+ #include <netinet/in.h>
+ #include <sys/stat.h>
++
++#include <ldap.h>
++#include <lber.h>
+ 
+ #if HAVE_UNISTD_H
+ # include <unistd.h>
+@@ -378,6 +381,18 @@
+     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;
++    struct berval** vals;
++
++    int rc;
+ 
+     /* check for domain */
+     if (config_virtdomains &&
+@@ -396,6 +411,49 @@
+     }
+ 
+     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_len(handle, entry, "mail")) ) {
++  				    if (memchr(vals[0]->bv_val, '@', vals[0]->bv_len)) {
++				        static char buf[81]; /* same size as in auth_canonifyid */
++					   int len = ((sizeof(buf) - 1) > vals[0]->bv_len ? vals[0]->bv_len : sizeof(buf) - 1);
++					strncpy( buf, vals[0]->bv_val, len);
++					buf[len] = '\0'; /* make sure it's null-terminated */
++					ldap_value_free_len( vals );
++				        ldap_msgfree( res );
++					ldap_unbind_s(handle); /* also frees handle */
++					syslog(LOG_DEBUG, "canonify: '%s'\n", buf);
++				        return auth_canonifyid( buf, 0) ;
++				    }
++				    ldap_value_free_len( 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 */
+@@ -408,7 +466,7 @@
+ 		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 2ebe14b7db9d lib/imapoptions
+--- a/lib/imapoptions	Mon Oct 27 18:47:12 2008 +0100
++++ b/lib/imapoptions	Mon Oct 27 18:48:18 2008 +0100
+@@ -1114,7 +1114,7 @@
+    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 --git a/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_cross-domain-acls.patch b/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_cross-domain-acls.patch
new file mode 100644
index 0000000..210f004
--- /dev/null
+++ b/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_cross-domain-acls.patch
@@ -0,0 +1,375 @@
+Index: imap/mboxlist.c
+===================================================================
+RCS file: /cvs/src/cyrus/imap/mboxlist.c,v
+retrieving revision 1.270
+diff -u -r1.270 mboxlist.c
+--- imap/mboxlist.c	28 Jul 2009 02:46:23 -0000	1.270
++++ imap/mboxlist.c	11 Dec 2009 20:49:36 -0000
+@@ -1576,7 +1576,7 @@
+ 	   except for "anonymous", "anyone", the global admin
+ 	   and users in the default domain */
+ 	if ((cp = strchr(identifier, '@'))) {
+-	    if (rights &&
++	    if (!config_getswitch(IMAPOPT_ALLOWCROSSDOMAINACLS) && rights &&
+ 		((domain && strncasecmp(cp+1, domain, strlen(cp+1))) ||
+ 		 (!domain && (!config_defdomain ||
+ 			      strcasecmp(config_defdomain, cp+1))))) {
+@@ -1918,6 +1918,7 @@
+     int usermboxnamelen;
+     int checkmboxlist;
+     int checkshared;
++    int crossdomain;
+     int isadmin;
+     struct auth_state *auth_state;
+     int (*proc)(char *, int, int, void *rock);
+@@ -1935,7 +1936,9 @@
+     long matchlen;
+ 
+     /* don't list mailboxes outside of the default domain */
+-    if (!rock->domainlen && !rock->isadmin && memchr(key, '!', keylen)) return 0; 
++    if (!rock->domainlen && !rock->isadmin && memchr(key, '!', keylen) &&
++	!config_getswitch(IMAPOPT_ALLOWCROSSDOMAINACLS))
++	return 0;
+ 
+     minmatch = 0;
+     if (rock->inboxoffset) {
+@@ -2108,6 +2111,23 @@
+ 	    }
+ 
+ 	    rock->checkshared = 0;
++
++	    if (rock->find_namespace == NAMESPACE_USER &&
++		config_getswitch(IMAPOPT_ALLOWCROSSDOMAINACLS) && !rock->isadmin &&
++		!rock->crossdomain) {
++		char *cp = strchr(namebuf+rock->inboxoffset, '!');
++		if (cp) {
++		    int local_matchlen = (matchlen - 1 -
++					  (cp - (namebuf+rock->inboxoffset)));
++		    if (!strncmp(cp + 1, "user", local_matchlen)) {
++			r = (*rock->proc)(cp + 1, local_matchlen, 1,
++					  rock->procrock);
++			return CYRUSDB_DONE;
++		    }
++		}
++	    }
++
++
+ 	    r = (*rock->proc)(namebuf+rock->inboxoffset, matchlen, 
+ 			      1, rock->procrock);
+ 
+@@ -2128,6 +2148,91 @@
+     return r;
+ }
+ 
++
++static void convert_cross_domain_pattern(char *domainpat, int domainpatlen,
++					 char **converted_pattern,
++					 const char *pattern, int *crossdomainmatch,
++					 const char *domain)
++{
++    int patternlen = strlen(pattern);
++    char *domain_pattern, *local_dest;
++    char *local_pattern, *domain_dest;
++    int local_prefix_len;
++    const char *src;
++    int c;
++
++    domain_dest = domain_pattern = xmalloc(patternlen + 1);
++    local_dest = local_pattern = xmalloc(patternlen + 1);
++    src = pattern;
++
++    while ((c = *src++)) {
++	*local_dest++ = c;
++	if (c == '.' || c == '*')
++	    break;
++    }
++
++    local_prefix_len = local_dest - local_pattern;
++    if (c && c != '.')
++	local_prefix_len -= 1;
++    if (strncmp(pattern, "user.", local_prefix_len) == 0) {
++	/* pattern matches "user.*".  so convert the domain part of the
++	 * pattern */
++
++	if (c == '*') {
++	    /* the pattern can match any domain */
++	    *domain_dest++ = '*';
++	}
++	else if (c == '.') {
++	    while ((c = *src++)) {
++		if (c == '.')
++		    break;
++		if (c == '^')
++		    c = '.';
++		*domain_dest++ = (c == '%' ? '*' : c);
++		if (c == '*')
++		    break;
++	    }
++
++	    if (c == '*') {
++		*local_dest++ = '*';
++	    }
++	}
++
++	if (c) {
++	    strcpy(local_dest, src);
++	}
++	else {
++	    if (local_dest > local_pattern) {
++		if (local_dest[-1] == '.') {
++		    local_dest--;
++		}
++	    }
++	    *local_dest = 0;
++	}
++
++	if (domain_dest == domain_pattern) {
++	    *domain_dest++ = '*';
++	}
++	*domain_dest++ = '!';
++	*domain_dest = 0;
++
++	strncpy(domainpat, domain_pattern, domainpatlen);
++	domainpat[domainpatlen - 1] = 0;
++	strncat(domainpat, local_pattern, domainpatlen - strlen(domainpat) - 1);
++
++	*converted_pattern = xstrdup(local_pattern);
++	*crossdomainmatch = 1;
++    }
++    else {
++	/* pattern doesn't contain an explicit domain part */
++	snprintf(domainpat, domainpatlen, "*!%s", pattern);
++	*crossdomainmatch = 0;
++    }
++
++    free(domain_pattern);
++    free(local_pattern);
++}
++
+ /*
+  * Find all mailboxes that match 'pattern'.
+  * 'isadmin' is nonzero if user is a mailbox admin.  'userid'
+@@ -2151,8 +2256,11 @@
+     char *p;
+     int prefixlen;
+     int userlen = userid ? strlen(userid) : 0, domainlen = 0;
++    int domainpat_prefixlen = 0;
+     char domainpat[MAX_MAILBOX_BUFFER] = ""; /* do intra-domain fetches only */
+     char *pat = NULL;
++    char *converted_pattern = NULL;
++    int crossdomainmatch = 0;
+ 
+     if (config_virtdomains) {
+ 	char *domain;
+@@ -2162,8 +2270,10 @@
+ 	    domainlen = strlen(domain); /* includes separator */
+ 
+ 	    if ((p = strchr(pattern , '!'))) {
+-		if ((p-pattern != domainlen-1) ||
+-		    strncmp(pattern, domain+1, domainlen-1)) {
++		if (!(config_getswitch(IMAPOPT_ALLOWCROSSDOMAINACLS) &&
++		      !isadmin) &&
++		    ((p-pattern != domainlen-1) ||
++		     strncmp(pattern, domain+1, domainlen-1))) {
+ 		    /* don't allow cross-domain access */
+ 		    return IMAP_MAILBOX_BADNAME;
+ 		}
+@@ -2171,7 +2281,16 @@
+ 		pattern = p+1;
+ 	    }
+ 
+-	    snprintf(domainpat, sizeof(domainpat), "%s!%s", domain+1, pattern);
++	    if (!(config_getswitch(IMAPOPT_ALLOWCROSSDOMAINACLS) && !isadmin)) {
++		snprintf(domainpat, sizeof(domainpat), "%s!%s", domain+1, pattern);
++	    }
++	    else {
++		convert_cross_domain_pattern(domainpat, sizeof(domainpat),
++					     &converted_pattern, pattern,
++					     &crossdomainmatch, domain + 1);
++		if (converted_pattern)
++		    pattern = converted_pattern;
++	    }
+ 	}
+ 	if ((p = strrchr(pattern, '@'))) {
+ 	    /* global admin specified mbox at domain */
+@@ -2201,6 +2320,7 @@
+     cbrock.auth_state = auth_state;
+     cbrock.checkmboxlist = 0;	/* don't duplicate work */
+     cbrock.checkshared = 0;
++    cbrock.crossdomain = 0;
+     cbrock.proc = proc;
+     cbrock.procrock = rock;
+ 
+@@ -2260,6 +2380,12 @@
+     prefixlen = p - pattern;
+     *p = '\0';
+ 
++    /* Find fixed-string domain pattern prefix */
++    for (p = domainpat; *p; p++) {
++	if (*p == '*' || *p == '%' || *p == '?' || *p == '@') break;
++    }
++    domainpat_prefixlen = p - domainpat;
++
+     /*
+      * If user.X.* or INBOX.* can match pattern,
+      * search for those mailboxes next
+@@ -2292,6 +2418,7 @@
+ 	glob_free(&cbrock.g);
+ 	cbrock.g = glob_init(domainpat, GLOB_HIERARCHY);
+ 	cbrock.inboxoffset = 0;
++	cbrock.crossdomain = crossdomainmatch;
+ 	if (usermboxnamelen) {
+ 	    usermboxname[--usermboxnamelen] = '\0';
+ 	    cbrock.usermboxname = usermboxname;
+@@ -2301,7 +2428,7 @@
+ 	   just bother looking at the ones that have the same pattern
+ 	   prefix. */
+ 	r = DB->foreach(mbdb,
+-			domainpat, domainlen + prefixlen,
++			domainpat, domainpat_prefixlen,
+ 			&find_p, &find_cb, &cbrock,
+ 			NULL);
+     }
+@@ -2310,6 +2437,7 @@
+   done:
+     glob_free(&cbrock.g);
+     if (pat) free(pat);
++    if (converted_pattern) free(converted_pattern);
+ 
+     return r;
+ }
+@@ -2347,6 +2475,7 @@
+     cbrock.auth_state = auth_state;
+     cbrock.checkmboxlist = 0;	/* don't duplicate work */
+     cbrock.checkshared = 0;
++    cbrock.crossdomain = 0;
+     cbrock.proc = proc;
+     cbrock.procrock = rock;
+ 
+@@ -2987,6 +3116,7 @@
+     cbrock.auth_state = auth_state;
+     cbrock.checkmboxlist = !force;
+     cbrock.checkshared = 0;
++    cbrock.crossdomain = 0;
+     cbrock.proc = proc;
+     cbrock.procrock = rock;
+ 
+@@ -3138,6 +3268,7 @@
+     cbrock.auth_state = auth_state;
+     cbrock.checkmboxlist = !force;
+     cbrock.checkshared = 0;
++    cbrock.crossdomain = 0;
+     cbrock.proc = proc;
+     cbrock.procrock = rock;
+ 
+Index: imap/mboxname.c
+===================================================================
+RCS file: /cvs/src/cyrus/imap/mboxname.c,v
+retrieving revision 1.47
+diff -u -r1.47 mboxname.c
+--- imap/mboxname.c	28 Jul 2009 06:17:26 -0000	1.47
++++ imap/mboxname.c	11 Dec 2009 20:49:36 -0000
+@@ -112,6 +112,8 @@
+ {
+     char *cp;
+     int userlen, domainlen = 0, namelen;
++    int name_has_domain = 0;
++    const char *name_local_part = NULL;
+ 
+     /* Blank the result, just in case */
+     result[0] = '\0';
+@@ -156,6 +158,18 @@
+ 	    }
+ 	}
+ 
++	if (config_getswitch(IMAPOPT_ALLOWCROSSDOMAINACLS) &&
++	    !namespace->isadmin &&
++	    !strncmp(name, "user", 4) && name[4] == namespace->hier_sep) {
++	    name_local_part = strchr(name + 5, namespace->hier_sep);
++	    if (!name_local_part) {
++		name_local_part = name + strlen(name);
++	    }
++	    domainlen = name_local_part - (name + 5) + 1;
++	    sprintf(result, "%.*s!", domainlen - 1, name + 5);
++	    name_has_domain = 1;
++	}
++
+ 	/* if no domain specified, we're in the default domain */
+     }
+ 
+@@ -186,7 +200,13 @@
+     if (domainlen+namelen > MAX_MAILBOX_NAME) {
+ 	return IMAP_MAILBOX_BADNAME;
+     }
+-    sprintf(result, "%.*s", namelen, name);
++
++    if (name_has_domain) {
++	sprintf(result, "user%s", name_local_part ? name_local_part : "");
++    }
++    else {
++	sprintf(result, "%.*s", namelen, name);
++    }
+ 
+     /* Translate any separators in mailboxname */
+     mboxname_hiersep_tointernal(namespace, result, 0);
+@@ -349,6 +369,7 @@
+ {
+     char *domain = NULL, *cp;
+     size_t domainlen = 0, resultlen;
++    int append_domain = 1;
+ 
+     /* Blank the result, just in case */
+     result[0] = '\0';
+@@ -363,18 +384,29 @@
+ 	/* don't use the domain if it matches the user's domain */
+ 	if (userid && (cp = strchr(userid, '@')) &&
+ 	    (strlen(++cp) == domainlen) && !strncmp(domain, cp, domainlen))
+-	    domain = NULL;
++	    append_domain = 0;
+     }
+ 
+-    strcpy(result, name);
+-
+-    /* Translate any separators in mailboxname */
+-    mboxname_hiersep_toexternal(namespace, result, 0);
++    if (config_getswitch(IMAPOPT_ALLOWCROSSDOMAINACLS) && !namespace->isadmin
++	&& domain && !strncmp(name, "user", 4) &&
++	(name[4] == 0 || name[4] == '.')) {
++	sprintf(result, "user%c%.*s", namespace->hier_sep, domainlen, domain);
++	if (name[4] != 0)
++	    sprintf(result + domainlen + 5, "%c%s", namespace->hier_sep,
++		    name + 5);
++	mboxname_hiersep_toexternal(namespace, result + domainlen + 6, 0);
++	append_domain = 0;
++    }
++    else {
++	strcpy(result, name);
++	/* Translate any separators in mailboxname */
++	mboxname_hiersep_toexternal(namespace, result, 0);
++    }
+ 
+     resultlen = strlen(result);
+ 
+     /* Append domain */
+-    if (domain) {
++    if (domain && append_domain) {
+ 	if(resultlen+domainlen+1 > MAX_MAILBOX_NAME) 
+ 	    return IMAP_MAILBOX_BADNAME;
+ 
+Index: lib/imapoptions
+===================================================================
+RCS file: /cvs/src/cyrus/lib/imapoptions,v
+retrieving revision 1.67
+diff -u -r1.67 imapoptions
+--- lib/imapoptions	29 Jun 2009 17:21:06 -0000	1.67
++++ lib/imapoptions	11 Dec 2009 20:49:38 -0000
+@@ -1155,6 +1155,9 @@
+    interface, otherwise the user is assumed to be in the default
+    domain (if set). */
+ 
++{ "allowcrossdomainacls", 0, SWITCH }
++/* Allow ACL across domain boundaries. */
++
+ /*
+ .SH SEE ALSO
+ .PP
diff --git a/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_timsieved_starttls-sendcaps.patch b/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_timsieved_starttls-sendcaps.patch
new file mode 100644
index 0000000..45088d8
--- /dev/null
+++ b/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_timsieved_starttls-sendcaps.patch
@@ -0,0 +1,21 @@
+This patch was downloaded from https://bugzilla.andrew.cmu.edu/cgi-bin/cvsweb.cgi/src/cyrus/timsieved/parser.c.diff?r1=1.44;r2=1.45
+(minus the CVS keywords)
+
+It should be reverse-applied with patch -p2 -R to work around the kontact
+behaviour described in kolab/issue2443 (kontact aborts sieve when imapd sends
+capabilities after starttls) and can be dropped as soon as kontact has a way
+to work with old and new cyrus imapd servers.
+
+diff -r 1688e25afb65 timsieved/parser.c
+--- a/timsieved/parser.c	Thu Apr 23 23:28:07 2009 +0200
++++ b/timsieved/parser.c	Thu Apr 23 23:28:54 2009 +0200
+@@ -908,8 +908,7 @@
+ 
+     starttls_done = 1;
+ 
+-    return capabilities(sieved_out, sieved_saslconn, starttls_done,
+-			authenticated, sasl_ssf);
++    return result;
+ }
+ #else
+ static int cmd_starttls(struct protstream *sieved_out, struct protstream *sieved_in)
diff --git a/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_workaround-for-missing-user_deny.db.patch b/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_workaround-for-missing-user_deny.db.patch
new file mode 100644
index 0000000..3bea233
--- /dev/null
+++ b/imapd/patches/cyrus-imapd-2.3.17/KOLAB_cyrus-imapd-2.3.17_workaround-for-missing-user_deny.db.patch
@@ -0,0 +1,42 @@
+From 1bfda761c67e62ebce7568c67d5fefe6a1ace025 Mon Sep 17 00:00:00 2001
+From: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
+Date: Tue, 3 Aug 2010 10:38:55 +0200
+Subject: [PATCH 12/13] Workaround for missing user_deny.db
+
+If there is no user_deny.db, then all users are denied by default
+in 2.3.16. This patch circumvents that by returning OK when no
+user_deny.db exists.
+---
+ imap/global.c |    8 ++++++++
+ 1 files changed, 8 insertions(+), 0 deletions(-)
+
+diff --git a/imap/global.c b/imap/global.c
+index 5d64895..dac3d1c 100644
+--- a/imap/global.c
++++ b/imap/global.c
+@@ -542,14 +542,22 @@ static int acl_ok(const char *user, struct auth_state *authstate)
+ int access_ok(const char *user, const char *service, char *msgbuf, int size)
+ {
+     static char *fname = NULL;
++    static int nodb = 0;
+     struct db *db = NULL;
+     int r, ret = 1;  /* access always granted by default */
+ 
++    if (nodb) return ret;
++
+     if (!fname) {
++	struct stat s;
+ 	/* create path to database */
+ 	fname = xmalloc(strlen(config_dir) + sizeof(FNAME_USERDENYDB) + 1);
+ 	strcpy(fname, config_dir);
+ 	strcat(fname, FNAME_USERDENYDB);
++	if (stat(fname, &s) == -1 && errno==ENOENT) {
++	    nodb = 1;
++	    return ret;
++	}
+     }
+ 
+     /* try to open database */
+-- 
+1.7.2
+
diff --git a/imapd/patches/cyrus-imapd-2.3.17/series b/imapd/patches/cyrus-imapd-2.3.17/series
new file mode 100644
index 0000000..fbb1d64
--- /dev/null
+++ b/imapd/patches/cyrus-imapd-2.3.17/series
@@ -0,0 +1,9 @@
+KOLAB_Groups2.patch
+KOLAB_cross-domain-acls.patch
+KOLAB_Logging.patch
+KOLAB_Folder-names.patch
+KOLAB_UID.patch
+KOLAB_Cyradm_Annotations.patch
+KOLAB_timsieved_starttls-sendcaps.patch
+KOLAB_flush-buffer-after-TLS-initiation.patch
+KOLAB_workaround-for-missing-user_deny.db.patch





More information about the commits mailing list