Mercurial > hg > xemacs-beta
comparison src/eldap.c @ 361:7347b34c275b r21-1-10
Import from CVS: tag r21-1-10
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:58:40 +0200 |
parents | 03446687b7cc |
children | cc15677e0335 |
comparison
equal
deleted
inserted
replaced
360:0f00b38cfccb | 361:7347b34c275b |
---|---|
24 | 24 |
25 /* This file provides lisp primitives for access to an LDAP library | 25 /* This file provides lisp primitives for access to an LDAP library |
26 conforming to the API defined in RFC 1823. | 26 conforming to the API defined in RFC 1823. |
27 It has been tested with: | 27 It has been tested with: |
28 - UMich LDAP 3.3 (http://www.umich.edu/~dirsvcs/ldap/) | 28 - UMich LDAP 3.3 (http://www.umich.edu/~dirsvcs/ldap/) |
29 - OpenLDAP 1.0.3 (http://www.openldap.org/) | 29 - OpenLDAP 1.2 (http://www.openldap.org/) |
30 - Netscape's LDAP SDK 1.0 (http://developer.netscape.com) */ | 30 - Netscape's LDAP SDK (http://developer.netscape.com/) */ |
31 | 31 |
32 | 32 |
33 #include <config.h> | 33 #include <config.h> |
34 #include "lisp.h" | 34 #include "lisp.h" |
35 #include "opaque.h" | 35 #include "opaque.h" |
37 #include "buffer.h" | 37 #include "buffer.h" |
38 | 38 |
39 #include <errno.h> | 39 #include <errno.h> |
40 | 40 |
41 #include "eldap.h" | 41 #include "eldap.h" |
42 | |
43 #ifdef HAVE_NS_LDAP | |
44 # define HAVE_LDAP_SET_OPTION 1 | |
45 # define HAVE_LDAP_GET_ERRNO 1 | |
46 #else | |
47 # undef HAVE_LDAP_SET_OPTION | |
48 # undef HAVE_LDAP_GET_ERRNO | |
49 #endif | |
50 | 42 |
51 static int ldap_default_port; | 43 static int ldap_default_port; |
52 static Lisp_Object Vldap_default_base; | 44 static Lisp_Object Vldap_default_base; |
53 | 45 |
54 /* Needed by the lrecord definition */ | 46 /* Needed by the lrecord definition */ |
67 /************************************************************************/ | 59 /************************************************************************/ |
68 /* Utility Functions */ | 60 /* Utility Functions */ |
69 /************************************************************************/ | 61 /************************************************************************/ |
70 | 62 |
71 static void | 63 static void |
72 signal_ldap_error (LDAP *ld) | 64 signal_ldap_error (LDAP *ld, LDAPMessage *res, int ldap_err) |
73 { | 65 { |
74 #ifdef HAVE_LDAP_GET_ERRNO | 66 if (ldap_err <= 0) |
75 signal_simple_error | 67 { |
76 ("LDAP error", | 68 #if defined HAVE_LDAP_PARSE_RESULT |
77 build_string (ldap_err2string (ldap_get_lderrno (ld, NULL, NULL)))); | 69 int err; |
70 ldap_err = ldap_parse_result (ld, res, | |
71 &err, | |
72 NULL, NULL, NULL, NULL, 0); | |
73 if (ldap_err == LDAP_SUCCESS) | |
74 ldap_err = err; | |
75 #elif defined HAVE_LDAP_GET_LDERRNO | |
76 ldap_err = ldap_get_lderrno (ld, NULL, NULL); | |
77 #elif defined HAVE_LDAP_RESULT2ERROR | |
78 ldap_err = ldap_result2error (ld, res, 0); | |
78 #else | 79 #else |
80 ldap_err = ld->ld_errno; | |
81 #endif | |
82 } | |
79 signal_simple_error ("LDAP error", | 83 signal_simple_error ("LDAP error", |
80 build_string (ldap_err2string (ld->ld_errno))); | 84 build_string (ldap_err2string (ldap_err))); |
81 #endif | |
82 } | 85 } |
83 | 86 |
84 | 87 |
85 /************************************************************************/ | 88 /************************************************************************/ |
86 /* ldap lrecord basic functions */ | 89 /* ldap lrecord basic functions */ |
111 error ("printing unreadable object #<ldap %s>", | 114 error ("printing unreadable object #<ldap %s>", |
112 XSTRING_DATA (ldap->host)); | 115 XSTRING_DATA (ldap->host)); |
113 | 116 |
114 write_c_string ("#<ldap ", printcharfun); | 117 write_c_string ("#<ldap ", printcharfun); |
115 print_internal (ldap->host, printcharfun, 1); | 118 print_internal (ldap->host, printcharfun, 1); |
116 if (!ldap->livep) | 119 if (!ldap->ld) |
117 write_c_string ("(dead) ",printcharfun); | 120 write_c_string ("(dead) ",printcharfun); |
118 sprintf (buf, " 0x%x>", (unsigned int)ldap); | 121 sprintf (buf, " 0x%x>", (unsigned int)ldap); |
119 write_c_string (buf, printcharfun); | 122 write_c_string (buf, printcharfun); |
120 } | 123 } |
121 | 124 |
125 struct Lisp_LDAP *ldap = | 128 struct Lisp_LDAP *ldap = |
126 alloc_lcrecord_type (struct Lisp_LDAP, lrecord_ldap); | 129 alloc_lcrecord_type (struct Lisp_LDAP, lrecord_ldap); |
127 | 130 |
128 ldap->ld = NULL; | 131 ldap->ld = NULL; |
129 ldap->host = Qnil; | 132 ldap->host = Qnil; |
130 ldap->livep = 0; | |
131 return ldap; | 133 return ldap; |
132 } | 134 } |
133 | 135 |
134 static void | 136 static void |
135 finalize_ldap (void *header, int for_disksave) | 137 finalize_ldap (void *header, int for_disksave) |
138 | 140 |
139 if (for_disksave) | 141 if (for_disksave) |
140 signal_simple_error ("Can't dump an emacs containing LDAP objects", | 142 signal_simple_error ("Can't dump an emacs containing LDAP objects", |
141 make_ldap (ldap)); | 143 make_ldap (ldap)); |
142 | 144 |
143 if (ldap->livep) | 145 if (ldap->ld) |
144 ldap_unbind (ldap->ld); | 146 ldap_unbind (ldap->ld); |
147 ldap->ld = NULL; | |
145 } | 148 } |
146 | 149 |
147 DEFINE_LRECORD_IMPLEMENTATION ("ldap", ldap, | 150 DEFINE_LRECORD_IMPLEMENTATION ("ldap", ldap, |
148 mark_ldap, print_ldap, finalize_ldap, | 151 mark_ldap, print_ldap, finalize_ldap, |
149 NULL, NULL, struct Lisp_LDAP); | 152 NULL, NULL, struct Lisp_LDAP); |
176 Return t if LDAP is an active LDAP connection. | 179 Return t if LDAP is an active LDAP connection. |
177 */ | 180 */ |
178 (ldap)) | 181 (ldap)) |
179 { | 182 { |
180 CHECK_LDAP (ldap); | 183 CHECK_LDAP (ldap); |
181 return (XLDAP (ldap))->livep ? Qt : Qnil; | 184 return (XLDAP (ldap))->ld ? Qt : Qnil; |
182 } | 185 } |
183 | 186 |
184 /************************************************************************/ | 187 /************************************************************************/ |
185 /* Opening/Closing a LDAP connection */ | 188 /* Opening/Closing a LDAP connection */ |
186 /************************************************************************/ | 189 /************************************************************************/ |
286 { | 289 { |
287 ldap_port = ldap_default_port; | 290 ldap_port = ldap_default_port; |
288 } | 291 } |
289 | 292 |
290 /* Connect to the server and bind */ | 293 /* Connect to the server and bind */ |
294 slow_down_interrupts (); | |
291 ld = ldap_open ((char *)XSTRING_DATA (host), ldap_port); | 295 ld = ldap_open ((char *)XSTRING_DATA (host), ldap_port); |
296 speed_up_interrupts (); | |
297 | |
292 if (ld == NULL ) | 298 if (ld == NULL ) |
293 signal_simple_error_2 ("Failed connecting to host", | 299 signal_simple_error_2 ("Failed connecting to host", |
294 host, | 300 host, |
295 lisp_strerror (errno)); | 301 lisp_strerror (errno)); |
296 | 302 |
297 | 303 |
298 #ifdef HAVE_LDAP_SET_OPTION | 304 #ifdef HAVE_LDAP_SET_OPTION |
299 if (ldap_set_option (ld, LDAP_OPT_DEREF, (void *)&ldap_deref) != LDAP_SUCCESS) | 305 if ((err = ldap_set_option (ld, LDAP_OPT_DEREF, |
300 signal_ldap_error (ld); | 306 (void *)&ldap_deref)) != LDAP_SUCCESS) |
301 if (ldap_set_option (ld, LDAP_OPT_TIMELIMIT, | 307 signal_ldap_error (ld, NULL, err); |
302 (void *)&ldap_timelimit) != LDAP_SUCCESS) | 308 if ((err = ldap_set_option (ld, LDAP_OPT_TIMELIMIT, |
303 signal_ldap_error (ld); | 309 (void *)&ldap_timelimit)) != LDAP_SUCCESS) |
304 if (ldap_set_option (ld, LDAP_OPT_SIZELIMIT, | 310 signal_ldap_error (ld, NULL, err); |
305 (void *)&ldap_sizelimit) != LDAP_SUCCESS) | 311 if ((err = ldap_set_option (ld, LDAP_OPT_SIZELIMIT, |
306 signal_ldap_error (ld); | 312 (void *)&ldap_sizelimit)) != LDAP_SUCCESS) |
307 if (ldap_set_option (ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON) != LDAP_SUCCESS) | 313 signal_ldap_error (ld, NULL, err); |
308 signal_ldap_error (ld); | 314 if ((err = ldap_set_option (ld, LDAP_OPT_REFERRALS, |
315 LDAP_OPT_ON)) != LDAP_SUCCESS) | |
316 signal_ldap_error (ld, NULL, err); | |
317 if ((err = ldap_set_option (ld, LDAP_OPT_RESTART, | |
318 LDAP_OPT_ON)) != LDAP_SUCCESS) | |
319 signal_ldap_error (ld, NULL, err); | |
309 #else /* not HAVE_LDAP_SET_OPTION */ | 320 #else /* not HAVE_LDAP_SET_OPTION */ |
310 ld->ld_deref = ldap_deref; | 321 ld->ld_deref = ldap_deref; |
311 ld->ld_timelimit = ldap_timelimit; | 322 ld->ld_timelimit = ldap_timelimit; |
312 ld->ld_sizelimit = ldap_sizelimit; | 323 ld->ld_sizelimit = ldap_sizelimit; |
313 #ifdef LDAP_REFERRALS | 324 #ifdef LDAP_REFERRALS |
314 ld->ld_options = LDAP_OPT_REFERRALS; | 325 ld->ld_options = LDAP_OPT_REFERRALS; |
315 #else /* not LDAP_REFERRALS */ | 326 #else /* not LDAP_REFERRALS */ |
316 ld->ld_options = 0; | 327 ld->ld_options = 0; |
317 #endif /* not LDAP_REFERRALS */ | 328 #endif /* not LDAP_REFERRALS */ |
329 /* XEmacs uses interrupts (SIGIO,SIGALRM), LDAP calls need to ignore them */ | |
330 ld->ld_options |= LDAP_OPT_RESTART; | |
318 #endif /* not HAVE_LDAP_SET_OPTION */ | 331 #endif /* not HAVE_LDAP_SET_OPTION */ |
319 | 332 |
320 /* ldap_bind_s calls select and may be wedged by SIGIO. */ | |
321 slow_down_interrupts (); | |
322 err = ldap_bind_s (ld, ldap_binddn, ldap_passwd, ldap_auth); | 333 err = ldap_bind_s (ld, ldap_binddn, ldap_passwd, ldap_auth); |
323 speed_up_interrupts (); | |
324 if (err != LDAP_SUCCESS) | 334 if (err != LDAP_SUCCESS) |
325 signal_simple_error ("Failed binding to the server", | 335 signal_simple_error ("Failed binding to the server", |
326 build_string (ldap_err2string (err))); | 336 build_string (ldap_err2string (err))); |
327 | 337 |
328 ldap = allocate_ldap (); | 338 ldap = allocate_ldap (); |
329 ldap->ld = ld; | 339 ldap->ld = ld; |
330 ldap->host = host; | 340 ldap->host = host; |
331 ldap->livep = 1; | |
332 | 341 |
333 return make_ldap (ldap); | 342 return make_ldap (ldap); |
334 } | 343 } |
335 | 344 |
336 | 345 |
342 { | 351 { |
343 struct Lisp_LDAP *lldap; | 352 struct Lisp_LDAP *lldap; |
344 CHECK_LIVE_LDAP (ldap); | 353 CHECK_LIVE_LDAP (ldap); |
345 lldap = XLDAP (ldap); | 354 lldap = XLDAP (ldap); |
346 ldap_unbind (lldap->ld); | 355 ldap_unbind (lldap->ld); |
347 lldap->livep = 0; | 356 lldap->ld = NULL; |
348 return Qnil; | 357 return Qnil; |
349 } | 358 } |
350 | 359 |
351 | 360 |
352 | 361 |
354 /* Working on a LDAP connection */ | 363 /* Working on a LDAP connection */ |
355 /************************************************************************/ | 364 /************************************************************************/ |
356 struct ldap_unwind_struct | 365 struct ldap_unwind_struct |
357 { | 366 { |
358 LDAPMessage *res; | 367 LDAPMessage *res; |
359 char **vals; | 368 struct berval **vals; |
360 }; | 369 }; |
361 | |
362 | 370 |
363 static Lisp_Object | 371 static Lisp_Object |
364 ldap_search_unwind (Lisp_Object unwind_obj) | 372 ldap_search_unwind (Lisp_Object unwind_obj) |
365 { | 373 { |
366 struct ldap_unwind_struct *unwind = | 374 struct ldap_unwind_struct *unwind = |
367 (struct ldap_unwind_struct *) get_opaque_ptr (unwind_obj); | 375 (struct ldap_unwind_struct *) get_opaque_ptr (unwind_obj); |
368 if (unwind->res) | 376 if (unwind->res) |
369 ldap_msgfree (unwind->res); | 377 ldap_msgfree (unwind->res); |
370 if (unwind->vals) | 378 if (unwind->vals) |
371 ldap_value_free (unwind->vals); | 379 ldap_value_free_len (unwind->vals); |
372 return Qnil; | 380 return Qnil; |
373 } | 381 } |
374 | 382 |
375 DEFUN ("ldap-search-internal", Fldap_search_internal, 2, 6, 0, /* | 383 DEFUN ("ldap-search-internal", Fldap_search_internal, 2, 6, 0, /* |
376 Perform a search on an open LDAP connection. | 384 Perform a search on an open LDAP connection. |
393 /* Vars for query */ | 401 /* Vars for query */ |
394 LDAP *ld; | 402 LDAP *ld; |
395 LDAPMessage *e; | 403 LDAPMessage *e; |
396 BerElement *ptr; | 404 BerElement *ptr; |
397 char *a; | 405 char *a; |
398 int i, rc; | 406 int i, rc, rc2; |
399 int matches; | 407 int matches; |
400 struct ldap_unwind_struct unwind; | 408 struct ldap_unwind_struct unwind; |
401 | 409 |
402 int ldap_scope = LDAP_SCOPE_SUBTREE; | 410 int ldap_scope = LDAP_SCOPE_SUBTREE; |
403 char **ldap_attributes = NULL; | 411 char **ldap_attributes = NULL; |
468 NILP (base) ? "" : (char *) XSTRING_DATA (base), | 476 NILP (base) ? "" : (char *) XSTRING_DATA (base), |
469 ldap_scope, | 477 ldap_scope, |
470 NILP (filter) ? "" : (char *) XSTRING_DATA (filter), | 478 NILP (filter) ? "" : (char *) XSTRING_DATA (filter), |
471 ldap_attributes, | 479 ldap_attributes, |
472 NILP (attrsonly) ? 0 : 1) | 480 NILP (attrsonly) ? 0 : 1) |
473 == -1) | 481 == -1) |
474 { | 482 { |
475 signal_ldap_error (ld); | 483 signal_ldap_error (ld, NULL, 0); |
476 } | 484 } |
477 | 485 |
478 /* Ensure we don't exit without cleaning up */ | 486 /* Ensure we don't exit without cleaning up */ |
479 record_unwind_protect (ldap_search_unwind, | 487 record_unwind_protect (ldap_search_unwind, |
480 make_opaque_ptr (&unwind)); | 488 make_opaque_ptr (&unwind)); |
481 | 489 |
482 /* Build the results list */ | 490 /* Build the results list */ |
483 matches = 0; | 491 matches = 0; |
484 | 492 |
485 /* ldap_result calls select() and can get wedged by EINTR signals */ | |
486 slow_down_interrupts (); | |
487 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &unwind.res); | 493 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &unwind.res); |
488 speed_up_interrupts (); | 494 |
489 while (rc == LDAP_RES_SEARCH_ENTRY) | 495 while (rc == LDAP_RES_SEARCH_ENTRY) |
490 { | 496 { |
491 QUIT; | 497 QUIT; |
492 matches ++; | 498 matches ++; |
493 e = ldap_first_entry (ld, unwind.res); | 499 e = ldap_first_entry (ld, unwind.res); |
497 restore the old echo area contents later. */ | 503 restore the old echo area contents later. */ |
498 message ("Parsing ldap results... %d", matches); | 504 message ("Parsing ldap results... %d", matches); |
499 entry = Qnil; | 505 entry = Qnil; |
500 for (a= ldap_first_attribute (ld, e, &ptr); | 506 for (a= ldap_first_attribute (ld, e, &ptr); |
501 a != NULL; | 507 a != NULL; |
502 a= ldap_next_attribute (ld, e, ptr) ) | 508 a = ldap_next_attribute (ld, e, ptr) ) |
503 { | 509 { |
504 list = Fcons (build_ext_string (a, FORMAT_OS), Qnil); | 510 list = Fcons (build_ext_string (a, FORMAT_OS), Qnil); |
505 unwind.vals = ldap_get_values (ld, e, a); | 511 unwind.vals = ldap_get_values_len (ld, e, a); |
506 if (unwind.vals != NULL) | 512 if (unwind.vals != NULL) |
507 { | 513 { |
508 for (i = 0; unwind.vals[i] != NULL; i++) | 514 for (i = 0; unwind.vals[i] != NULL; i++) |
509 { | 515 { |
510 list = Fcons (build_ext_string (unwind.vals[i], FORMAT_OS), | 516 list = Fcons (make_ext_string (unwind.vals[i]->bv_val, |
517 unwind.vals[i]->bv_len, | |
518 FORMAT_OS), | |
511 list); | 519 list); |
512 } | 520 } |
513 } | 521 } |
514 entry = Fcons (Fnreverse (list), | 522 entry = Fcons (Fnreverse (list), |
515 entry); | 523 entry); |
516 ldap_value_free (unwind.vals); | 524 ldap_value_free_len (unwind.vals); |
517 unwind.vals = NULL; | 525 unwind.vals = NULL; |
518 } | 526 } |
519 result = Fcons (Fnreverse (entry), | 527 result = Fcons (Fnreverse (entry), |
520 result); | 528 result); |
521 ldap_msgfree (unwind.res); | 529 ldap_msgfree (unwind.res); |
522 unwind.res = NULL; | 530 unwind.res = NULL; |
523 | 531 |
524 slow_down_interrupts (); | |
525 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &(unwind.res)); | 532 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &(unwind.res)); |
526 speed_up_interrupts (); | 533 } |
527 } | 534 |
535 #if defined HAVE_LDAP_PARSE_RESULT | |
536 rc2 = ldap_parse_result (ld, unwind.res, | |
537 &rc, | |
538 NULL, NULL, NULL, NULL, 0); | |
539 if (rc2 != LDAP_SUCCESS) | |
540 rc = rc2; | |
541 #else | |
542 if (rc == 0) | |
543 signal_ldap_error (ld, NULL, LDAP_TIMELIMIT_EXCEEDED); | |
528 | 544 |
529 if (rc == -1) | 545 if (rc == -1) |
530 { | 546 signal_ldap_error (ld, unwind.res, (unwind.res==NULL) ? ld->ld_errno : 0); |
531 signal_ldap_error (ld); | 547 |
532 } | 548 #if defined HAVE_LDAP_RESULT2ERROR |
533 rc = ldap_result2error (ld, unwind.res, 0); | 549 rc = ldap_result2error (ld, unwind.res, 0); |
534 if ((rc != LDAP_SUCCESS) && | 550 #endif |
535 (rc != LDAP_SIZELIMIT_EXCEEDED)) | 551 #endif |
536 { | 552 |
537 signal_ldap_error (ld); | 553 if (rc != LDAP_SUCCESS) |
538 } | 554 signal_ldap_error (ld, NULL, rc); |
539 | 555 |
540 ldap_msgfree (unwind.res); | 556 ldap_msgfree (unwind.res); |
541 unwind.res = (LDAPMessage *)NULL; | 557 unwind.res = (LDAPMessage *)NULL; |
558 | |
542 /* #### See above for calling message(). */ | 559 /* #### See above for calling message(). */ |
543 message ("Parsing ldap results... done"); | 560 message ("Parsing ldap results... done"); |
544 | 561 |
545 unbind_to (speccount, Qnil); | 562 unbind_to (speccount, Qnil); |
546 UNGCPRO; | 563 UNGCPRO; |
561 } | 578 } |
562 | 579 |
563 void | 580 void |
564 vars_of_eldap (void) | 581 vars_of_eldap (void) |
565 { | 582 { |
566 Fprovide (intern ("ldap")); | |
567 | 583 |
568 ldap_default_port = LDAP_PORT; | 584 ldap_default_port = LDAP_PORT; |
569 Vldap_default_base = Qnil; | 585 Vldap_default_base = Qnil; |
570 | 586 |
571 DEFVAR_INT ("ldap-default-port", &ldap_default_port /* | 587 DEFVAR_INT ("ldap-default-port", &ldap_default_port /* |