diff src/eldap.c @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents 2f8bb876ab1d
children e804706bfb8c
line wrap: on
line diff
--- a/src/eldap.c	Mon Aug 13 11:19:22 2007 +0200
+++ b/src/eldap.c	Mon Aug 13 11:20:41 2007 +0200
@@ -26,8 +26,8 @@
    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/) */
+   - OpenLDAP 1.0.3 (http://www.openldap.org/)
+   - Netscape's LDAP SDK 1.0 (http://developer.netscape.com/) */
 
 
 #include <config.h>
@@ -40,6 +40,14 @@
 
 #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;
 
@@ -47,43 +55,30 @@
 Lisp_Object Qldapp;
 
 /* ldap-open plist keywords */
-static Lisp_Object Qport, Qauth, Qbinddn, Qpasswd, Qderef, Qtimelimit, Qsizelimit;
+extern Lisp_Object Qport, Qauth, Qbinddn, Qpasswd, Qderef, Qtimelimit,
+  Qsizelimit;
 /* Search scope limits */
-static Lisp_Object Qbase, Qonelevel, Qsubtree;
+extern Lisp_Object Qbase, Qonelevel, Qsubtree;
 /* Authentication methods */
-static Lisp_Object Qkrbv41, Qkrbv42;
+extern Lisp_Object Qkrbv41, Qkrbv42;
 /* Deref policy */
-static Lisp_Object Qnever, Qalways, Qfind;
-/* Modification types (Qdelete is defined in general.c) */
-static Lisp_Object Qadd, Qreplace;
-
+extern Lisp_Object Qnever, Qalways, Qfind;
 
 /************************************************************************/
 /*                         Utility Functions                            */
 /************************************************************************/
 
 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)));
 }
 
 
@@ -92,7 +87,7 @@
 /************************************************************************/
 
 static Lisp_Object
-make_ldap (Lisp_LDAP *ldap)
+make_ldap (struct Lisp_LDAP *ldap)
 {
   Lisp_Object lisp_ldap;
   XSETLDAP (lisp_ldap, ldap);
@@ -100,7 +95,7 @@
 }
 
 static Lisp_Object
-mark_ldap (Lisp_Object obj)
+mark_ldap (Lisp_Object obj, void (*markobj) (Lisp_Object))
 {
   return XLDAP (obj)->host;
 }
@@ -110,7 +105,7 @@
 {
   char buf[32];
 
-  Lisp_LDAP *ldap = XLDAP (obj);
+  struct Lisp_LDAP *ldap = XLDAP (obj);
 
   if (print_readably)
     error ("printing unreadable object #<ldap %s>",
@@ -118,39 +113,40 @@
 
   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);
 }
 
-static Lisp_LDAP *
+static struct Lisp_LDAP *
 allocate_ldap (void)
 {
-  Lisp_LDAP *ldap = alloc_lcrecord_type (Lisp_LDAP, &lrecord_ldap);
+  struct Lisp_LDAP *ldap =
+    alloc_lcrecord_type (struct Lisp_LDAP, &lrecord_ldap);
 
   ldap->ld = NULL;
   ldap->host = Qnil;
+  ldap->livep = 0;
   return ldap;
 }
 
 static void
 finalize_ldap (void *header, int for_disksave)
 {
-  Lisp_LDAP *ldap = (Lisp_LDAP *) header;
+  struct Lisp_LDAP *ldap = (struct Lisp_LDAP *) header;
 
   if (for_disksave)
     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,
                                mark_ldap, print_ldap, finalize_ldap,
-                               NULL, NULL, 0, Lisp_LDAP);
+                               NULL, NULL, struct Lisp_LDAP);
 
 
 
@@ -182,7 +178,7 @@
        (ldap))
 {
   CHECK_LDAP (ldap);
-  return (XLDAP (ldap))->ld ? Qt : Qnil;
+  return (XLDAP (ldap))->livep ? Qt : Qnil;
 }
 
 /************************************************************************/
