diff -Nur cyrus-imapd-2.4-2.4.9.orig/configure.in cyrus-imapd-2.4-2.4.9/configure.in
--- cyrus-imapd-2.4-2.4.9.orig/configure.in	2011-09-08 12:07:33.552218491 +0200
+++ cyrus-imapd-2.4-2.4.9/configure.in	2011-09-08 14:36:13.892717720 +0200
@@ -1240,7 +1240,7 @@
 done
 
 IMAP_COM_ERR_LIBS="${COM_ERR_LIBS}"
-IMAP_LIBS="${LIB_SASL} ${LIBS} ${SQL_LIBS}"
+IMAP_LIBS="${LIB_SASL} ${LIBS} ${SQL_LIBS} -lldap"
 
 AC_SUBST(LIB_RT)
 AC_SUBST(IMAP_COM_ERR_LIBS)
diff -Nur cyrus-imapd-2.4-2.4.9.orig/imap/global.c cyrus-imapd-2.4-2.4.9/imap/global.c
--- cyrus-imapd-2.4-2.4.9.orig/imap/global.c	2011-09-08 12:07:33.539718227 +0200
+++ cyrus-imapd-2.4-2.4.9/imap/global.c	2011-09-08 14:36:13.903217897 +0200
@@ -256,6 +256,22 @@
 				  config_getstring(IMAPOPT_SQL_PASSWD));
 	libcyrus_config_setswitch(CYRUSOPT_SQL_USESSL,
 				  config_getswitch(IMAPOPT_SQL_USESSL));
+	libcyrus_config_setswitch(CYRUSOPT_AUTH_LDAP_GROUP_ENABLE,
+				  config_getswitch(IMAPOPT_AUTH_LDAP_GROUP));
+	libcyrus_config_setstring(CYRUSOPT_LDAP_BASE,
+				  config_getstring(IMAPOPT_LDAP_BASE));
+	libcyrus_config_setstring(CYRUSOPT_LDAP_HOST,
+				  config_getstring(IMAPOPT_LDAP_HOST));
+	libcyrus_config_setint(CYRUSOPT_LDAP_PORT,
+				  config_getint(IMAPOPT_LDAP_PORT));
+	libcyrus_config_setstring(CYRUSOPT_LDAP_FROM_ATTR,
+				  config_getstring(IMAPOPT_LDAP_FROM_ATTR));
+	libcyrus_config_setstring(CYRUSOPT_LDAP_TO_ATTR,
+				  config_getstring(IMAPOPT_LDAP_TO_ATTR));
+	libcyrus_config_setstring(CYRUSOPT_LDAP_BINDDN,
+				  config_getstring(IMAPOPT_LDAP_BINDDN));
+	libcyrus_config_setstring(CYRUSOPT_LDAP_BINDPWFILE,
+				  config_getstring(IMAPOPT_LDAP_BINDPWFILE));
 
 	/* Not until all configuration parameters are set! */
 	libcyrus_init();
diff -Nur cyrus-imapd-2.4-2.4.9.orig/lib/imapoptions cyrus-imapd-2.4-2.4.9/lib/imapoptions
--- cyrus-imapd-2.4-2.4.9.orig/lib/imapoptions	2011-09-08 12:07:33.603220258 +0200
+++ cyrus-imapd-2.4-2.4.9/lib/imapoptions	2011-09-08 14:36:13.915717363 +0200
@@ -1368,6 +1368,24 @@
    to set this to yes, especially if OpenLDAP is used as authentication
    source. */
 
