* Merge LDAP code; bindings are not yet complete
[citadel.git] / citadel / ldap.c
1 /*
2  * 
3  */
4
5
6 int ldap_version = 3;
7
8 #ifdef HAVE_LDAP
9
10 #include "sysdep.h"
11 #include <errno.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <stdio.h>
15 #include <fcntl.h>
16 #include <signal.h>
17 #include <pwd.h>
18 #include <ctype.h>
19 #include <sys/types.h>
20 #include <sys/wait.h>
21 #ifdef HAVE_SYS_STAT_H
22 #include <sys/stat.h>
23 #endif
24
25 #if TIME_WITH_SYS_TIME
26 # include <sys/time.h>
27 # include <time.h>
28 #else
29 # if HAVE_SYS_TIME_H
30 #  include <sys/time.h>
31 # else
32 #  include <time.h>
33 # endif
34 #endif
35
36 #include <string.h>
37 #include <limits.h>
38 #include <libcitadel.h>
39 #include "auth.h"
40 #include "citadel.h"
41 #include "server.h"
42 #include "database.h"
43 #include "user_ops.h"
44 #include "sysdep_decls.h"
45 #include "support.h"
46 #include "room_ops.h"
47 #include "file_ops.h"
48 #include "control.h"
49 #include "msgbase.h"
50 #include "config.h"
51 #include "citserver.h"
52 #include "citadel_dirs.h"
53 #include "genstamp.h"
54 #include "threads.h"
55 #include "citadel_ldap.h"
56
57 #define LDAP_DEPRECATED 1       /* Needed to suppress misleading warnings */
58
59 #include <ldap.h>
60
61 int CtdlTryUserLDAP(char *username, char *found_dn, int found_dn_size, char *fullname, int fullname_size)
62 {
63         LDAP *ldserver = NULL;
64         int i;
65         LDAPMessage *search_result = NULL;
66         LDAPMessage *entry = NULL;
67         char searchstring[1024];
68         struct timeval tv;
69         char **values;
70         char *user_dn = NULL;
71
72         safestrncpy(fullname, username, fullname_size);
73
74         ldserver = ldap_init(CTDL_LDAP_HOST, CTDL_LDAP_PORT);
75         if (ldserver == NULL) {
76                 CtdlLogPrintf(CTDL_ALERT, "LDAP: Could not connect to %s:%d : %s\n",
77                         CTDL_LDAP_HOST, CTDL_LDAP_PORT,
78                         strerror(errno));
79                 return(errno);
80         }
81
82         ldap_set_option(ldserver, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
83
84         i = ldap_simple_bind_s(ldserver, BIND_DN, BIND_PW);
85         if (i != LDAP_SUCCESS) {
86                 CtdlLogPrintf(CTDL_ALERT, "LDAP: Cannot bind: %s (%d)\n", ldap_err2string(i), i);
87                 return(i);
88         }
89
90         tv.tv_sec = 10;
91         tv.tv_usec = 0;
92
93         sprintf(searchstring, SEARCH_STRING, username);
94
95         i = ldap_search_st(ldserver,
96                 BASE_DN,
97                 LDAP_SCOPE_SUBTREE,
98                 searchstring,
99                 NULL,   // return all attributes
100                 0,      // attributes + values
101                 &tv,    // timeout
102                 &search_result
103         );
104         if (i != LDAP_SUCCESS) {
105                 CtdlLogPrintf(CTDL_DEBUG,
106                         "Couldn't find what I was looking for: %s (%d)\n", ldap_err2string(i), i);
107                 ldap_unbind(ldserver);
108                 return(i);
109         }
110
111         if (search_result == NULL) {
112                 CtdlLogPrintf(CTDL_DEBUG, "No results were returned\n");
113                 ldap_unbind(ldserver);
114                 return(2);
115         }
116
117         /* At this point we've got at least one result from our query.  If there are multiple
118          * results, we still only look at the first one.
119          */
120         entry = ldap_first_entry(ldserver, search_result);
121         if (entry) {
122
123                 user_dn = ldap_get_dn(ldserver, entry);
124                 if (user_dn) {
125                         CtdlLogPrintf(CTDL_DEBUG, "dn = %s\n", user_dn);
126                 }
127
128                 values = ldap_get_values(ldserver, search_result, "cn");
129                 if (values) {
130                         if (values[0]) {
131                                 safestrncpy(fullname, values[0], fullname_size);
132                                 CtdlLogPrintf(CTDL_DEBUG, "cn = %s\n", values[0]);
133                         }
134                         ldap_value_free(values);
135                 }
136
137                 values = ldap_get_values(ldserver, search_result, "uidNumber");
138                 if (values) {
139                         if (values[0]) {
140                                 CtdlLogPrintf(CTDL_DEBUG, "uidNumber = %s\n", values[0]);
141                         }
142                         ldap_value_free(values);
143                 }
144
145                 values = ldap_get_values(ldserver, search_result, "objectGUID");
146                 if (values) {
147                         if (values[0]) {
148                                 CtdlLogPrintf(CTDL_DEBUG, "objectGUID = (%d characers)\n", strlen(values[0]));
149                         }
150                         ldap_value_free(values);
151                 }
152
153         }
154
155         /* free the results */
156         ldap_msgfree(search_result);
157
158         /* unbind so we can go back in as the authenticating user */
159         ldap_unbind(ldserver);
160
161         if (!user_dn) {
162                 CtdlLogPrintf(CTDL_DEBUG, "No such user was found.\n");
163                 return(4);
164         }
165
166         safestrncpy(found_dn, user_dn, found_dn_size);
167         ldap_memfree(user_dn);
168         return(0);
169 }
170
171
172 int CtdlTryPasswordLDAP(char *user_dn, char *password)
173 {
174         LDAP *ldserver = NULL;
175         int i;
176
177         ldserver = ldap_init(CTDL_LDAP_HOST, CTDL_LDAP_PORT);
178         if (ldserver) {
179                 ldap_set_option(ldserver, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
180                 i = ldap_simple_bind_s(ldserver, user_dn, password);
181                 if (i == LDAP_SUCCESS) {
182                         CtdlLogPrintf(CTDL_DEBUG, "LDAP: bind succeeded\n");
183                 }
184                 else {
185                         CtdlLogPrintf(CTDL_DEBUG, "LDAP: Cannot bind: %s (%d)\n", ldap_err2string(i), i);
186                 }
187                 ldap_unbind(ldserver);
188         }
189
190         return((i == LDAP_SUCCESS) ? 0 : 1);
191 }
192
193
194
195
196 #endif /* HAVE_LDAP */