Mercurial > hg > xemacs-beta
comparison src/eldap.c @ 400:a86b2b5e0111 r21-2-30
Import from CVS: tag r21-2-30
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:14:34 +0200 |
parents | 74fd4e045ea6 |
children | 2f8bb876ab1d |
comparison
equal
deleted
inserted
replaced
399:376370fb5946 | 400:a86b2b5e0111 |
---|---|
52 static Lisp_Object Qbase, Qonelevel, Qsubtree; | 52 static Lisp_Object Qbase, Qonelevel, Qsubtree; |
53 /* Authentication methods */ | 53 /* Authentication methods */ |
54 static Lisp_Object Qkrbv41, Qkrbv42; | 54 static Lisp_Object Qkrbv41, Qkrbv42; |
55 /* Deref policy */ | 55 /* Deref policy */ |
56 static Lisp_Object Qnever, Qalways, Qfind; | 56 static Lisp_Object Qnever, Qalways, Qfind; |
57 /* Modification types (Qdelete is defined in general.c) */ | |
58 static Lisp_Object Qadd, Qreplace; | |
59 | |
57 | 60 |
58 /************************************************************************/ | 61 /************************************************************************/ |
59 /* Utility Functions */ | 62 /* Utility Functions */ |
60 /************************************************************************/ | 63 /************************************************************************/ |
61 | 64 |
314 (void *)&ldap_sizelimit)) != LDAP_SUCCESS) | 317 (void *)&ldap_sizelimit)) != LDAP_SUCCESS) |
315 signal_ldap_error (ld, NULL, err); | 318 signal_ldap_error (ld, NULL, err); |
316 if ((err = ldap_set_option (ld, LDAP_OPT_REFERRALS, | 319 if ((err = ldap_set_option (ld, LDAP_OPT_REFERRALS, |
317 LDAP_OPT_ON)) != LDAP_SUCCESS) | 320 LDAP_OPT_ON)) != LDAP_SUCCESS) |
318 signal_ldap_error (ld, NULL, err); | 321 signal_ldap_error (ld, NULL, err); |
322 if ((err = ldap_set_option (ld, LDAP_OPT_RESTART, | |
323 LDAP_OPT_ON)) != LDAP_SUCCESS) | |
324 signal_ldap_error (ld, NULL, err); | |
319 #else /* not HAVE_LDAP_SET_OPTION */ | 325 #else /* not HAVE_LDAP_SET_OPTION */ |
320 ld->ld_deref = ldap_deref; | 326 ld->ld_deref = ldap_deref; |
321 ld->ld_timelimit = ldap_timelimit; | 327 ld->ld_timelimit = ldap_timelimit; |
322 ld->ld_sizelimit = ldap_sizelimit; | 328 ld->ld_sizelimit = ldap_sizelimit; |
323 #ifdef LDAP_REFERRALS | 329 #ifdef LDAP_REFERRALS |
324 ld->ld_options = LDAP_OPT_REFERRALS; | 330 ld->ld_options = LDAP_OPT_REFERRALS; |
325 #else /* not LDAP_REFERRALS */ | 331 #else /* not LDAP_REFERRALS */ |
326 ld->ld_options = 0; | 332 ld->ld_options = 0; |
327 #endif /* not LDAP_REFERRALS */ | 333 #endif /* not LDAP_REFERRALS */ |
334 /* XEmacs uses interrupts (SIGIO,SIGALRM), LDAP calls need to ignore them */ | |
335 ld->ld_options |= LDAP_OPT_RESTART; | |
328 #endif /* not HAVE_LDAP_SET_OPTION */ | 336 #endif /* not HAVE_LDAP_SET_OPTION */ |
329 | 337 |
330 /* ldap_bind_s calls select and may be wedged by SIGIO. */ | |
331 slow_down_interrupts (); | |
332 err = ldap_bind_s (ld, ldap_binddn, ldap_passwd, ldap_auth); | 338 err = ldap_bind_s (ld, ldap_binddn, ldap_passwd, ldap_auth); |
333 speed_up_interrupts (); | |
334 if (err != LDAP_SUCCESS) | 339 if (err != LDAP_SUCCESS) |
335 signal_simple_error ("Failed binding to the server", | 340 signal_simple_error ("Failed binding to the server", |
336 build_string (ldap_err2string (err))); | 341 build_string (ldap_err2string (err))); |
337 | 342 |
338 ldap = allocate_ldap (); | 343 ldap = allocate_ldap (); |
365 struct ldap_unwind_struct | 370 struct ldap_unwind_struct |
366 { | 371 { |
367 LDAPMessage *res; | 372 LDAPMessage *res; |
368 struct berval **vals; | 373 struct berval **vals; |
369 }; | 374 }; |
370 | |
371 | 375 |
372 static Lisp_Object | 376 static Lisp_Object |
373 ldap_search_unwind (Lisp_Object unwind_obj) | 377 ldap_search_unwind (Lisp_Object unwind_obj) |
374 { | 378 { |
375 struct ldap_unwind_struct *unwind = | 379 struct ldap_unwind_struct *unwind = |
379 if (unwind->vals) | 383 if (unwind->vals) |
380 ldap_value_free_len (unwind->vals); | 384 ldap_value_free_len (unwind->vals); |
381 return Qnil; | 385 return Qnil; |
382 } | 386 } |
383 | 387 |
384 DEFUN ("ldap-search-internal", Fldap_search_internal, 2, 7, 0, /* | 388 /* The following function is called `ldap-search-basic' instead of */ |
389 /* plain `ldap-search' to maintain compatibility with the XEmacs 21.1 */ | |
390 /* API where `ldap-search' was the name of the high-level search */ | |
391 /* function */ | |
392 | |
393 DEFUN ("ldap-search-basic", Fldap_search_basic, 2, 8, 0, /* | |
385 Perform a search on an open LDAP connection. | 394 Perform a search on an open LDAP connection. |
386 LDAP is an LDAP connection object created with `ldap-open'. | 395 LDAP is an LDAP connection object created with `ldap-open'. |
387 FILTER is a filter string for the search as described in RFC 1558. | 396 FILTER is a filter string for the search as described in RFC 1558. |
388 BASE is the distinguished name at which to start the search. | 397 BASE is the distinguished name at which to start the search. |
389 SCOPE is one of the symbols `base', `onelevel' or `subtree' indicating | 398 SCOPE is one of the symbols `base', `onelevel' or `subtree' indicating |
390 the scope of the search. | 399 the scope of the search. |
391 ATTRS is a list of strings indicating which attributes to retrieve | 400 ATTRS is a list of strings indicating which attributes to retrieve |
392 for each matching entry. If nil return all available attributes. | 401 for each matching entry. If nil return all available attributes. |
393 If ATTRSONLY is non-nil then only the attributes are retrieved, not | 402 If ATTRSONLY is non-nil then only the attributes are retrieved, not |
394 the associated values. | 403 the associated values. |
395 If WITHDN is non-nil each entry in the result will be prepennded with | 404 If WITHDN is non-nil each entry in the result will be prepended with |
396 its distinguished name DN. | 405 its distinguished name DN. |
406 If VERBOSE is non-nil progress messages will be echoed. | |
397 The function returns a list of matching entries. Each entry is itself | 407 The function returns a list of matching entries. Each entry is itself |
398 an alist of attribute/value pairs optionally preceded by the DN of the | 408 an alist of attribute/value pairs optionally preceded by the DN of the |
399 entry according to the value of WITHDN. | 409 entry according to the value of WITHDN. |
400 */ | 410 */ |
401 (ldap, filter, base, scope, attrs, attrsonly, withdn)) | 411 (ldap, filter, base, scope, attrs, attrsonly, withdn, verbose)) |
402 { | 412 { |
403 /* This function can GC */ | 413 /* This function can GC */ |
404 | 414 |
405 /* Vars for query */ | 415 /* Vars for query */ |
406 LDAP *ld; | 416 LDAP *ld; |
494 make_opaque_ptr (&unwind)); | 504 make_opaque_ptr (&unwind)); |
495 | 505 |
496 /* Build the results list */ | 506 /* Build the results list */ |
497 matches = 0; | 507 matches = 0; |
498 | 508 |
499 /* ldap_result calls select() and can get wedged by EINTR signals */ | |
500 slow_down_interrupts (); | |
501 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &unwind.res); | 509 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &unwind.res); |
502 speed_up_interrupts (); | 510 |
503 while (rc == LDAP_RES_SEARCH_ENTRY) | 511 while (rc == LDAP_RES_SEARCH_ENTRY) |
504 { | 512 { |
505 QUIT; | 513 QUIT; |
506 matches ++; | 514 matches ++; |
507 e = ldap_first_entry (ld, unwind.res); | 515 e = ldap_first_entry (ld, unwind.res); |
508 /* #### This call to message() is pretty fascist, because it | 516 /* #### This call to message() is pretty fascist, because it |
509 destroys the current echo area contents, even when invoked | 517 destroys the current echo area contents, even when invoked |
510 from Lisp. It should use echo_area_message() instead, and | 518 from Lisp. It should use echo_area_message() instead, and |
511 restore the old echo area contents later. */ | 519 restore the old echo area contents later. */ |
512 message ("Parsing ldap results... %d", matches); | 520 if (! NILP (verbose)) |
521 message ("Parsing ldap results... %d", matches); | |
513 entry = Qnil; | 522 entry = Qnil; |
514 /* Get the DN if required */ | 523 /* Get the DN if required */ |
515 if (! NILP (withdn)) | 524 if (! NILP (withdn)) |
516 { | 525 { |
517 dn = ldap_get_dn (ld, e); | 526 dn = ldap_get_dn (ld, e); |
543 result = Fcons (Fnreverse (entry), | 552 result = Fcons (Fnreverse (entry), |
544 result); | 553 result); |
545 ldap_msgfree (unwind.res); | 554 ldap_msgfree (unwind.res); |
546 unwind.res = NULL; | 555 unwind.res = NULL; |
547 | 556 |
548 slow_down_interrupts (); | |
549 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &(unwind.res)); | 557 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &(unwind.res)); |
550 speed_up_interrupts (); | 558 } |
551 } | |
552 | |
553 if (rc == -1) | |
554 signal_ldap_error (ld, unwind.res, 0); | |
555 | |
556 if (rc == 0) | |
557 signal_ldap_error (ld, NULL, LDAP_TIMELIMIT_EXCEEDED); | |
558 | 559 |
559 #if defined HAVE_LDAP_PARSE_RESULT | 560 #if defined HAVE_LDAP_PARSE_RESULT |
560 rc2 = ldap_parse_result (ld, unwind.res, | 561 rc2 = ldap_parse_result (ld, unwind.res, |
561 &rc, | 562 &rc, |
562 NULL, NULL, NULL, NULL, 0); | 563 NULL, NULL, NULL, NULL, 0); |
563 if (rc2 != LDAP_SUCCESS) | 564 if (rc2 != LDAP_SUCCESS) |
564 rc = rc2; | 565 rc = rc2; |
565 #elif defined HAVE_LDAP_RESULT2ERROR | 566 #else |
567 if (rc == 0) | |
568 signal_ldap_error (ld, NULL, LDAP_TIMELIMIT_EXCEEDED); | |
569 | |
570 if (rc == -1) | |
571 signal_ldap_error (ld, unwind.res, (unwind.res==NULL) ? ld->ld_errno : 0); | |
572 | |
573 #if defined HAVE_LDAP_RESULT2ERROR | |
566 rc = ldap_result2error (ld, unwind.res, 0); | 574 rc = ldap_result2error (ld, unwind.res, 0); |
567 #endif | 575 #endif |
568 if ((rc != LDAP_SUCCESS) && (rc != LDAP_SIZELIMIT_EXCEEDED)) | 576 #endif |
577 | |
578 if (rc != LDAP_SUCCESS) | |
569 signal_ldap_error (ld, NULL, rc); | 579 signal_ldap_error (ld, NULL, rc); |
570 | 580 |
571 ldap_msgfree (unwind.res); | 581 ldap_msgfree (unwind.res); |
572 unwind.res = (LDAPMessage *)NULL; | 582 unwind.res = (LDAPMessage *)NULL; |
583 | |
573 /* #### See above for calling message(). */ | 584 /* #### See above for calling message(). */ |
574 message ("Parsing ldap results... done"); | 585 if (! NILP (verbose)) |
586 message ("Parsing ldap results... done"); | |
575 | 587 |
576 unbind_to (speccount, Qnil); | 588 unbind_to (speccount, Qnil); |
577 UNGCPRO; | 589 UNGCPRO; |
578 return Fnreverse (result); | 590 return Fnreverse (result); |
579 } | 591 } |
580 | 592 |
593 DEFUN ("ldap-add", Fldap_add, 3, 3, 0, /* | |
594 Add an entry to an LDAP directory. | |
595 LDAP is an LDAP connection object created with `ldap-open'. | |
596 DN is the distinguished name of the entry to add. | |
597 ENTRY is an entry specification, i.e., a list of cons cells | |
598 containing attribute/value string pairs. | |
599 */ | |
600 (ldap, dn, entry)) | |
601 { | |
602 LDAP *ld; | |
603 LDAPMod *ldap_mods, **ldap_mods_ptrs; | |
604 struct berval *bervals; | |
605 int rc; | |
606 int i, j; | |
607 | |
608 Lisp_Object current, values; | |
609 struct gcpro gcpro1, gcpro2; | |
610 GCPRO2 (current, values); | |
611 | |
612 /* Do all the parameter checking */ | |
613 CHECK_LIVE_LDAP (ldap); | |
614 ld = XLDAP (ldap)->ld; | |
615 | |
616 /* Check the DN */ | |
617 CHECK_STRING (dn); | |
618 | |
619 /* Check the entry */ | |
620 CHECK_CONS (entry); | |
621 if (NILP (entry)) | |
622 signal_simple_error ("Cannot add void entry", entry); | |
623 | |
624 /* Build the ldap_mods array */ | |
625 ldap_mods = alloca_array (LDAPMod, XINT (Flength (entry))); | |
626 ldap_mods_ptrs = alloca_array (LDAPMod *, 1 + XINT (Flength (entry))); | |
627 i = 0; | |
628 EXTERNAL_LIST_LOOP (entry, entry) | |
629 { | |
630 current = XCAR (entry); | |
631 CHECK_CONS (current); | |
632 CHECK_STRING (XCAR (current)); | |
633 ldap_mods_ptrs[i] = &(ldap_mods[i]); | |
634 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (current), | |
635 C_STRING_ALLOCA, ldap_mods[i].mod_type, | |
636 Qnative); | |
637 ldap_mods[i].mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES; | |
638 values = XCDR (current); | |
639 if (CONSP (values)) | |
640 { | |
641 bervals = | |
642 alloca_array (struct berval, XINT (Flength (values))); | |
643 ldap_mods[i].mod_vals.modv_bvals = | |
644 alloca_array (struct berval *, 1 + XINT (Flength (values))); | |
645 j = 0; | |
646 EXTERNAL_LIST_LOOP (values, values) | |
647 { | |
648 current = XCAR (values); | |
649 CHECK_STRING (current); | |
650 ldap_mods[i].mod_vals.modv_bvals[j] = &(bervals[j]); | |
651 TO_EXTERNAL_FORMAT (LISP_STRING, current, | |
652 ALLOCA, (bervals[j].bv_val, | |
653 bervals[j].bv_len), | |
654 Qnative); | |
655 j++; | |
656 } | |
657 ldap_mods[i].mod_vals.modv_bvals[j] = NULL; | |
658 } | |
659 else | |
660 { | |
661 CHECK_STRING (values); | |
662 bervals = alloca_array (struct berval, 1); | |
663 ldap_mods[i].mod_vals.modv_bvals = alloca_array (struct berval *, 2); | |
664 ldap_mods[i].mod_vals.modv_bvals[0] = &(bervals[0]); | |
665 TO_EXTERNAL_FORMAT (LISP_STRING, values, | |
666 ALLOCA, (bervals[0].bv_val, | |
667 bervals[0].bv_len), | |
668 Qnative); | |
669 ldap_mods[i].mod_vals.modv_bvals[1] = NULL; | |
670 } | |
671 i++; | |
672 } | |
673 ldap_mods_ptrs[i] = NULL; | |
674 rc = ldap_add_s (ld, (char *) XSTRING_DATA (dn), ldap_mods_ptrs); | |
675 if (rc != LDAP_SUCCESS) | |
676 signal_ldap_error (ld, NULL, rc); | |
677 | |
678 UNGCPRO; | |
679 } | |
680 | |
681 DEFUN ("ldap-modify", Fldap_modify, 3, 3, 0, /* | |
682 Add an entry to an LDAP directory. | |
683 LDAP is an LDAP connection object created with `ldap-open'. | |
684 DN is the distinguished name of the entry to modify. | |
685 MODS is a list of modifications to apply. | |
686 A modification is a list of the form (MOD-OP ATTR VALUE1 VALUE2 ...) | |
687 MOD-OP and ATTR are mandatory, VALUEs are optional depending on MOD-OP. | |
688 MOD-OP is the type of modification, one of the symbols `add', `delete' | |
689 or `replace'. ATTR is the LDAP attribute type to modify | |
690 */ | |
691 (ldap, dn, mods)) | |
692 { | |
693 LDAP *ld; | |
694 LDAPMod *ldap_mods, **ldap_mods_ptrs; | |
695 struct berval *bervals; | |
696 int i, j, rc; | |
697 | |
698 Lisp_Object current, mod_op, values; | |
699 struct gcpro gcpro1, gcpro2; | |
700 | |
701 GCPRO2 (current, values); | |
702 | |
703 /* Do all the parameter checking */ | |
704 CHECK_LIVE_LDAP (ldap); | |
705 ld = XLDAP (ldap)->ld; | |
706 | |
707 /* Check the DN */ | |
708 CHECK_STRING (dn); | |
709 | |
710 /* Check the entry */ | |
711 CHECK_CONS (mods); | |
712 if (NILP (mods)) | |
713 return Qnil; | |
714 | |
715 /* Build the ldap_mods array */ | |
716 ldap_mods = alloca_array (LDAPMod, XINT (Flength (mods))); | |
717 ldap_mods_ptrs = alloca_array (LDAPMod *, 1 + XINT (Flength (mods))); | |
718 i = 0; | |
719 EXTERNAL_LIST_LOOP (mods, mods) | |
720 { | |
721 current = XCAR (mods); | |
722 CHECK_CONS (current); | |
723 CHECK_SYMBOL (XCAR (current)); | |
724 mod_op = XCAR (current); | |
725 ldap_mods_ptrs[i] = &(ldap_mods[i]); | |
726 ldap_mods[i].mod_op = LDAP_MOD_BVALUES; | |
727 if (EQ (mod_op, Qadd)) | |
728 ldap_mods[i].mod_op |= LDAP_MOD_ADD; | |
729 else if (EQ (mod_op, Qdelete)) | |
730 ldap_mods[i].mod_op |= LDAP_MOD_DELETE; | |
731 else if (EQ (mod_op, Qreplace)) | |
732 ldap_mods[i].mod_op |= LDAP_MOD_REPLACE; | |
733 else | |
734 signal_simple_error ("Invalid LDAP modification type", mod_op); | |
735 current = XCDR (current); | |
736 CHECK_STRING (XCAR (current)); | |
737 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (current), | |
738 C_STRING_ALLOCA, ldap_mods[i].mod_type, | |
739 Qnative); | |
740 values = XCDR (current); | |
741 bervals = alloca_array (struct berval, XINT (Flength (values))); | |
742 ldap_mods[i].mod_vals.modv_bvals = | |
743 alloca_array (struct berval *, 1 + XINT (Flength (values))); | |
744 j = 0; | |
745 EXTERNAL_LIST_LOOP (values, values) | |
746 { | |
747 current = XCAR (values); | |
748 CHECK_STRING (current); | |
749 ldap_mods[i].mod_vals.modv_bvals[j] = &(bervals[j]); | |
750 TO_EXTERNAL_FORMAT (LISP_STRING, current, | |
751 ALLOCA, (bervals[j].bv_val, | |
752 bervals[j].bv_len), | |
753 Qnative); | |
754 j++; | |
755 } | |
756 ldap_mods[i].mod_vals.modv_bvals[j] = NULL; | |
757 i++; | |
758 } | |
759 ldap_mods_ptrs[i] = NULL; | |
760 rc = ldap_modify_s (ld, (char *) XSTRING_DATA (dn), ldap_mods_ptrs); | |
761 if (rc != LDAP_SUCCESS) | |
762 signal_ldap_error (ld, NULL, rc); | |
763 | |
764 UNGCPRO; | |
765 } | |
766 | |
767 | |
768 DEFUN ("ldap-delete", Fldap_delete, 2, 2, 0, /* | |
769 Delete an entry to an LDAP directory. | |
770 LDAP is an LDAP connection object created with `ldap-open'. | |
771 DN is the distinguished name of the entry to delete. | |
772 */ | |
773 (ldap, dn)) | |
774 { | |
775 LDAP *ld; | |
776 int rc; | |
777 | |
778 /* Check parameters */ | |
779 CHECK_LIVE_LDAP (ldap); | |
780 ld = XLDAP (ldap)->ld; | |
781 CHECK_STRING (dn); | |
782 | |
783 rc = ldap_delete_s (ld, (char *) XSTRING_DATA (dn)); | |
784 if (rc != LDAP_SUCCESS) | |
785 signal_ldap_error (ld, NULL, rc); | |
786 } | |
581 | 787 |
582 void | 788 void |
583 syms_of_eldap (void) | 789 syms_of_eldap (void) |
584 { | 790 { |
791 INIT_LRECORD_IMPLEMENTATION (ldap); | |
792 | |
585 defsymbol (&Qldapp, "ldapp"); | 793 defsymbol (&Qldapp, "ldapp"); |
586 defsymbol (&Qport, "port"); | 794 defsymbol (&Qport, "port"); |
587 defsymbol (&Qauth, "auth"); | 795 defsymbol (&Qauth, "auth"); |
588 defsymbol (&Qbinddn, "binddn"); | 796 defsymbol (&Qbinddn, "binddn"); |
589 defsymbol (&Qpasswd, "passwd"); | 797 defsymbol (&Qpasswd, "passwd"); |
596 defsymbol (&Qkrbv41, "krbv41"); | 804 defsymbol (&Qkrbv41, "krbv41"); |
597 defsymbol (&Qkrbv42, "krbv42"); | 805 defsymbol (&Qkrbv42, "krbv42"); |
598 defsymbol (&Qnever, "never"); | 806 defsymbol (&Qnever, "never"); |
599 defsymbol (&Qalways, "always"); | 807 defsymbol (&Qalways, "always"); |
600 defsymbol (&Qfind, "find"); | 808 defsymbol (&Qfind, "find"); |
809 defsymbol (&Qadd, "add"); | |
810 defsymbol (&Qreplace, "replace"); | |
601 | 811 |
602 DEFSUBR (Fldapp); | 812 DEFSUBR (Fldapp); |
603 DEFSUBR (Fldap_host); | 813 DEFSUBR (Fldap_host); |
604 DEFSUBR (Fldap_status); | 814 DEFSUBR (Fldap_status); |
605 DEFSUBR (Fldap_open); | 815 DEFSUBR (Fldap_open); |
606 DEFSUBR (Fldap_close); | 816 DEFSUBR (Fldap_close); |
607 DEFSUBR (Fldap_search_internal); | 817 DEFSUBR (Fldap_search_basic); |
818 DEFSUBR (Fldap_add); | |
819 DEFSUBR (Fldap_modify); | |
820 DEFSUBR (Fldap_delete); | |
608 } | 821 } |
609 | 822 |
610 void | 823 void |
611 vars_of_eldap (void) | 824 vars_of_eldap (void) |
612 { | 825 { |