@@ -207,7 +203,7 @@
        (host, plist))
 {
   /* This function can GC */
-  Lisp_LDAP *ldap;
+  struct Lisp_LDAP *ldap;
   LDAP *ld;
   int  ldap_port = 0;
   int  ldap_auth = LDAP_AUTH_SIMPLE;
@@ -250,17 +246,13 @@
       else if (EQ (keyword, Qbinddn))
         {
           CHECK_STRING (value);
-	  TO_EXTERNAL_FORMAT (LISP_STRING, value,
-			      C_STRING_ALLOCA, ldap_binddn,
-			      Qnative);
+          GET_C_STRING_OS_DATA_ALLOCA (value, ldap_binddn);
         }
       /* Password */
       else if (EQ (keyword, Qpasswd))
         {
           CHECK_STRING (value);
-	  TO_EXTERNAL_FORMAT (LISP_STRING, value,
-			      C_STRING_ALLOCA, ldap_passwd,
-			      Qnative);
+          GET_C_STRING_OS_DATA_ALLOCA (value, ldap_passwd);
         }
       /* Deref */
       else if (EQ (keyword, Qderef))
@@ -307,21 +299,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;
@@ -331,11 +318,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)));
@@ -343,6 +331,7 @@
   ldap = allocate_ldap ();
   ldap->ld = ld;
   ldap->host = host;
+  ldap->livep = 1;
 
   return make_ldap (ldap);
 }
@@ -354,11 +343,11 @@
 */
       (ldap))
 {
-  Lisp_LDAP *lldap;
+  struct Lisp_LDAP *lldap;
   CHECK_LIVE_LDAP (ldap);
   lldap = XLDAP (ldap);
   ldap_unbind (lldap->ld);
-  lldap->ld = NULL;
+  lldap->livep = 0;
   return Qnil;
 }
 
@@ -373,6 +362,7 @@
   struct berval **vals;
 };
 
+
 static Lisp_Object
 ldap_search_unwind (Lisp_Object unwind_obj)
 {
@@ -385,12 +375,7 @@
   return Qnil;
 }
 
