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