comparison src/eldap.c @ 276:6330739388db r21-0b36

Import from CVS: tag r21-0b36
author cvs
date Mon, 13 Aug 2007 10:30:37 +0200
parents c5d627a313b1
children 90d73dddcdc4
comparison
equal deleted inserted replaced
275:a68ae4439f57 276:6330739388db
33 #include "lisp.h" 33 #include "lisp.h"
34 34
35 #include <errno.h> 35 #include <errno.h>
36 #include <lber.h> 36 #include <lber.h>
37 #include <ldap.h> 37 #include <ldap.h>
38
39 #include "eldap.h"
38 40
39 #ifdef HAVE_NS_LDAP 41 #ifdef HAVE_NS_LDAP
40 #define HAVE_LDAP_SET_OPTION 1 42 #define HAVE_LDAP_SET_OPTION 1
41 #define HAVE_LDAP_GET_ERRNO 1 43 #define HAVE_LDAP_GET_ERRNO 1
42 #else 44 #else
43 #undef HAVE_LDAP_SET_OPTION 45 #undef HAVE_LDAP_SET_OPTION
44 #undef HAVE_LDAP_GET_ERRNO 46 #undef HAVE_LDAP_GET_ERRNO
45 #endif 47 #endif
46 48
49
50
51 static int ldap_default_port;
47 static Lisp_Object Vldap_default_base; 52 static Lisp_Object Vldap_default_base;
48 static Lisp_Object Vldap_default_host; 53
49 54 /* ldap-open plist keywords */
50 /* ldap-search-internal plist keywords */ 55 static Lisp_Object Qport, Qauth, Qbinddn, Qpasswd, Qderef, Qtimelimit,
51 static Lisp_Object Qhost, Qfilter, Qattributes, Qattrsonly, Qbase, Qscope, 56 Qsizelimit;
52 Qauth, Qbinddn, Qpasswd, Qderef, Qtimelimit, Qsizelimit;
53 /* Search scope limits */ 57 /* Search scope limits */
54 static Lisp_Object Qbase, Qonelevel, Qsubtree; 58 static Lisp_Object Qbase, Qonelevel, Qsubtree;
55 /* Authentication methods */ 59 /* Authentication methods */
56 #ifdef LDAP_AUTH_KRBV41 60 #ifdef LDAP_AUTH_KRBV41
57 static Lisp_Object Qkrbv41; 61 static Lisp_Object Qkrbv41;
60 static Lisp_Object Qkrbv42; 64 static Lisp_Object Qkrbv42;
61 #endif 65 #endif
62 /* Deref policy */ 66 /* Deref policy */
63 static Lisp_Object Qnever, Qalways, Qfind; 67 static Lisp_Object Qnever, Qalways, Qfind;
64 68
65 DEFUN ("ldap-search-internal", Fldap_search_internal, 1, 1, 0, /* 69 static Lisp_Object Qldapp;
66 Perform a search on a LDAP server. 70
67 SEARCH-PLIST is a property list describing the search request. 71
72 /************************************************************************/
73 /* Utility Functions */
74 /************************************************************************/
75
76 static void
77 signal_ldap_error (LDAP *ld)
78 {
79 #if HAVE_LDAP_GET_ERRNO
80 signal_simple_error
81 ("LDAP error",
82 build_string (ldap_err2string (ldap_get_lderrno (ld, NULL, NULL))));
83 #else
84 signal_simple_error ("LDAP error",
85 build_string (ldap_err2string (ld->ld_errno)));
86 #endif
87 }
88
89
90 /************************************************************************/
91 /* The ldap Lisp object */
92 /************************************************************************/
93
94 /*
95 * Structure records pertinent information about an open LDAP connection.
96 */
97
98 struct Lisp_LDAP
99 {
100 /* lcrecord header */
101 struct lcrecord_header header;
102 /* The LDAP connection handle used by the LDAP API */
103 LDAP *ld;
104 /* Name of the host we connected to */
105 Lisp_Object host;
106 /* Status of the LDAP connection.
107 This is a symbol: open or closed */
108 Lisp_Object status_symbol;
109 };
110
111
112
113 static Lisp_Object
114 mark_ldap (Lisp_Object obj, void (*markobj) (Lisp_Object))
115 {
116 struct Lisp_LDAP *ldap = XLDAP (obj);
117 ((markobj) (ldap->host));
118 return ldap->status_symbol;
119 }
120
121 static void
122 print_ldap (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
123 {
124 char buf[16];
125
126 struct Lisp_LDAP *ldap = XLDAP (obj);
127
128 if (print_readably)
129 error ("printing unreadable object #<ldap %s>",
130 XSTRING_DATA (ldap->host));
131
132 if (!escapeflag)
133 {
134 print_internal (ldap->host, printcharfun, 0);
135 }
136 else
137 {
138 write_c_string (GETTEXT ("#<ldap "), printcharfun);
139 print_internal (ldap->host, printcharfun, 1);
140 write_c_string (" state:",printcharfun);
141 print_internal (ldap->status_symbol, printcharfun, 1);
142 sprintf (buf, " 0x%x>", ldap);
143 write_c_string (buf, printcharfun);
144 }
145 }
146
147 static struct Lisp_LDAP *
148 allocate_ldap (void)
149 {
150 struct Lisp_LDAP *ldap =
151 alloc_lcrecord_type (struct Lisp_LDAP, lrecord_ldap);
152
153 ldap->ld = (LDAP *) NULL;
154 ldap->host = Qnil;
155 ldap->status_symbol = Qnil;
156 return ldap;
157 }
158
159 DEFINE_LRECORD_IMPLEMENTATION ("ldap", ldap,
160 mark_ldap, print_ldap, NULL,
161 NULL, NULL, struct Lisp_LDAP);
162
163
164
165
166 /************************************************************************/
167 /* Basic ldap accessors */
168 /************************************************************************/
169
170 DEFUN ("ldapp", Fldapp, 1, 1, 0, /*
171 Return t if OBJECT is a LDAP connection.
172 */
173 (object))
174 {
175 return LDAPP (object) ? Qt : Qnil;
176 }
177
178
179 DEFUN ("ldap-host", Fldap_host, 1, 1, 0, /*
180 Return the server host of the connection LDAP, as a string.
181 */
182 (ldap))
183 {
184 CHECK_LDAP (ldap);
185 return (XLDAP (ldap))->host;
186 }
187
188
189
190 DEFUN ("ldap-status", Fldap_status, 1, 1, 0, /*
191 Return the status of the connection LDAP.
192 This is a symbol, one of these:
193
194 open -- for a LDAP connection that is open.
195 closed -- for a LDAP connection that is closed.
196 */
197 (ldap))
198 {
199 CHECK_LDAP (ldap);
200 return (XLDAP (ldap))->status_symbol;
201 }
202
203
204
205 /************************************************************************/
206 /* Opening/Closing a LDAP connection */
207 /************************************************************************/
208
209
210 DEFUN ("ldap-open", Fldap_open, 1, 2, 0, /*
211 Open a LDAP connection to HOST.
212 PLIST is a plist containing additional parameters for the connection.
68 Valid keys in that list are: 213 Valid keys in that list are:
69 `host' is a string naming one or more (blank separated) LDAP servers to 214 `port' the TCP port to use for the connection if different from
70 to try to connect to. Each host name may optionally be of the form host:port. 215 `ldap-default-port'.
71 `filter' is a filter string for the search as described in RFC 1558
72 `attributes' is a list of strings indicating which attributes to retrieve
73 for each matching entry. If nil return all available attributes.
74 `attrsonly' if non-nil indicates that only the attributes are retrieved, not
75 the associated values.
76 `base' is the base for the search as described in RFC 1779.
77 `scope' is one of the three symbols `subtree', `base' or `onelevel'.
78 `auth' is the authentication method to use, possible values depend on 216 `auth' is the authentication method to use, possible values depend on
79 the LDAP library XEmacs was compiled with: `simple', `krbv41' and `krbv42'. 217 the LDAP library XEmacs was compiled with: `simple', `krbv41' and `krbv42'.
80 `binddn' is the distinguished name of the user to bind as (in RFC 1779 syntax). 218 `binddn' is the distinguished name of the user to bind as (in RFC 1779 syntax).
81 `passwd' is the password to use for simple authentication. 219 `passwd' is the password to use for simple authentication.
82 `deref' is one of the symbols `never', `always', `search' or `find'. 220 `deref' is one of the symbols `never', `always', `search' or `find'.
83 `timelimit' is the timeout limit for the connection in seconds. 221 `timelimit' is the timeout limit for the connection in seconds.
84 `sizelimit' is the maximum number of matches to return. 222 `sizelimit' is the maximum number of matches to return.
85 The function returns a list of matching entries. Each entry is itself
86 an alist of attribute/values.
87 */ 223 */
88 (search_plist)) 224 (host, plist))
89 { 225 {
90 /* This function calls lisp */ 226 /* This function can call lisp */
91 227
92 /* Vars for query */ 228 struct Lisp_LDAP *lisp_ldap;
93 LDAP *ld; 229 LDAP *ld;
94 LDAPMessage *res, *e; 230 int ldap_port = 0;
95 BerElement *ptr;
96 char *a;
97 int i, rc, err;
98
99 char *ldap_host = NULL;
100 char *ldap_filter = NULL;
101 char **ldap_attributes = NULL;
102 int ldap_attrsonly = 0;
103 char *ldap_base = NULL;
104 int ldap_scope = LDAP_SCOPE_SUBTREE;
105 int ldap_auth = LDAP_AUTH_SIMPLE; 231 int ldap_auth = LDAP_AUTH_SIMPLE;
106 char *ldap_binddn = NULL; 232 char *ldap_binddn = NULL;
107 char *ldap_passwd = NULL; 233 char *ldap_passwd = NULL;
108 int ldap_deref = LDAP_DEREF_NEVER; 234 int ldap_deref = LDAP_DEREF_NEVER;
109 int ldap_timelimit = 0; 235 int ldap_timelimit = 0;
110 int ldap_sizelimit = 0; 236 int ldap_sizelimit = 0;
111 237 int err;
112 char **vals = NULL; 238
113 int matches; 239 Lisp_Object ldap, list, keyword, value;
114 240 struct gcpro gcpro1;
115 Lisp_Object list, entry, result, keyword, value; 241
116 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 242 ldap = Qnil;
117 243 GCPRO1 (ldap);
118 list = entry = result = keyword = value = Qnil; 244
119 GCPRO5 (list, entry, result, keyword, value); 245 CHECK_STRING (host);
120 246
121 247 EXTERNAL_PROPERTY_LIST_LOOP(list, keyword, value, plist)
122 EXTERNAL_PROPERTY_LIST_LOOP(list, keyword, value, search_plist) 248 {
123 { 249 /* TCP Port */
124 /* Host */ 250 if (EQ (keyword, Qport))
125 if (EQ (keyword, Qhost)) 251 {
126 { 252 CHECK_INT (value);
127 CHECK_STRING (value); 253 ldap_port = XINT (value);
128 ldap_host = alloca (XSTRING_LENGTH (value) + 1);
129 strcpy (ldap_host, (char *)XSTRING_DATA (value));
130 }
131 /* Filter */
132 else if (EQ (keyword, Qfilter))
133 {
134 CHECK_STRING (value);
135 ldap_filter = alloca (XSTRING_LENGTH (value) + 1);
136 strcpy (ldap_filter, (char *)XSTRING_DATA (value));
137 }
138 /* Attributes */
139 else if (EQ (keyword, Qattributes))
140 {
141 if (! NILP (value))
142 {
143 Lisp_Object attr_left = value;
144 struct gcpro ngcpro1;
145
146 NGCPRO1 (attr_left);
147 CHECK_CONS (value);
148
149 ldap_attributes = alloca ((XINT (Flength (value)) + 1)*sizeof (char *));
150
151 for (i=0; !NILP (attr_left); i++) {
152 CHECK_STRING (XCAR (attr_left));
153 ldap_attributes[i] = alloca (XSTRING_LENGTH (XCAR (attr_left)) + 1);
154 strcpy(ldap_attributes[i],
155 (char *)(XSTRING_DATA( XCAR (attr_left))));
156 attr_left = XCDR (attr_left);
157 }
158 ldap_attributes[i] = NULL;
159 NUNGCPRO;
160 }
161 }
162 /* Attributes Only */
163 else if (EQ (keyword, Qattrsonly))
164 {
165 CHECK_SYMBOL (value);
166 ldap_attrsonly = NILP (value) ? 0 : 1;
167 }
168 /* Base */
169 else if (EQ (keyword, Qbase))
170 {
171 if (!NILP (value))
172 {
173 CHECK_STRING (value);
174 ldap_base = alloca (XSTRING_LENGTH (value) + 1);
175 strcpy (ldap_base, (char *)XSTRING_DATA (value));
176 }
177 }
178 /* Scope */
179 else if (EQ (keyword, Qscope))
180 {
181 CHECK_SYMBOL (value);
182
183 if (EQ (value, Qbase))
184 ldap_scope = LDAP_SCOPE_BASE;
185 else if (EQ (value, Qonelevel))
186 ldap_scope = LDAP_SCOPE_ONELEVEL;
187 else if (EQ (value, Qsubtree))
188 ldap_scope = LDAP_SCOPE_SUBTREE;
189 else
190 signal_simple_error ("Invalid scope", value);
191 } 254 }
192 /* Authentication method */ 255 /* Authentication method */
193 else if (EQ (keyword, Qauth)) 256 if (EQ (keyword, Qauth))
194 { 257 {
195 CHECK_SYMBOL (value); 258 CHECK_SYMBOL (value);
196 259
197 if (EQ (value, Qsimple)) 260 if (EQ (value, Qsimple))
198 ldap_auth = LDAP_AUTH_SIMPLE; 261 ldap_auth = LDAP_AUTH_SIMPLE;
208 signal_simple_error ("Invalid authentication method", value); 271 signal_simple_error ("Invalid authentication method", value);
209 } 272 }
210 /* Bind DN */ 273 /* Bind DN */
211 else if (EQ (keyword, Qbinddn)) 274 else if (EQ (keyword, Qbinddn))
212 { 275 {
213 if (!NILP (value)) 276 CHECK_STRING (value);
214 { 277 ldap_binddn = alloca (XSTRING_LENGTH (value) + 1);
215 CHECK_STRING (value); 278 strcpy (ldap_binddn, (char *)XSTRING_DATA (value));
216 ldap_binddn = alloca (XSTRING_LENGTH (value) + 1);
217 strcpy (ldap_binddn, (char *)XSTRING_DATA (value));
218 }
219 } 279 }
220 /* Password */ 280 /* Password */
221 else if (EQ (keyword, Qpasswd)) 281 else if (EQ (keyword, Qpasswd))
222 { 282 {
223 if (!NILP (value)) 283 CHECK_STRING (value);
224 { 284 ldap_passwd = alloca (XSTRING_LENGTH (value) + 1);
225 CHECK_STRING (value); 285 strcpy (ldap_passwd, (char *)XSTRING_DATA (value));
226 ldap_passwd = alloca (XSTRING_LENGTH (value) + 1);
227 strcpy (ldap_passwd, (char *)XSTRING_DATA (value));
228 }
229 } 286 }
230 /* Deref */ 287 /* Deref */
231 else if (EQ (keyword, Qderef)) 288 else if (EQ (keyword, Qderef))
232 { 289 {
233 CHECK_SYMBOL (value); 290 CHECK_SYMBOL (value);
243 signal_simple_error ("Invalid deref value", value); 300 signal_simple_error ("Invalid deref value", value);
244 } 301 }
245 /* Timelimit */ 302 /* Timelimit */
246 else if (EQ (keyword, Qtimelimit)) 303 else if (EQ (keyword, Qtimelimit))
247 { 304 {
248 if (!NILP (value)) 305 CHECK_INT (value);
249 { 306 ldap_timelimit = XINT (value);
250 CHECK_INT (value);
251 ldap_timelimit = XINT (value);
252 }
253 } 307 }
254 /* Sizelimit */ 308 /* Sizelimit */
255 else if (EQ (keyword, Qsizelimit)) 309 else if (EQ (keyword, Qsizelimit))
256 { 310 {
257 if (!NILP (value)) 311 CHECK_INT (value);
258 { 312 ldap_sizelimit = XINT (value);
259 CHECK_INT (value); 313 }
260 ldap_sizelimit = XINT (value); 314 }
261 } 315
262 } 316 if (ldap_port == 0)
263 } 317 {
264 318 ldap_port = ldap_default_port;
265 /* Use ldap-default-base if no default base was given */ 319 }
266 if (ldap_base == NULL && !NILP (Vldap_default_base))
267 {
268 CHECK_STRING (Vldap_default_base);
269 ldap_base = alloca (XSTRING_LENGTH (Vldap_default_base) + 1);
270 strcpy (ldap_base, (char *)XSTRING_DATA (Vldap_default_base));
271 }
272
273 /* Use ldap-default-host if no host was given */
274 if (ldap_host == NULL && !NILP (Vldap_default_host))
275 {
276 CHECK_STRING (Vldap_default_host);
277 ldap_host = alloca (XSTRING_LENGTH (Vldap_default_host) + 1);
278 strcpy (ldap_host, (char *)XSTRING_DATA (Vldap_default_host));
279 }
280
281 if (ldap_filter == NULL)
282 error ("Empty search filter");
283
284 /* Garbage collect before connecting (if using UMich lib).
285 This is ugly, I know, but without this, the UMich LDAP library 3.3
286 frequently reports "Can't contact LDAP server". I really need to
287 check what happens inside that lib. Anyway this should be harmless to
288 XEmacs and makes things work. */
289 #if defined (HAVE_UMICH_LDAP)
290 garbage_collect_1 ();
291 #endif
292 320
293 /* Connect to the server and bind */ 321 /* Connect to the server and bind */
294 message ("Connecting to %s...", ldap_host); 322 ld = ldap_open ((char *)XSTRING_DATA (host), ldap_port);
295 if ( (ld = ldap_open (ldap_host, LDAP_PORT)) == NULL ) 323 if (ld == NULL )
296 signal_simple_error_2 ("Failed connecting to host", 324 signal_simple_error_2 ("Failed connecting to host",
297 build_string (ldap_host), 325 host,
298 lisp_strerror (errno)); 326 lisp_strerror (errno));
327
299 328
300 #if HAVE_LDAP_SET_OPTION 329 #if HAVE_LDAP_SET_OPTION
301 if (ldap_set_option (ld, LDAP_OPT_DEREF, (void *)&ldap_deref) != LDAP_SUCCESS) 330 if (ldap_set_option (ld, LDAP_OPT_DEREF, (void *)&ldap_deref) != LDAP_SUCCESS)
302 error ("Failed to set deref option"); 331 signal_ldap_error (ld);
303 if (ldap_set_option (ld, LDAP_OPT_TIMELIMIT, (void *)&ldap_timelimit) != LDAP_SUCCESS) 332 if (ldap_set_option (ld, LDAP_OPT_TIMELIMIT,
304 error ("Failed to set timelimit option"); 333 (void *)&ldap_timelimit) != LDAP_SUCCESS)
305 if (ldap_set_option (ld, LDAP_OPT_SIZELIMIT, (void *)&ldap_sizelimit) != LDAP_SUCCESS) 334 signal_ldap_error (ld);
306 error ("Failed to set sizelimit option"); 335 if (ldap_set_option (ld, LDAP_OPT_SIZELIMIT,
336 (void *)&ldap_sizelimit) != LDAP_SUCCESS)
337 signal_ldap_error (ld);
307 if (ldap_set_option (ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON) != LDAP_SUCCESS) 338 if (ldap_set_option (ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON) != LDAP_SUCCESS)
308 error ("Failed to set referral option"); 339 signal_ldap_error (ld);
309 #else /* HAVE_LDAP_SET_OPTION */ 340 #else /* HAVE_LDAP_SET_OPTION */
310 ld->ld_deref = ldap_deref; 341 ld->ld_deref = ldap_deref;
311 ld->ld_timelimit = ldap_timelimit; 342 ld->ld_timelimit = ldap_timelimit;
312 ld->ld_sizelimit = ldap_sizelimit; 343 ld->ld_sizelimit = ldap_sizelimit;
313 #ifdef LDAP_REFERRALS 344 #ifdef LDAP_REFERRALS
315 #else /* LDAP_REFERRALS */ 346 #else /* LDAP_REFERRALS */
316 ld->ld_options = 0; 347 ld->ld_options = 0;
317 #endif /* LDAP_REFERRALS */ 348 #endif /* LDAP_REFERRALS */
318 #endif /* HAVE_LDAP_SET_OPTION */ 349 #endif /* HAVE_LDAP_SET_OPTION */
319 350
320 message ("Binding to %s...", ldap_host); 351 /* ldap_bind_s calls select and may be wedged by spurious signals */
321 if ( (err = (ldap_bind_s (ld, ldap_binddn, ldap_passwd, ldap_auth ))) != LDAP_SUCCESS ) 352 slow_down_interrupts ();
353 err = ldap_bind_s (ld, ldap_binddn, ldap_passwd, ldap_auth);
354 speed_up_interrupts ();
355 if (err != LDAP_SUCCESS)
322 signal_simple_error ("Failed binding to the server", 356 signal_simple_error ("Failed binding to the server",
323 build_string (ldap_err2string (err))); 357 build_string (ldap_err2string (err)));
324 358
359 lisp_ldap = allocate_ldap ();
360 lisp_ldap->ld = ld;
361 lisp_ldap->host = host;
362 lisp_ldap->status_symbol = Qopen;
363 XSETLDAP (ldap,lisp_ldap);
364
365 UNGCPRO;
366 return ldap;
367 }
368
369
370
371 DEFUN ("ldap-close", Fldap_close, 1, 1, 0, /*
372 Close an LDAP connection.
373 Return t if the connection was actually closed or nil if
374 it was already closed before the call
375 */
376 (ldap))
377 {
378 CHECK_LDAP (ldap);
379 if ( EQ ((XLDAP (ldap))->status_symbol, Qopen) )
380 {
381 ldap_unbind ((XLDAP (ldap))->ld);
382 (XLDAP (ldap))->status_symbol = Qclosed;
383 return Qt;
384 }
385 return Qnil;
386 }
387
388
389
390 /************************************************************************/
391 /* Working on a LDAP connection */
392 /************************************************************************/
393
394 DEFUN ("ldap-search-internal", Fldap_search_internal, 2, 6, 0, /*
395 Perform a search on an open LDAP connection.
396 LDAP is an LDAP connection object created with `ldap-open'.
397 FILTER is a filter string for the search as described in RFC 1558
398 BASE is the distinguished name at which to start the search
399 SCOPE is an integer or a symbol indicating the scope of the search
400 Possible values are `ldap-scope-base', `ldap-scope-onelevel' or
401 `ldap-scope-subtree'
402 ATTRS is a list of strings indicating which attributes to retrieve
403 for each matching entry. If nil return all available attributes.
404 If ATTRSONLY is non-nil then only the attributes are retrieved, not
405 the associated values
406 The function returns a list of matching entries. Each entry is itself
407 an alist of attribute/values.
408 */
409 (ldap, filter, base, scope, attrs, attrsonly))
410 {
411 /* This function can call lisp */
412
413 /* Vars for query */
414 LDAP *ld;
415 LDAPMessage *res, *e;
416 BerElement *ptr;
417 char *a;
418 int i, rc, err;
419
420 char **vals = NULL;
421 int matches;
422
423 int ldap_scope = LDAP_SCOPE_SUBTREE;
424 char **ldap_attributes = NULL;
425
426 Lisp_Object list, entry, result;
427 struct gcpro gcpro1, gcpro2, gcpro3;
428
429 list = entry = result = Qnil;
430 GCPRO3(list, entry, result);
431
432 /* Do all the parameter checking */
433 CHECK_LIVE_LDAP (ldap);
434 ld = (XLDAP (ldap))->ld;
435
436 /* Filter */
437 CHECK_STRING (filter);
438
439 /* Search base */
440 if (NILP (base))
441 {
442 base = Vldap_default_base;
443 }
444 if (!NILP (base))
445 {
446 CHECK_STRING (Vldap_default_base);
447 }
448
449 /* Search scope */
450 if (!NILP (scope))
451 {
452 CHECK_SYMBOL (scope);
453 if (EQ (scope, Qbase))
454 ldap_scope = LDAP_SCOPE_BASE;
455 else if (EQ (scope, Qonelevel))
456 ldap_scope = LDAP_SCOPE_ONELEVEL;
457 else if (EQ (scope, Qsubtree))
458 ldap_scope = LDAP_SCOPE_SUBTREE;
459 else
460 signal_simple_error ("Invalid scope", scope);
461 }
462
463 /* Attributes to search */
464 if (!NILP (attrs))
465 {
466 Lisp_Object attr_left = attrs;
467 struct gcpro ngcpro1;
468
469 NGCPRO1 (attr_left);
470 CHECK_CONS (attrs);
471
472 ldap_attributes = alloca ((XINT (Flength (attrs)) + 1)*sizeof (char *));
473
474 for (i=0; !NILP (attr_left); i++) {
475 CHECK_STRING (XCAR (attr_left));
476 ldap_attributes[i] = alloca (XSTRING_LENGTH (XCAR (attr_left)) + 1);
477 strcpy(ldap_attributes[i],
478 (char *)(XSTRING_DATA( XCAR (attr_left))));
479 attr_left = XCDR (attr_left);
480 }
481 ldap_attributes[i] = NULL;
482 NUNGCPRO;
483 }
484
485 /* Attributes only ? */
486 CHECK_SYMBOL (attrsonly);
487
488
325 /* Perform the search */ 489 /* Perform the search */
326 message ("Searching with LDAP on %s...", ldap_host); 490 if (ldap_search (ld,
327 if ( ldap_search (ld, ldap_base, ldap_scope, ldap_filter, 491 NILP (base) ? "" : (char *) XSTRING_DATA (base),
328 ldap_attributes, ldap_attrsonly) == -1) 492 ldap_scope,
329 { 493 NILP (filter) ? "" : (char *) XSTRING_DATA (filter),
330 ldap_unbind (ld); 494 ldap_attributes,
331 #if HAVE_LDAP_GET_ERRNO 495 NILP (attrsonly) ? 0 : 1)
332 signal_simple_error ("Error during LDAP search", 496 == -1)
333 build_string (ldap_err2string (ldap_get_lderrno (ld, NULL, NULL)))); 497 {
334 #else 498 signal_ldap_error (ld);
335 signal_simple_error ("Error during LDAP search",
336 build_string (ldap_err2string (ld->ld_errno)));
337 #endif
338 } 499 }
339 500
340 /* Build the results list */ 501 /* Build the results list */
341 matches = 0; 502 matches = 0;
342 503
343 while ( (rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &res)) 504 /* ldap_result calls select() and can get wedged by EINTR signals */
344 == LDAP_RES_SEARCH_ENTRY ) 505 slow_down_interrupts ();
506 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &res);
507 speed_up_interrupts ();
508 while ( rc == LDAP_RES_SEARCH_ENTRY )
345 { 509 {
346 matches ++; 510 matches ++;
347 e = ldap_first_entry (ld, res); 511 e = ldap_first_entry (ld, res);
348 message ("Parsing results... %d", matches); 512 message ("Parsing results... %d", matches);
349 entry = Qnil; 513 entry = Qnil;
366 ldap_value_free (vals); 530 ldap_value_free (vals);
367 } 531 }
368 result = Fcons (Fnreverse (entry), 532 result = Fcons (Fnreverse (entry),
369 result); 533 result);
370 ldap_msgfree (res); 534 ldap_msgfree (res);
535
536 slow_down_interrupts ();
537 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &res);
538 speed_up_interrupts ();
371 } 539 }
372 540
373 if (rc == -1) 541 if (rc == -1)
374 { 542 {
375 #if HAVE_LDAP_GET_ERRNO 543 signal_ldap_error (ld);
376 signal_simple_error ("Error retrieving result",
377 build_string (ldap_err2string (ldap_get_lderrno (ld, NULL, NULL))));
378 #else
379 signal_simple_error ("Error retrieving result",
380 build_string (ldap_err2string (ld->ld_errno)));
381 #endif
382 } 544 }
383 545
384 if ((rc = ldap_result2error (ld, res, 0)) != LDAP_SUCCESS) 546 if ((rc = ldap_result2error (ld, res, 0)) != LDAP_SUCCESS)
385 { 547 {
386 #if HAVE_LDAP_GET_ERRNO 548 signal_ldap_error (ld);
387 signal_simple_error ("Error on result",
388 build_string (ldap_err2string (ldap_get_lderrno (ld, NULL, NULL))));
389 #else
390 signal_simple_error ("Error on result",
391 build_string (ldap_err2string (ld->ld_errno)));
392 #endif
393 } 549 }
394 550
395 ldap_msgfree (res); 551 ldap_msgfree (res);
396 ldap_unbind (ld);
397 message ("Done."); 552 message ("Done.");
398 553
399 result = Fnreverse (result); 554 result = Fnreverse (result);
400 clear_message (); 555 clear_message ();
401 556
405 560
406 561
407 void 562 void
408 syms_of_eldap (void) 563 syms_of_eldap (void)
409 { 564 {
410 DEFSUBR(Fldap_search_internal); 565 defsymbol (&Qldapp, "ldapp");
411 566
412 defsymbol (&Qhost, "host"); 567 DEFSUBR (Fldapp);
413 defsymbol (&Qfilter, "filter"); 568 DEFSUBR (Fldap_host);
414 defsymbol (&Qattributes, "attributes"); 569 DEFSUBR (Fldap_status);
415 defsymbol (&Qattrsonly, "attrsonly"); 570 DEFSUBR (Fldap_open);
416 defsymbol (&Qbase, "base"); 571 DEFSUBR (Fldap_close);
417 defsymbol (&Qscope, "scope"); 572 DEFSUBR (Fldap_search_internal);
418 defsymbol (&Qauth, "auth");
419 defsymbol (&Qbinddn, "binddn");
420 defsymbol (&Qpasswd, "passwd");
421 defsymbol (&Qderef, "deref");
422 defsymbol (&Qtimelimit, "timelimit");
423 defsymbol (&Qsizelimit, "sizelimit");
424 defsymbol (&Qonelevel, "onelevel");
425 defsymbol (&Qsubtree, "subtree");
426 #ifdef LDAP_AUTH_KRBV41
427 defsymbol (&Qkrbv41, "krbv41");
428 #endif
429 #ifdef LDAP_AUTH_KRBV42
430 defsymbol (&Qkrbv42, "krbv42");
431 #endif
432 defsymbol (&Qnever, "never");
433 defsymbol (&Qalways, "always");
434 defsymbol (&Qfind, "find");
435 } 573 }
436 574
437 void 575 void
438 vars_of_eldap (void) 576 vars_of_eldap (void)
439 { 577 {
440 Fprovide (intern ("ldap-internal")); 578 Fprovide (intern ("ldap"));
441 579
442 DEFVAR_LISP ("ldap-default-host", &Vldap_default_host /* 580 ldap_default_port = LDAP_PORT;
443 Default LDAP host. 581 Vldap_default_base = Qnil;
582
583 DEFVAR_INT ("ldap-default-port", &ldap_default_port /*
584 Default TCP port for LDAP connections.
585 Initialized from the LDAP library. Default value is 389.
444 */ ); 586 */ );
445 587
446 DEFVAR_LISP ("ldap-default-base", &Vldap_default_base /* 588 DEFVAR_LISP ("ldap-default-base", &Vldap_default_base /*
447 Default base for LDAP searches. 589 Default base for LDAP searches.
448 This is a string using the syntax of RFC 1779. 590 This is a string using the syntax of RFC 1779.
449 For instance, "o=ACME, c=US" limits the search to the 591 For instance, "o=ACME, c=US" limits the search to the
450 Acme organization in the United States. 592 Acme organization in the United States.
451 */ ); 593 */ );
452 594
453 Vldap_default_host = Qnil; 595 }
454 Vldap_default_base = Qnil; 596
455 } 597