Mercurial > hg > xemacs-beta
diff src/eldap.c @ 371:cc15677e0335 r21-2b1
Import from CVS: tag r21-2b1
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:03:08 +0200 |
parents | 7347b34c275b |
children | bbff43aa5eb7 |
line wrap: on
line diff
--- a/src/eldap.c Mon Aug 13 11:01:58 2007 +0200 +++ b/src/eldap.c Mon Aug 13 11:03:08 2007 +0200 @@ -26,20 +26,26 @@ conforming to the API defined in RFC 1823. It has been tested with: - UMich LDAP 3.3 (http://www.umich.edu/~dirsvcs/ldap/) - - OpenLDAP 1.2 (http://www.openldap.org/) - - Netscape's LDAP SDK (http://developer.netscape.com/) */ + - Netscape's LDAP SDK 1.0 (http://developer.netscape.com) */ #include <config.h> #include "lisp.h" #include "opaque.h" #include "sysdep.h" -#include "buffer.h" #include <errno.h> #include "eldap.h" +#ifdef HAVE_NS_LDAP +# define HAVE_LDAP_SET_OPTION 1 +# define HAVE_LDAP_GET_ERRNO 1 +#else +# undef HAVE_LDAP_SET_OPTION +# undef HAVE_LDAP_GET_ERRNO +#endif + static int ldap_default_port; static Lisp_Object Vldap_default_base; @@ -61,27 +67,16 @@ /************************************************************************/ static void -signal_ldap_error (LDAP *ld, LDAPMessage *res, int ldap_err) +signal_ldap_error (LDAP *ld) { - if (ldap_err <= 0) - { -#if defined HAVE_LDAP_PARSE_RESULT - int err; - ldap_err = ldap_parse_result (ld, res, - &err, - NULL, NULL, NULL, NULL, 0); - if (ldap_err == LDAP_SUCCESS) - ldap_err = err; -#elif defined HAVE_LDAP_GET_LDERRNO - ldap_err = ldap_get_lderrno (ld, NULL, NULL); -#elif defined HAVE_LDAP_RESULT2ERROR - ldap_err = ldap_result2error (ld, res, 0); +#ifdef HAVE_LDAP_GET_ERRNO + signal_simple_error + ("LDAP error", + build_string (ldap_err2string (ldap_get_lderrno (ld, NULL, NULL)))); #else - ldap_err = ld->ld_errno; + signal_simple_error ("LDAP error", + build_string (ldap_err2string (ld->ld_errno))); #endif - } - signal_simple_error ("LDAP error", - build_string (ldap_err2string (ldap_err))); } @@ -116,7 +111,7 @@ write_c_string ("#<ldap ", printcharfun); print_internal (ldap->host, printcharfun, 1); - if (!ldap->ld) + if (!ldap->livep) write_c_string ("(dead) ",printcharfun); sprintf (buf, " 0x%x>", (unsigned int)ldap); write_c_string (buf, printcharfun); @@ -130,6 +125,7 @@ ldap->ld = NULL; ldap->host = Qnil; + ldap->livep = 0; return ldap; } @@ -142,9 +138,8 @@ signal_simple_error ("Can't dump an emacs containing LDAP objects", make_ldap (ldap)); - if (ldap->ld) + if (ldap->livep) ldap_unbind (ldap->ld); - ldap->ld = NULL; } DEFINE_LRECORD_IMPLEMENTATION ("ldap", ldap, @@ -181,7 +176,7 @@ (ldap)) { CHECK_LDAP (ldap); - return (XLDAP (ldap))->ld ? Qt : Qnil; + return (XLDAP (ldap))->livep ? Qt : Qnil; } /************************************************************************/ @@ -249,13 +244,15 @@ else if (EQ (keyword, Qbinddn)) { CHECK_STRING (value); - GET_C_STRING_OS_DATA_ALLOCA (value, ldap_binddn); + ldap_binddn = alloca (XSTRING_LENGTH (value) + 1); + strcpy (ldap_binddn, (char *)XSTRING_DATA (value)); } /* Password */ else if (EQ (keyword, Qpasswd)) { CHECK_STRING (value); - GET_C_STRING_OS_DATA_ALLOCA (value, ldap_passwd); + ldap_passwd = alloca (XSTRING_LENGTH (value) + 1); + strcpy (ldap_passwd, (char *)XSTRING_DATA (value)); } /* Deref */ else if (EQ (keyword, Qderef)) @@ -291,10 +288,7 @@ } /* Connect to the server and bind */ - slow_down_interrupts (); ld = ldap_open ((char *)XSTRING_DATA (host), ldap_port); - speed_up_interrupts (); - if (ld == NULL ) signal_simple_error_2 ("Failed connecting to host", host, @@ -302,21 +296,16 @@ #ifdef HAVE_LDAP_SET_OPTION - if ((err = ldap_set_option (ld, LDAP_OPT_DEREF, - (void *)&ldap_deref)) != LDAP_SUCCESS) - signal_ldap_error (ld, NULL, err); - if ((err = ldap_set_option (ld, LDAP_OPT_TIMELIMIT, - (void *)&ldap_timelimit)) != LDAP_SUCCESS) - signal_ldap_error (ld, NULL, err); - if ((err = ldap_set_option (ld, LDAP_OPT_SIZELIMIT, - (void *)&ldap_sizelimit)) != LDAP_SUCCESS) - signal_ldap_error (ld, NULL, err); - if ((err = ldap_set_option (ld, LDAP_OPT_REFERRALS, - LDAP_OPT_ON)) != LDAP_SUCCESS) - signal_ldap_error (ld, NULL, err); - if ((err = ldap_set_option (ld, LDAP_OPT_RESTART, - LDAP_OPT_ON)) != LDAP_SUCCESS) - signal_ldap_error (ld, NULL, err); + if (ldap_set_option (ld, LDAP_OPT_DEREF, (void *)&ldap_deref) != LDAP_SUCCESS) + signal_ldap_error (ld); + if (ldap_set_option (ld, LDAP_OPT_TIMELIMIT, + (void *)&ldap_timelimit) != LDAP_SUCCESS) + signal_ldap_error (ld); + if (ldap_set_option (ld, LDAP_OPT_SIZELIMIT, + (void *)&ldap_sizelimit) != LDAP_SUCCESS) + signal_ldap_error (ld); + if (ldap_set_option (ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON) != LDAP_SUCCESS) + signal_ldap_error (ld); #else /* not HAVE_LDAP_SET_OPTION */ ld->ld_deref = ldap_deref; ld->ld_timelimit = ldap_timelimit; @@ -326,11 +315,12 @@ #else /* not LDAP_REFERRALS */ ld->ld_options = 0; #endif /* not LDAP_REFERRALS */ - /* XEmacs uses interrupts (SIGIO,SIGALRM), LDAP calls need to ignore them */ - ld->ld_options |= LDAP_OPT_RESTART; #endif /* not HAVE_LDAP_SET_OPTION */ + /* ldap_bind_s calls select and may be wedged by SIGIO. */ + slow_down_interrupts (); err = ldap_bind_s (ld, ldap_binddn, ldap_passwd, ldap_auth); + speed_up_interrupts (); if (err != LDAP_SUCCESS) signal_simple_error ("Failed binding to the server", build_string (ldap_err2string (err))); @@ -338,6 +328,7 @@ ldap = allocate_ldap (); ldap->ld = ld; ldap->host = host; + ldap->livep = 1; return make_ldap (ldap); } @@ -353,7 +344,7 @@ CHECK_LIVE_LDAP (ldap); lldap = XLDAP (ldap); ldap_unbind (lldap->ld); - lldap->ld = NULL; + lldap->livep = 0; return Qnil; } @@ -365,9 +356,10 @@ struct ldap_unwind_struct { LDAPMessage *res; - struct berval **vals; + char **vals; }; + static Lisp_Object ldap_search_unwind (Lisp_Object unwind_obj) { @@ -376,7 +368,7 @@ if (unwind->res) ldap_msgfree (unwind->res); if (unwind->vals) - ldap_value_free_len (unwind->vals); + ldap_value_free (unwind->vals); return Qnil; } @@ -403,7 +395,7 @@ LDAPMessage *e; BerElement *ptr; char *a; - int i, rc, rc2; + int i, rc; int matches; struct ldap_unwind_struct unwind; @@ -462,7 +454,11 @@ { Lisp_Object current = XCAR (attrs); CHECK_STRING (current); - GET_C_STRING_OS_DATA_ALLOCA (current, ldap_attributes[i]); + ldap_attributes[i] = + alloca_array (char, 1 + XSTRING_LENGTH (current)); + /* XSTRING_LENGTH is increased by one in order to copy the final 0 */ + memcpy (ldap_attributes[i], + XSTRING_DATA (current), 1 + XSTRING_LENGTH (current)); ++i; } ldap_attributes[i] = NULL; @@ -478,9 +474,9 @@ NILP (filter) ? "" : (char *) XSTRING_DATA (filter), ldap_attributes, NILP (attrsonly) ? 0 : 1) - == -1) + == -1) { - signal_ldap_error (ld, NULL, 0); + signal_ldap_error (ld); } /* Ensure we don't exit without cleaning up */ @@ -490,8 +486,10 @@ /* Build the results list */ matches = 0; + /* ldap_result calls select() and can get wedged by EINTR signals */ + slow_down_interrupts (); rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &unwind.res); - + speed_up_interrupts (); while (rc == LDAP_RES_SEARCH_ENTRY) { QUIT; @@ -505,23 +503,21 @@ entry = Qnil; for (a= ldap_first_attribute (ld, e, &ptr); a != NULL; - a = ldap_next_attribute (ld, e, ptr) ) + a= ldap_next_attribute (ld, e, ptr) ) { list = Fcons (build_ext_string (a, FORMAT_OS), Qnil); - unwind.vals = ldap_get_values_len (ld, e, a); + unwind.vals = ldap_get_values (ld, e, a); if (unwind.vals != NULL) { for (i = 0; unwind.vals[i] != NULL; i++) { - list = Fcons (make_ext_string (unwind.vals[i]->bv_val, - unwind.vals[i]->bv_len, - FORMAT_OS), + list = Fcons (build_ext_string (unwind.vals[i], FORMAT_OS), list); } } entry = Fcons (Fnreverse (list), entry); - ldap_value_free_len (unwind.vals); + ldap_value_free (unwind.vals); unwind.vals = NULL; } result = Fcons (Fnreverse (entry), @@ -529,33 +525,24 @@ ldap_msgfree (unwind.res); unwind.res = NULL; + slow_down_interrupts (); rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &(unwind.res)); + speed_up_interrupts (); } -#if defined HAVE_LDAP_PARSE_RESULT - rc2 = ldap_parse_result (ld, unwind.res, - &rc, - NULL, NULL, NULL, NULL, 0); - if (rc2 != LDAP_SUCCESS) - rc = rc2; -#else - if (rc == 0) - signal_ldap_error (ld, NULL, LDAP_TIMELIMIT_EXCEEDED); - if (rc == -1) - signal_ldap_error (ld, unwind.res, (unwind.res==NULL) ? ld->ld_errno : 0); - -#if defined HAVE_LDAP_RESULT2ERROR + { + signal_ldap_error (ld); + } rc = ldap_result2error (ld, unwind.res, 0); -#endif -#endif - - if (rc != LDAP_SUCCESS) - signal_ldap_error (ld, NULL, rc); + if ((rc != LDAP_SUCCESS) && + (rc != LDAP_SIZELIMIT_EXCEEDED)) + { + signal_ldap_error (ld); + } ldap_msgfree (unwind.res); unwind.res = (LDAPMessage *)NULL; - /* #### See above for calling message(). */ message ("Parsing ldap results... done"); @@ -580,6 +567,7 @@ void vars_of_eldap (void) { + Fprovide (intern ("ldap")); ldap_default_port = LDAP_PORT; Vldap_default_base = Qnil;