+{ "auth_ldap_group", 0, SWITCH }
+/* auth_ldap_group from kolab patch. */
+
+{ "ldap_from_attr", "mailPrimaryAddress", STRING }
+/* ldap_from_attr from kolab patch. */
+
+{ "ldap_host", "localhost", STRING }
+/* ldap_host from kolab patch. */
+
+{ "ldap_port", 389, INT }
+/* ldap_port from kolab patch. */
+
+{ "ldap_to_attr", "uid", STRING }
+/* ldap_to_attr from kolab patch. */
+
+{ "ldap_binddn", "", STRING }
+{ "ldap_bindpwfile", "/etc/cyrus-ldap.secret", STRING }
+
 /*
 .SH SEE ALSO
 .PP
diff -Nur cyrus-imapd-2.4-2.4.9.orig/lib/libcyr_cfg.c cyrus-imapd-2.4-2.4.9/lib/libcyr_cfg.c
--- cyrus-imapd-2.4-2.4.9.orig/lib/libcyr_cfg.c	2011-09-08 12:07:33.599220128 +0200
+++ cyrus-imapd-2.4-2.4.9/lib/libcyr_cfg.c	2011-09-08 14:36:13.931717510 +0200
@@ -162,6 +162,38 @@
       CFGVAL(long, 1),
       CYRUS_OPT_SWITCH },
 
+    { CYRUSOPT_AUTH_LDAP_GROUP_ENABLE,
+      CFGVAL(long, 0),
+      CYRUS_OPT_SWITCH },
+
+    { CYRUSOPT_LDAP_BASE,
+      CFGVAL(const char *, NULL),
+      CYRUS_OPT_STRING },
+
+    { CYRUSOPT_LDAP_HOST,
+      CFGVAL(const char *, "localhost"),
+      CYRUS_OPT_STRING },
+
+    { CYRUSOPT_LDAP_PORT,
+      CFGVAL(long, 389),
+      CYRUS_OPT_INT },
+
+    { CYRUSOPT_LDAP_FROM_ATTR,
+      CFGVAL(const char *, "mailPrimaryAddress"),
+      CYRUS_OPT_STRING },
+
+    { CYRUSOPT_LDAP_TO_ATTR,
+      CFGVAL(const char *, "uid"),
+      CYRUS_OPT_STRING },
+
+    { CYRUSOPT_LDAP_BINDDN,
+      CFGVAL(const char *, NULL),
+      CYRUS_OPT_STRING },
+
+    { CYRUSOPT_LDAP_BINDPWFILE,
+      CFGVAL(const char *, "/etc/cyrus-ldap.secret"),
+      CYRUS_OPT_STRING },
+
     { CYRUSOPT_LAST, { NULL }, CYRUS_OPT_NOTOPT }
 };
 
diff -Nur cyrus-imapd-2.4-2.4.9.orig/lib/libcyr_cfg.h cyrus-imapd-2.4-2.4.9/lib/libcyr_cfg.h
--- cyrus-imapd-2.4-2.4.9.orig/lib/libcyr_cfg.h	2011-09-08 12:07:33.607219025 +0200
+++ cyrus-imapd-2.4-2.4.9/lib/libcyr_cfg.h	2011-09-08 14:36:13.943218586 +0200
@@ -118,6 +118,22 @@
     CYRUSOPT_SKIPLIST_ALWAYS_CHECKPOINT,
     /* Lowercase uid and strip leading and trailing blanks (OFF) */
     CYRUSOPT_NORMALIZEUID,
+    /* LDAP Mapping (0) */
+    CYRUSOPT_AUTH_LDAP_GROUP_ENABLE,
+    /* LDAP Base */
+    CYRUSOPT_LDAP_BASE,
+    /* LDAP Host (localhost) */
+    CYRUSOPT_LDAP_HOST,
+    /* LDAP Port (389)*/
+    CYRUSOPT_LDAP_PORT,
+    /* LDAP from attribute (mailPrimaryAddress)*/
+    CYRUSOPT_LDAP_FROM_ATTR,
+    /* LDAP to attribute (uid) */
+    CYRUSOPT_LDAP_TO_ATTR,
+    /* LDAP binddn */
+    CYRUSOPT_LDAP_BINDDN,
+    /* LDAP bind passwd file */ 
+    CYRUSOPT_LDAP_BINDPWFILE,
 
     CYRUSOPT_LAST
     
diff -Nur cyrus-imapd-2.4-2.4.9.orig/lib/auth_unix.c cyrus-imapd-2.4-2.4.9/lib/auth_unix.c
--- cyrus-imapd-2.4-2.4.9.orig/lib/auth_unix.c	2011-10-14 13:15:51.000000000 +0200
+++ cyrus-imapd-2.4-2.4.9/lib/auth_unix.c	2011-10-14 13:09:30.000000000 +0200
@@ -48,6 +48,8 @@
 #include <grp.h>
 #include <ctype.h>
 #include <string.h>
+#include <ldap.h>
+#include <syslog.h>
 
 #include "auth.h"
 #include "libcyr_cfg.h"
@@ -242,6 +244,7 @@
     struct auth_state *newstate;
     struct passwd *pwd;
     struct group *grp;
+    const char *user;
 #if defined(HAVE_GETGROUPLIST) && defined(__GLIBC__)
     gid_t gid, *groupids = NULL;
     int ret, ngroups = 10;
@@ -262,7 +265,108 @@
     if(!libcyrus_config_getswitch(CYRUSOPT_AUTH_UNIX_GROUP_ENABLE))
 	return newstate;
 