-/* The following function is called `ldap-search-basic' instead of      */
-/* plain `ldap-search' to maintain compatibility with the XEmacs 21.1   */
-/* API where `ldap-search' was the name of the high-level search        */
-/* function                                                             */
-
-DEFUN ("ldap-search-basic", Fldap_search_basic, 2, 8, 0, /*
+DEFUN ("ldap-search-internal", Fldap_search_internal, 2, 7, 0, /*
 Perform a search on an open LDAP connection.
 LDAP is an LDAP connection object created with `ldap-open'.
 FILTER is a filter string for the search as described in RFC 1558.
@@ -401,14 +386,13 @@
  for each matching entry. If nil return all available attributes.
 If ATTRSONLY is non-nil then only the attributes are retrieved, not
 the associated values.
-If WITHDN is non-nil each entry in the result will be prepended with
+If WITHDN is non-nil each entry in the result will be prepennded with
 its distinguished name DN.
-If VERBOSE is non-nil progress messages will be echoed.
 The function returns a list of matching entries.  Each entry is itself
 an alist of attribute/value pairs optionally preceded by the DN of the
 entry according to the value of WITHDN.
 */
-       (ldap, filter, base, scope, attrs, attrsonly, withdn, verbose))
+       (ldap, filter, base, scope, attrs, attrsonly, withdn))
 {
   /* This function can GC */
 
@@ -426,11 +410,10 @@
 
   int speccount = specpdl_depth ();
 
-  Lisp_Object list   = Qnil;
-  Lisp_Object entry  = Qnil;
-  Lisp_Object result = Qnil;
+  Lisp_Object list, entry, result;
   struct gcpro gcpro1, gcpro2, gcpro3;
 
+  list = entry = result = Qnil;
   GCPRO3 (list, entry, result);
 
   unwind.res = NULL;
@@ -477,9 +460,7 @@
 	{
 	  Lisp_Object current = XCAR (attrs);
 	  CHECK_STRING (current);
-	  TO_EXTERNAL_FORMAT (LISP_STRING, current,
-			      C_STRING_ALLOCA, ldap_attributes[i],
-			      Qnative);
+          GET_C_STRING_OS_DATA_ALLOCA (current, ldap_attributes[i]);
 	  ++i;
 	}
       ldap_attributes[i] = NULL;
@@ -490,14 +471,14 @@
 
   /* Perform the search */
   if (ldap_search (ld,
-                   NILP (base) ? (char *) "" : (char *) XSTRING_DATA (base),
+                   NILP (base) ? "" : (char *) XSTRING_DATA (base),
                    ldap_scope,
-                   NILP (filter) ? (char *) "" : (char *) XSTRING_DATA (filter),
+                   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 */
@@ -507,8 +488,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;
@@ -518,30 +501,31 @@
          destroys the current echo area contents, even when invoked
          from Lisp.  It should use echo_area_message() instead, and
          restore the old echo area contents later.  */
-      if (! NILP (verbose))
-        message ("Parsing ldap results... %d", matches);
+      message ("Parsing ldap results... %d", matches);
       entry = Qnil;
       /* Get the DN if required */
       if (! NILP (withdn))
         {
           dn = ldap_get_dn (ld, e);
           if (dn == NULL)
-            signal_ldap_error (ld, e, 0);
-          entry = Fcons (build_ext_string (dn, Qnative), Qnil);
+            {
+              signal_ldap_error (ld);
+            }
+          entry = Fcons (build_ext_string (dn, FORMAT_OS), Qnil);
         }
       for (a= ldap_first_attribute (ld, e, &ptr);
            a != NULL;
            a = ldap_next_attribute (ld, e, ptr) )
         {
-          list = Fcons (build_ext_string (a, Qnative), Qnil);
+          list = Fcons (build_ext_string (a, FORMAT_OS), Qnil);
           unwind.vals = ldap_get_values_len (ld, e, a);
           if (unwind.vals != NULL)
             {
               for (i = 0; unwind.vals[i] != NULL; i++)
                 {
-                  list = Fcons (make_ext_string ((Extbyte *) unwind.vals[i]->bv_val,
+                  list = Fcons (make_ext_string (unwind.vals[i]->bv_val,
                                                  unwind.vals[i]->bv_len,
-                                                 Qnative),
+                                                 FORMAT_OS),
                                 list);
                 }
             }
@@ -555,285 +539,43 @@
       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
-  {
-    int 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().  */
-  if (! NILP (verbose))
-    message ("Parsing ldap results... done");
+  message ("Parsing ldap results... done");
 
   unbind_to (speccount, Qnil);
   UNGCPRO;
   return Fnreverse (result);
 }
 
-DEFUN ("ldap-add", Fldap_add, 3, 3, 0, /*
-Add an entry to an LDAP directory.
-LDAP is an LDAP connection object created with `ldap-open'.
-DN is the distinguished name of the entry to add.
-ENTRY is an entry specification, i.e., a list of cons cells
-containing attribute/value string pairs.
-*/
-       (ldap, dn, entry))
-{
-  LDAP *ld;
-  LDAPMod *ldap_mods, **ldap_mods_ptrs;
-  struct berval *bervals;
-  int rc;
-  int i, j;
-  size_t len;
-
-  Lisp_Object current = Qnil;
-  Lisp_Object values  = Qnil;
-  struct gcpro gcpro1, gcpro2;
-
-  GCPRO2 (current, values);
-
-  /* Do all the parameter checking  */
-  CHECK_LIVE_LDAP (ldap);
-  ld = XLDAP (ldap)->ld;
-
-  /* Check the DN */
-  CHECK_STRING (dn);
-
-  /* Check the entry */
-  CHECK_CONS (entry);
-  if (NILP (entry))
-    signal_simple_error ("Cannot add void entry", entry);
-
-  /* Build the ldap_mods array */
-  len = XINT (Flength (entry));
-  ldap_mods = alloca_array (LDAPMod, len);
-  ldap_mods_ptrs = alloca_array (LDAPMod *, 1 + len);
-  i = 0;
-  EXTERNAL_LIST_LOOP (entry, entry)
-    {
-      current = XCAR (entry);
-      CHECK_CONS (current);
-      CHECK_STRING (XCAR (current));
-      ldap_mods_ptrs[i] = &(ldap_mods[i]);
-      TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (current),
-			  C_STRING_ALLOCA, ldap_mods[i].mod_type,
-			  Qnative);
-      ldap_mods[i].mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
-      values = XCDR (current);
-      if (CONSP (values))
-        {
-	  len = XINT (Flength (values));
-          bervals = alloca_array (struct berval, len);
-          ldap_mods[i].mod_vals.modv_bvals =
-            alloca_array (struct berval *, 1 + len);
-          j = 0;
-          EXTERNAL_LIST_LOOP (values, values)
-            {
-              current = XCAR (values);
-              CHECK_STRING (current);
-              ldap_mods[i].mod_vals.modv_bvals[j] = &(bervals[j]);
-	      TO_EXTERNAL_FORMAT (LISP_STRING, current,
-				  ALLOCA, (bervals[j].bv_val,
-					   bervals[j].bv_len),
-				  Qnative);
-              j++;
-            }
-          ldap_mods[i].mod_vals.modv_bvals[j] = NULL;
-        }
-      else
-        {
-          CHECK_STRING (values);
-          bervals = alloca_array (struct berval, 1);
-          ldap_mods[i].mod_vals.modv_bvals = alloca_array (struct berval *, 2);
-          ldap_mods[i].mod_vals.modv_bvals[0] = &(bervals[0]);
-	  TO_EXTERNAL_FORMAT (LISP_STRING, values,
-			      ALLOCA, (bervals[0].bv_val,
-				       bervals[0].bv_len),
-			      Qnative);
-          ldap_mods[i].mod_vals.modv_bvals[1] = NULL;
-        }
-      i++;
-    }
-  ldap_mods_ptrs[i] = NULL;
-  rc = ldap_add_s (ld, (char *) XSTRING_DATA (dn), ldap_mods_ptrs);
-  if (rc != LDAP_SUCCESS)
-    signal_ldap_error (ld, NULL, rc);
-
-  UNGCPRO;
-  return Qnil;
-}
-
-DEFUN ("ldap-modify", Fldap_modify, 3, 3, 0, /*
-Add an entry to an LDAP directory.
-LDAP is an LDAP connection object created with `ldap-open'.
-DN is the distinguished name of the entry to modify.
-MODS is a list of modifications to apply.
-A modification is a list of the form (MOD-OP ATTR VALUE1 VALUE2 ...)
-MOD-OP and ATTR are mandatory, VALUEs are optional depending on MOD-OP.
-MOD-OP is the type of modification, one of the symbols `add', `delete'
-or `replace'. ATTR is the LDAP attribute type to modify.
-*/
-       (ldap, dn, mods))
-{
-  LDAP *ld;
-  LDAPMod *ldap_mods, **ldap_mods_ptrs;
-  struct berval *bervals;
-  int i, j, rc;
-  Lisp_Object mod_op;
-  size_t len;
-
-  Lisp_Object current = Qnil;
-  Lisp_Object values  = Qnil;
-  struct gcpro gcpro1, gcpro2;
-
-  GCPRO2 (current, values);
-
-  /* Do all the parameter checking  */
-  CHECK_LIVE_LDAP (ldap);
-  ld = XLDAP (ldap)->ld;
-
-  /* Check the DN */
-  CHECK_STRING (dn);
-
-  /* Check the entry */
-  CHECK_CONS (mods);
-  if (NILP (mods))
-    return Qnil;
-
-  /* Build the ldap_mods array */
-  len = XINT (Flength (mods));
-  ldap_mods = alloca_array (LDAPMod, len);
-  ldap_mods_ptrs = alloca_array (LDAPMod *, 1 + len);
-  i = 0;
-  EXTERNAL_LIST_LOOP (mods, mods)
-    {
-      current = XCAR (mods);
-      CHECK_CONS (current);
-      CHECK_SYMBOL (XCAR (current));
-      mod_op = XCAR (current);
-      ldap_mods_ptrs[i] = &(ldap_mods[i]);
-      ldap_mods[i].mod_op = LDAP_MOD_BVALUES;
-      if (EQ (mod_op, Qadd))
-        ldap_mods[i].mod_op |= LDAP_MOD_ADD;
-      else if (EQ (mod_op, Qdelete))
-        ldap_mods[i].mod_op |= LDAP_MOD_DELETE;
-      else if (EQ (mod_op, Qreplace))
-        ldap_mods[i].mod_op |= LDAP_MOD_REPLACE;
-      else
-        signal_simple_error ("Invalid LDAP modification type", mod_op);
-      current = XCDR (current);
-      CHECK_STRING (XCAR (current));
-      TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (current),
-			  C_STRING_ALLOCA, ldap_mods[i].mod_type,
-			  Qnative);
-      values = XCDR (current);
-      len = XINT (Flength (values));
-      bervals = alloca_array (struct berval, len);
-      ldap_mods[i].mod_vals.modv_bvals =
-        alloca_array (struct berval *, 1 + len);
-      j = 0;
-      EXTERNAL_LIST_LOOP (values, values)
-        {
-          current = XCAR (values);
-          CHECK_STRING (current);
-          ldap_mods[i].mod_vals.modv_bvals[j] = &(bervals[j]);
-	  TO_EXTERNAL_FORMAT (LISP_STRING, current,
-			      ALLOCA, (bervals[j].bv_val,
-				       bervals[j].bv_len),
-			      Qnative);
-          j++;
-        }
-      ldap_mods[i].mod_vals.modv_bvals[j] = NULL;
-      i++;
-    }
-  ldap_mods_ptrs[i] = NULL;
-  rc = ldap_modify_s (ld, (char *) XSTRING_DATA (dn), ldap_mods_ptrs);
-  if (rc != LDAP_SUCCESS)
-    signal_ldap_error (ld, NULL, rc);
-
-  UNGCPRO;
-  return Qnil;
-}
-
-
-DEFUN ("ldap-delete", Fldap_delete, 2, 2, 0, /*
-Delete an entry to an LDAP directory.
-LDAP is an LDAP connection object created with `ldap-open'.
-DN is the distinguished name of the entry to delete.
-*/
-       (ldap, dn))
-{
-  LDAP *ld;
-  int rc;
-
-  /* Check parameters */
-  CHECK_LIVE_LDAP (ldap);
-  ld = XLDAP (ldap)->ld;
-  CHECK_STRING (dn);
-
-  rc = ldap_delete_s (ld, (char *) XSTRING_DATA (dn));
-  if (rc != LDAP_SUCCESS)
-    signal_ldap_error (ld, NULL, rc);
-
-  return Qnil;
-}
 
 void
 syms_of_eldap (void)
 {
-  INIT_LRECORD_IMPLEMENTATION (ldap);
-
   defsymbol (&Qldapp, "ldapp");
-  defsymbol (&Qport, "port");
-  defsymbol (&Qauth, "auth");
-  defsymbol (&Qbinddn, "binddn");
-  defsymbol (&Qpasswd, "passwd");
-  defsymbol (&Qderef, "deref");
-  defsymbol (&Qtimelimit, "timelimit");
-  defsymbol (&Qsizelimit, "sizelimit");
-  defsymbol (&Qbase, "base");
-  defsymbol (&Qonelevel, "onelevel");
-  defsymbol (&Qsubtree, "subtree");
-  defsymbol (&Qkrbv41, "krbv41");
-  defsymbol (&Qkrbv42, "krbv42");
-  defsymbol (&Qnever, "never");
-  defsymbol (&Qalways, "always");
-  defsymbol (&Qfind, "find");
-  defsymbol (&Qadd, "add");
-  defsymbol (&Qreplace, "replace");
-
   DEFSUBR (Fldapp);
   DEFSUBR (Fldap_host);
   DEFSUBR (Fldap_status);
   DEFSUBR (Fldap_open);
   DEFSUBR (Fldap_close);
-  DEFSUBR (Fldap_search_basic);
-  DEFSUBR (Fldap_add);
-  DEFSUBR (Fldap_modify);
-  DEFSUBR (Fldap_delete);
+  DEFSUBR (Fldap_search_internal);
 }
 
 void