summaryrefslogtreecommitdiff
path: root/imapd/kolab-ldap.patch
blob: 4f19fed5d984629fd6fd92e3979ea96ec670e133 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
diff -urp ../cyrus-imapd-2.2.8.orig/configure ./configure
--- ../cyrus-imapd-2.2.8.orig/configure	2004-07-29 18:22:18.000000000 +0200
+++ ./configure	2005-01-10 12:56:16.000000000 +0100
@@ -14422,7 +14422,7 @@ for flag in ${ldflags} ${default_ldflags
 done
 
 IMAP_COM_ERR_LIBS="${COM_ERR_LIBS}"
-IMAP_LIBS="${LIB_SASL} ${LIBS}"
+IMAP_LIBS="${LIB_SASL} -lldap -llber ${LIBS}"
 
 
 
diff -urp ../cyrus-imapd-2.2.8.orig/imap/global.c ./imap/global.c
--- ../cyrus-imapd-2.2.8.orig/imap/global.c	2004-05-22 05:45:49.000000000 +0200
+++ ./imap/global.c	2005-01-10 13:40:19.000000000 +0100
@@ -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
@@ -349,6 +352,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 &&
@@ -367,6 +382,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 */
@@ -379,7 +435,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;
Kun i ./imap: global.c~
diff -urp ../cyrus-imapd-2.2.8.orig/lib/imapoptions ./lib/imapoptions
--- ../cyrus-imapd-2.2.8.orig/lib/imapoptions	2004-07-21 21:07:45.000000000 +0200
+++ ./lib/imapoptions	2005-01-10 12:56:16.000000000 +0100
@@ -839,7 +839,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 -urp ../cyrus-imapd-2.2.8.orig/lib/imapopts.c ./lib/imapopts.c
--- ../cyrus-imapd-2.2.8.orig/lib/imapopts.c	2004-07-29 18:22:18.000000000 +0200
+++ ./lib/imapopts.c	2005-01-10 12:56:16.000000000 +0100
@@ -186,7 +186,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 -urp ../cyrus-imapd-2.2.8.orig/lib/imapopts.h ./lib/imapopts.h
--- ../cyrus-imapd-2.2.8.orig/lib/imapopts.h	2004-07-29 18:22:18.000000000 +0200
+++ ./lib/imapopts.h	2005-01-10 12:56:16.000000000 +0100
@@ -188,6 +188,7 @@ enum enum_value {
 
   IMAP_ENUM_VIRTDOMAINS_ON,
   IMAP_ENUM_VIRTDOMAINS_USERID,
+  IMAP_ENUM_VIRTDOMAINS_LDAP,
   IMAP_ENUM_VIRTDOMAINS_OFF = 0
 
 };