-    pwd = getpwnam(identifier);
+    user = identifier;
+
+    if (libcyrus_config_getswitch(CYRUSOPT_AUTH_LDAP_GROUP_ENABLE)) {
+        /* map identifier with primary mail address to uid to get group memberships */
+        char ldap_base[1024];
+        char ldap_host[1024];
+        int ldap_port;
+        char ldap_from_attr[1024];
+        char ldap_to_attr[1024];
+        char ldap_bindpw[1024];
+        char ldap_uri[1024];
+        char ldap_binddn[1024];
+        char ldap_bindpwfile[1024];
+        char uresult[1024];
+        struct  timeval timeout;
+        timeout.tv_sec=3;
+        timeout.tv_usec=0;
+        FILE *fp;
+        int len;
+  
+        strcpy(ldap_base, libcyrus_config_getstring(CYRUSOPT_LDAP_BASE));
+        strcpy(ldap_host, libcyrus_config_getstring(CYRUSOPT_LDAP_HOST));
+        ldap_port=libcyrus_config_getint(CYRUSOPT_LDAP_PORT);
+        strcpy(ldap_from_attr, libcyrus_config_getstring(CYRUSOPT_LDAP_FROM_ATTR));
+        strcpy(ldap_to_attr, libcyrus_config_getstring(CYRUSOPT_LDAP_TO_ATTR));
+        strcpy(ldap_binddn, libcyrus_config_getstring(CYRUSOPT_LDAP_BINDDN));
+        strcpy(ldap_bindpwfile, libcyrus_config_getstring(CYRUSOPT_LDAP_BINDPWFILE));
+  
+        /* read password from file */
+        if ((fp = fopen(ldap_bindpwfile, "r")) != NULL) {
+            if (fgets(ldap_bindpw, 1024, fp) == NULL) {
+                len = strlen(ldap_bindpw);
+                if (ldap_bindpw[len-1] == '\n')
+                    ldap_bindpw[len-1] = '\0';
+            }
+            fclose(fp);
+        }
+  
+        LDAP *ld;
+        int msgid;
+        char filter[8192];
+        char *attrs[] = {ldap_to_attr, NULL};
+        LDAPMessage *res = NULL, *entry;
+        struct berval** values=NULL;
+        int error=0;
+        int protocol = LDAP_VERSION3;
+        int rv = 0;
+        
+        snprintf(filter, 8192, "(&(%s=%s)(%s=*))", ldap_from_attr, identifier, ldap_to_attr);
+        snprintf(ldap_uri, sizeof(ldap_uri), "ldap://%s:%d", ldap_host, ldap_port);
+  
+        if (ldap_initialize(&ld, ldap_uri) != LDAP_SUCCESS) {
+            syslog(LOG_ERR, "failed to init ldap connection on %s", ldap_uri);
+            error=1;
+            goto cleanup;
+        }
+        ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &protocol);
+        if ((rv = ldap_start_tls_s(ld, NULL, NULL)) != LDAP_SUCCESS) {
+            syslog(LOG_ERR, "start_tls failed: %s", ldap_err2string(rv));
+        }
+        if (ldap_simple_bind_s(ld, ldap_binddn, ldap_bindpw) != LDAP_SUCCESS) {
+            syslog(LOG_ERR, "ldap simple bind to %s with %s failed", ldap_host, ldap_binddn);
+            error=2;
+            goto cleanup;
+        }
+        if ((msgid = ldap_search_ext_s(ld, ldap_base, LDAP_SCOPE_SUBTREE, filter, attrs, 0, NULL, NULL, &timeout, 0, &res)) != LDAP_SUCCESS) {
+            syslog(LOG_ERR, "Failed to query LDAP server: %s", filter);
+            error=3;
+            goto cleanup;
+        }
+        if (ldap_count_entries(ld, res) != 1) {
+            syslog(LOG_ERR, "No or ambigous results found: %d" , ldap_count_entries(ld, res));
+            error=4;
+            goto cleanup;
+        }
+        if ((entry = ldap_first_entry(ld, res)) == NULL) {
+            syslog(LOG_ERR, "LDAP search returned no entries.");
+            error=5;
+            goto cleanup;
+        }
+        if ((values = ldap_get_values_len(ld, entry, ldap_to_attr)) == NULL) {
+            syslog(LOG_ERR, "LDAP search returned no values");
+            error=6;
+            goto cleanup;
+        }
+	if (ldap_count_values_len(values) != 1) {
+            syslog(LOG_ERR, "No or ambigous values found: %d", ldap_count_values_len(values));
+            error=7;
+            goto cleanup;
+        }
+        strncpy(uresult, values[0]->bv_val, 1024);
+        user = uresult;
+  
+cleanup:
+        if ( values ) ldap_value_free_len(values);
+        if ( res ) ldap_msgfree(res);
+        ldap_unbind_ext(ld, NULL, NULL);
+        if ( error > 0 )
+            return newstate;
+    }
+
+    pwd = getpwnam(user);
 
 #if defined(HAVE_GETGROUPLIST) && defined(__GLIBC__)
     gid = pwd ? pwd->pw_gid : (gid_t) -1;
@@ -273,7 +376,7 @@
 				     ngroups * sizeof(gid_t));
 
 	newstate->ngroups = ngroups; /* copy of ngroups for comparision */
-	ret = getgrouplist(identifier, gid, groupids, &ngroups);
+	ret = getgrouplist(user, gid, groupids, &ngroups);
 	/*
 	 * This is tricky. We do this as long as getgrouplist tells us to
 	 * realloc _and_ the number of groups changes. It tells us to realloc
@@ -305,7 +408,7 @@
     setgrent();
     while ((grp = getgrent())) {
 	for (mem = grp->gr_mem; *mem; mem++) {
-	    if (!strcmp(*mem, identifier)) break;
+	    if (!strcmp(*mem, user)) break;
 	}
 
 	if (*mem || (pwd && pwd->pw_gid == grp->gr_gid)) {
