Patch to move functions directly from pdb_ldap.c into lib/smbldap.c
authorAndrew Bartlett <abartlet@samba.org>
Wed, 25 Jun 2003 12:51:58 +0000 (12:51 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 25 Jun 2003 12:51:58 +0000 (12:51 +0000)
The functions are unchanged.  Next step is to make idmap_ldap use them.

Andrew Bartlett

source/Makefile.in
source/include/smbldap.h
source/lib/smbldap.c
source/passdb/pdb_ldap.c

index 7cf07c15b44c54df889dc834520627fb0eb3bad5..c96a87ebc7586978527bffb7ce25315e3e2e8cad 100644 (file)
@@ -562,7 +562,7 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \
            $(LIB_SMBD_OBJ) $(SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
            $(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) \
            $(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ) \
-           $(IDMAP_OBJ) $(RPC_ECHO_OBJ) 
+           $(IDMAP_OBJ) $(RPC_ECHO_OBJ) $(SMBLDAP_OBJ)
 
 WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) \
        $(LIBSMB_OBJ) $(LIB_OBJ) $(NSSWINS_OBJ)
index 31f8d33b88c96dd649bfc57b696b2248fe3ae1b9..5f3606aa32c649062defdacd50d2f5edb8a98eb8 100644 (file)
    
 */
 
-#ifdef HAVE_LDAP
-
 #ifndef _SMBLDAP_H
 #define _SMBLDAP_H
 
+#ifdef HAVE_LDAP
+
 /* specify schema versions between 2.2. and 3.0 */
 
 #define SCHEMAVER_SAMBAACCOUNT         1
@@ -93,17 +93,6 @@ typedef struct _attrib_map_entry {
 } ATTRIB_MAP_ENTRY;
 
 
-struct smbldap_state {
-       LDAP *ldap_struct;
-       time_t last_ping;
-       /* retrive-once info */
-       const char *uri;
-       char *bind_dn;
-       char *bind_secret;
-
-       unsigned int num_failures;
-};
-
 /* structures */
 
 extern ATTRIB_MAP_ENTRY attrib_map_v22[];
@@ -120,9 +109,30 @@ extern ATTRIB_MAP_ENTRY sidmap_attr_list[];
 const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key );
 char** get_attr_list( ATTRIB_MAP_ENTRY table[] );
 void free_attr_list( char **list );
-BOOL fetch_ldap_pw(char **dn, char** pw);
 void smbldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value);
+void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing,
+                     LDAPMod ***mods,
+                     const char *attribute, const char *newval);
 
-#endif /* _SMBLDAP_H */
+/**
+ * Struct to keep the state for all the ldap stuff 
+ *
+ */
+
+struct smbldap_state {
+       LDAP *ldap_struct;
+       time_t last_ping;
+       /* retrive-once info */
+       const char *uri;
+       char *bind_dn;
+       char *bind_secret;
+
+       unsigned int num_failures;
+};
 
 #endif         /* HAVE_LDAP */
+
+struct smbldap_state;
+
+#endif /* _SMBLDAP_H */
+
index b627134446308fb1dbe4daa95edc44038030bd0e..84017873177311606d757257f840f97fc4f24bdd 100644 (file)
@@ -1,7 +1,11 @@
 /* 
    Unix SMB/CIFS mplementation.
    LDAP protocol helper functions for SAMBA
+   Copyright (C) Jean François Micouleau       1998
    Copyright (C) Gerald Carter                 2001-2003
+   Copyright (C) Shahms King                   2001
+   Copyright (C) Andrew Bartlett               2002-2003
+   Copyright (C) Stefan (metze) Metzmacher     2002
     
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #include "includes.h"
 #include "smbldap.h"
 
+#ifndef LDAP_OPT_SUCCESS
+#define LDAP_OPT_SUCCESS 0
+#endif
+
+/* Try not to hit the up or down server forever */
+
+#define SMBLDAP_DONT_PING_TIME 10      /* ping only all 10 seconds */
+#define SMBLDAP_NUM_RETRIES 8          /* retry only 8 times */
+
+
 /* attributes used by Samba 2.2 */
 
 ATTRIB_MAP_ENTRY attrib_map_v22[] = {
@@ -133,7 +147,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
  perform a simple table lookup and return the attribute name 
  **********************************************************************/
  
-const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
+ const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
 {
        int i = 0;
        
@@ -151,7 +165,7 @@ const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
  Return the list of attribute names from a mapping table
  **********************************************************************/
 
-char** get_attr_list( ATTRIB_MAP_ENTRY table[] )
+ char** get_attr_list( ATTRIB_MAP_ENTRY table[] )
 {
        char **names;
        int i = 0;
@@ -180,7 +194,7 @@ char** get_attr_list( ATTRIB_MAP_ENTRY table[] )
  Cleanup 
  ********************************************************************/
 
-void free_attr_list( char **list )
+ void free_attr_list( char **list )
 {
        int i = 0;
 
@@ -262,7 +276,7 @@ BOOL fetch_ldap_pw(char **dn, char** pw)
  manage memory used by the array, by each struct, and values
  ***********************************************************************/
 
-void smbldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
+ void smbldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
 {
        LDAPMod **mods;
        int i;
@@ -345,3 +359,714 @@ void smbldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, con
 }
 
 
+/**********************************************************************
+  Set attribute to newval in LDAP, regardless of what value the
+  attribute had in LDAP before.
+*********************************************************************/
+ void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing,
+                     LDAPMod ***mods,
+                     const char *attribute, const char *newval)
+{
+       char **values = NULL;
+
+       if (existing != NULL) {
+               values = ldap_get_values(ldap_struct, existing, attribute);
+       }
+
+       /* all of our string attributes are case insensitive */
+       
+       if ((values != NULL) && (values[0] != NULL) &&
+           StrCaseCmp(values[0], newval) == 0) 
+       {
+               
+               /* Believe it or not, but LDAP will deny a delete and
+                  an add at the same time if the values are the
+                  same... */
+
+               ldap_value_free(values);
+               return;
+       }
+
+       /* Regardless of the real operation (add or modify)
+          we add the new value here. We rely on deleting
+          the old value, should it exist. */
+
+       if ((newval != NULL) && (strlen(newval) > 0)) {
+               smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval);
+       }
+
+       if (values == NULL) {
+               /* There has been no value before, so don't delete it.
+                  Here's a possible race: We might end up with
+                  duplicate attributes */
+               return;
+       }
+
+       /* By deleting exactly the value we found in the entry this
+          should be race-free in the sense that the LDAP-Server will
+          deny the complete operation if somebody changed the
+          attribute behind our back. */
+
+       smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, values[0]);
+       ldap_value_free(values);
+}
+
+
+/**********************************************************************
+ Some varients of the LDAP rebind code do not pass in the third 'arg' 
+ pointer to a void*, so we try and work around it by assuming that the 
+ value of the 'LDAP *' pointer is the same as the one we had passed in
+ **********************************************************************/
+
+struct smbldap_state_lookup {
+       LDAP *ld;
+       struct smbldap_state *smbldap_state;
+       struct smbldap_state_lookup *prev, *next;
+};
+
+static struct smbldap_state_lookup *smbldap_state_lookup_list;
+
+static struct smbldap_state *smbldap_find_state(LDAP *ld) 
+{
+       struct smbldap_state_lookup *t;
+
+       for (t = smbldap_state_lookup_list; t; t = t->next) {
+               if (t->ld == ld) {
+                       return t->smbldap_state;
+               }
+       }
+       return NULL;
+}
+
+static void smbldap_delete_state(struct smbldap_state *smbldap_state) 
+{
+       struct smbldap_state_lookup *t;
+
+       for (t = smbldap_state_lookup_list; t; t = t->next) {
+               if (t->smbldap_state == smbldap_state) {
+                       DLIST_REMOVE(smbldap_state_lookup_list, t);
+                       SAFE_FREE(t);
+                       return;
+               }
+       }
+}
+
+static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state) 
+{
+       struct smbldap_state *tmp_ldap_state;
+       struct smbldap_state_lookup *t;
+       struct smbldap_state_lookup *tmp;
+       
+       if ((tmp_ldap_state = smbldap_find_state(ld))) {
+               SMB_ASSERT(tmp_ldap_state == smbldap_state);
+               return;
+       }
+
+       t = smb_xmalloc(sizeof(*t));
+       ZERO_STRUCTP(t);
+       
+       DLIST_ADD_END(smbldap_state_lookup_list, t, tmp);
+       t->ld = ld;
+       t->smbldap_state = smbldap_state;
+}
+
+/*******************************************************************
+ open a connection to the ldap server.
+******************************************************************/
+static int smbldap_open_connection (struct smbldap_state *ldap_state)
+
+{
+       int rc = LDAP_SUCCESS;
+       int version;
+       BOOL ldap_v3 = False;
+       LDAP **ldap_struct = &ldap_state->ldap_struct;
+
+#ifdef HAVE_LDAP_INITIALIZE
+       DEBUG(10, ("smbldap_open_connection: %s\n", ldap_state->uri));
+       
+       if ((rc = ldap_initialize(ldap_struct, ldap_state->uri)) != LDAP_SUCCESS) {
+               DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
+               return rc;
+       }
+#else 
+
+       /* Parse the string manually */
+
+       {
+               int port = 0;
+               fstring protocol;
+               fstring host;
+               const char *p = ldap_state->uri; 
+               SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
+               
+               /* skip leading "URL:" (if any) */
+               if ( strncasecmp( p, "URL:", 4 ) == 0 ) {
+                       p += 4;
+               }
+               
+               sscanf(p, "%10[^:]://%254s[^:]:%d", protocol, host, &port);
+               
+               if (port == 0) {
+                       if (strequal(protocol, "ldap")) {
+                               port = LDAP_PORT;
+                       } else if (strequal(protocol, "ldaps")) {
+                               port = LDAPS_PORT;
+                       } else {
+                               DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
+                       }
+               }
+               
+               if ((*ldap_struct = ldap_init(host, port)) == NULL)     {
+                       DEBUG(0, ("ldap_init failed !\n"));
+                       return LDAP_OPERATIONS_ERROR;
+               }
+               
+               if (strequal(protocol, "ldaps")) {
+#ifdef LDAP_OPT_X_TLS
+                       int tls = LDAP_OPT_X_TLS_HARD;
+                       if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
+                       {
+                               DEBUG(0, ("Failed to setup a TLS session\n"));
+                       }
+                       
+                       DEBUG(3,("LDAPS option set...!\n"));
+#else
+                       DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
+                       return LDAP_OPERATIONS_ERROR;
+#endif
+               }
+       }
+#endif
+
+       /* Store the LDAP pointer in a lookup list */
+
+       smbldap_store_state(*ldap_struct, ldap_state);
+
+       /* Upgrade to LDAPv3 if possible */
+
+       if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
+       {
+               if (version != LDAP_VERSION3)
+               {
+                       version = LDAP_VERSION3;
+                       if (ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) {
+                               ldap_v3 = True;
+                       }
+               } else {
+                       ldap_v3 = True;
+               }
+       }
+
+       if (lp_ldap_ssl() == LDAP_SSL_START_TLS) {
+#ifdef LDAP_OPT_X_TLS
+               if (ldap_v3) {
+                       if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
+                       {
+                               DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
+                                        ldap_err2string(rc)));
+                               return rc;
+                       }
+                       DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
+               } else {
+                       
+                       DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
+                       return LDAP_OPERATIONS_ERROR;
+               }
+#else
+               DEBUG(0,("smbldap_open_connection: StartTLS not supported by LDAP client libraries!\n"));
+               return LDAP_OPERATIONS_ERROR;
+#endif
+       }
+
+       DEBUG(2, ("smbldap_open_connection: connection opened\n"));
+       return rc;
+}
+
+
+/*******************************************************************
+ a rebind function for authenticated referrals
+ This version takes a void* that we can shove useful stuff in :-)
+******************************************************************/
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+#else
+static int rebindproc_with_state  (LDAP * ld, char **whop, char **credp, 
+                                  int *methodp, int freeit, void *arg)
+{
+       struct smbldap_state *ldap_state = arg;
+       
+       /** @TODO Should we be doing something to check what servers we rebind to?
+           Could we get a referral to a machine that we don't want to give our
+           username and password to? */
+       
+       if (freeit) {
+               SAFE_FREE(*whop);
+               memset(*credp, '\0', strlen(*credp));
+               SAFE_FREE(*credp);
+       } else {
+               DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n", 
+                         ldap_state->bind_dn));
+
+               *whop = strdup(ldap_state->bind_dn);
+               if (!*whop) {
+                       return LDAP_NO_MEMORY;
+               }
+               *credp = strdup(ldap_state->bind_secret);
+               if (!*credp) {
+                       SAFE_FREE(*whop);
+                       return LDAP_NO_MEMORY;
+               }
+               *methodp = LDAP_AUTH_SIMPLE;
+       }
+       return 0;
+}
+#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
+
+/*******************************************************************
+ a rebind function for authenticated referrals
+ This version takes a void* that we can shove useful stuff in :-)
+ and actually does the connection.
+******************************************************************/
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+static int rebindproc_connect_with_state (LDAP *ldap_struct, 
+                                         LDAP_CONST char *url, 
+                                         ber_tag_t request,
+                                         ber_int_t msgid, void *arg)
+{
+       struct smbldap_state *ldap_state = arg;
+       int rc;
+       DEBUG(5,("rebindproc_connect_with_state: Rebinding as \"%s\"\n", 
+                ldap_state->bind_dn));
+       
+       /** @TODO Should we be doing something to check what servers we rebind to?
+           Could we get a referral to a machine that we don't want to give our
+           username and password to? */
+
+       rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
+       
+       return rc;
+}
+#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
+
+/*******************************************************************
+ Add a rebind function for authenticated referrals
+******************************************************************/
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+#else
+# if LDAP_SET_REBIND_PROC_ARGS == 2
+static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
+                      int *method, int freeit )
+{
+       struct smbldap_state *ldap_state = smbldap_find_state(ldap_struct);
+
+       return rebindproc_with_state(ldap_struct, whop, credp,
+                                    method, freeit, ldap_state);
+       
+}
+# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
+#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
+
+/*******************************************************************
+ a rebind function for authenticated referrals
+ this also does the connection, but no void*.
+******************************************************************/
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+# if LDAP_SET_REBIND_PROC_ARGS == 2
+static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
+                              ber_int_t msgid)
+{
+       struct smbldap_state *ldap_state = smbldap_find_state(ld);
+
+       return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid, 
+                                            ldap_state);
+}
+# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
+#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
+
+/*******************************************************************
+ connect to the ldap server under system privilege.
+******************************************************************/
+static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_struct)
+{
+       int rc;
+       char *ldap_dn;
+       char *ldap_secret;
+
+       /* get the password */
+       if (!fetch_ldap_pw(&ldap_dn, &ldap_secret))
+       {
+               DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
+               return LDAP_INVALID_CREDENTIALS;
+       }
+
+       ldap_state->bind_dn = ldap_dn;
+       ldap_state->bind_secret = ldap_secret;
+
+       /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite 
+          (OpenLDAP) doesnt' seem to support it */
+          
+       DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
+                 ldap_state->uri, ldap_dn));
+
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+# if LDAP_SET_REBIND_PROC_ARGS == 2    
+       ldap_set_rebind_proc(ldap_struct, &rebindproc_connect); 
+# endif
+# if LDAP_SET_REBIND_PROC_ARGS == 3    
+       ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);  
+# endif
+#else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
+# if LDAP_SET_REBIND_PROC_ARGS == 2    
+       ldap_set_rebind_proc(ldap_struct, &rebindproc); 
+# endif
+# if LDAP_SET_REBIND_PROC_ARGS == 3    
+       ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);  
+# endif
+#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
+
+       rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
+
+       if (rc != LDAP_SUCCESS) {
+               char *ld_error = NULL;
+               ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
+                               &ld_error);
+               DEBUG(ldap_state->num_failures ? 2 : 0,
+                     ("failed to bind to server with dn= %s Error: %s\n\t%s\n",
+                              ldap_dn ? ldap_dn : "(unknown)", ldap_err2string(rc),
+                              ld_error ? ld_error : "(unknown)"));
+               SAFE_FREE(ld_error);
+               ldap_state->num_failures++;
+               return rc;
+       }
+
+       ldap_state->num_failures = 0;
+
+       DEBUG(3, ("ldap_connect_system: succesful connection to the LDAP server\n"));
+       return rc;
+}
+
+/**********************************************************************
+Connect to LDAP server (called before every ldap operation)
+*********************************************************************/
+static int smbldap_open(struct smbldap_state *ldap_state)
+{
+       int rc;
+       SMB_ASSERT(ldap_state);
+               
+#ifndef NO_LDAP_SECURITY
+       if (geteuid() != 0) {
+               DEBUG(0, ("smbldap_open: cannot access LDAP when not root..\n"));
+               return  LDAP_INSUFFICIENT_ACCESS;
+       }
+#endif
+
+               if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time(NULL))) {
+               struct sockaddr_un addr;
+               socklen_t len = sizeof(addr);
+               int sd;
+               if (ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd) == 0 &&
+                   getpeername(sd, (struct sockaddr *) &addr, &len) < 0) {
+                       /* the other end has died. reopen. */
+                       ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
+                       ldap_state->ldap_struct = NULL;
+                       ldap_state->last_ping = (time_t)0;
+               } else {
+                       ldap_state->last_ping = time(NULL);
+               } 
+       }
+
+       if (ldap_state->ldap_struct != NULL) {
+               DEBUG(5,("smbldap_open: already connected to the LDAP server\n"));
+               return LDAP_SUCCESS;
+       }
+
+       if ((rc = smbldap_open_connection(ldap_state))) {
+               return rc;
+       }
+
+       if ((rc = smbldap_connect_system(ldap_state, ldap_state->ldap_struct))) {
+               ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
+               ldap_state->ldap_struct = NULL;
+               return rc;
+       }
+
+
+       ldap_state->last_ping = time(NULL);
+       DEBUG(4,("The LDAP server is succesful connected\n"));
+
+       return LDAP_SUCCESS;
+}
+
+/**********************************************************************
+Disconnect from LDAP server 
+*********************************************************************/
+static NTSTATUS smbldap_close(struct smbldap_state *ldap_state)
+{
+       if (!ldap_state)
+               return NT_STATUS_INVALID_PARAMETER;
+               
+       if (ldap_state->ldap_struct != NULL) {
+               ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
+               ldap_state->ldap_struct = NULL;
+       }
+
+       smbldap_delete_state(ldap_state);
+       
+       DEBUG(5,("The connection to the LDAP server was closed\n"));
+       /* maybe free the results here --metze */
+       
+       
+
+       return NT_STATUS_OK;
+}
+
+static int smbldap_retry_open(struct smbldap_state *ldap_state, int *attempts)
+{
+       int rc;
+
+       SMB_ASSERT(ldap_state && attempts);
+               
+       if (*attempts != 0) {
+               unsigned int sleep_time;
+               uint8 rand_byte;
+
+               /* Sleep for a random timeout */
+               rand_byte = (char)(sys_random());
+
+               sleep_time = (((*attempts)*(*attempts))/2)*rand_byte*2; 
+               /* we retry after (0.5, 1, 2, 3, 4.5, 6) seconds
+                  on average.  
+                */
+               DEBUG(3, ("Sleeping for %u milliseconds before reconnecting\n", 
+                         sleep_time));
+               msleep(sleep_time);
+       }
+       (*attempts)++;
+
+       if ((rc = smbldap_open(ldap_state))) {
+               DEBUG(1,("Connection to LDAP Server failed for the %d try!\n",*attempts));
+               return rc;
+       } 
+       
+       return LDAP_SUCCESS;            
+}
+
+
+/*********************************************************************
+ ********************************************************************/
+
+int smbldap_search(struct smbldap_state *ldap_state, 
+                  const char *base, int scope, const char *filter, 
+                  char *attrs[], int attrsonly, 
+                  LDAPMessage **res)
+{
+       int             rc = LDAP_SERVER_DOWN;
+       int             attempts = 0;
+       char           *utf8_filter;
+
+       SMB_ASSERT(ldap_state);
+
+       if (push_utf8_allocate(&utf8_filter, filter) == (size_t)-1) {
+               return LDAP_NO_MEMORY;
+       }
+
+       while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
+               
+               if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
+                       continue;
+               
+               rc = ldap_search_s(ldap_state->ldap_struct, base, scope, 
+                                  utf8_filter, attrs, attrsonly, res);
+       }
+       
+       if (rc == LDAP_SERVER_DOWN) {
+               DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
+               smbldap_close(ldap_state);      
+       }
+
+       SAFE_FREE(utf8_filter);
+       return rc;
+}
+
+int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
+{
+       int             rc = LDAP_SERVER_DOWN;
+       int             attempts = 0;
+       char           *utf8_dn;
+
+       SMB_ASSERT(ldap_state);
+
+       if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
+               return LDAP_NO_MEMORY;
+       }
+
+       while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
+               
+               if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
+                       continue;
+               
+               rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs);
+       }
+       
+       if (rc == LDAP_SERVER_DOWN) {
+               DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
+               smbldap_close(ldap_state);      
+       }
+       
+       SAFE_FREE(utf8_dn);
+       return rc;
+}
+
+int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
+{
+       int             rc = LDAP_SERVER_DOWN;
+       int             attempts = 0;
+       char           *utf8_dn;
+       
+       SMB_ASSERT(ldap_state);
+
+       if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
+               return LDAP_NO_MEMORY;
+       }
+
+       while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
+               
+               if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
+                       continue;
+               
+               rc = ldap_add_s(ldap_state->ldap_struct, utf8_dn, attrs);
+       }
+       
+       if (rc == LDAP_SERVER_DOWN) {
+               DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
+               smbldap_close(ldap_state);      
+       }
+               
+       SAFE_FREE(utf8_dn);
+       return rc;
+}
+
+int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
+{
+       int             rc = LDAP_SERVER_DOWN;
+       int             attempts = 0;
+       char           *utf8_dn;
+       
+       SMB_ASSERT(ldap_state);
+
+       if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
+               return LDAP_NO_MEMORY;
+       }
+
+       while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
+               
+               if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
+                       continue;
+               
+               rc = ldap_delete_s(ldap_state->ldap_struct, utf8_dn);
+       }
+       
+       if (rc == LDAP_SERVER_DOWN) {
+               DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
+               smbldap_close(ldap_state);      
+       }
+               
+       SAFE_FREE(utf8_dn);
+       return rc;
+}
+
+int smbldap_extended_operation(struct smbldap_state *ldap_state, 
+                              LDAP_CONST char *reqoid, struct berval *reqdata, 
+                              LDAPControl **serverctrls, LDAPControl **clientctrls, 
+                              char **retoidp, struct berval **retdatap)
+{
+       int             rc = LDAP_SERVER_DOWN;
+       int             attempts = 0;
+       
+       if (!ldap_state)
+               return (-1);
+
+       while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
+               
+               if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
+                       continue;
+               
+               rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata, 
+                                              serverctrls, clientctrls, retoidp, retdatap);
+       }
+       
+       if (rc == LDAP_SERVER_DOWN) {
+               DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
+               smbldap_close(ldap_state);      
+       }
+               
+       return rc;
+}
+
+/*******************************************************************
+ run the search by name.
+******************************************************************/
+int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter, 
+                          char **search_attr, LDAPMessage ** result)
+{
+       int scope = LDAP_SCOPE_SUBTREE;
+       int rc;
+
+       DEBUG(2, ("smbldap_search_suffix: searching for:[%s]\n", filter));
+
+       rc = smbldap_search(ldap_state, lp_ldap_suffix(), scope, filter, search_attr, 0, result);
+
+       if (rc != LDAP_SUCCESS) {
+               char *ld_error = NULL;
+               ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
+                               &ld_error);
+               DEBUG(0,("smbldap_search_suffix: Problem during the LDAP search: %s (%s)\n", 
+                       ld_error?ld_error:"(unknown)", ldap_err2string (rc)));
+               DEBUG(3,("smbldap_search_suffix: Query was: %s, %s\n", lp_ldap_suffix(), 
+                       filter));
+               SAFE_FREE(ld_error);
+       }
+       
+       return rc;
+}
+
+/**********************************************************************
+ Housekeeping
+ *********************************************************************/
+
+void smbldap_free_struct(struct smbldap_state **ldap_state) 
+{
+       smbldap_close(*ldap_state);
+       
+       if ((*ldap_state)->bind_secret) {
+               memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
+       }
+
+       SAFE_FREE((*ldap_state)->bind_dn);
+       SAFE_FREE((*ldap_state)->bind_secret);
+
+       *ldap_state = NULL;
+
+       /* No need to free any further, as it is talloc()ed */
+}
+
+
+/**********************************************************************
+ Intitalise the 'general' ldap structures, on which ldap operations may be conducted
+ *********************************************************************/
+
+NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_state **smbldap_state) 
+{
+       *smbldap_state = talloc_zero(mem_ctx, sizeof(**smbldap_state));
+       if (!*smbldap_state) {
+               DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (location) {
+               (*smbldap_state)->uri = talloc_strdup(mem_ctx, location);
+       } else {
+               (*smbldap_state)->uri = "ldap://localhost";
+       }
+       return NT_STATUS_OK;
+}
+
index 1149a92a997923fe134cd777d730b12051ced5cb..ec164a7e7be4f8ce411c85e44ef4d0bf248ab9af 100644 (file)
@@ -4,7 +4,7 @@
    Copyright (C) Jean François Micouleau       1998
    Copyright (C) Gerald Carter                 2001-2003
    Copyright (C) Shahms King                   2001
-   Copyright (C) Andrew Bartlett               2002
+   Copyright (C) Andrew Bartlett               2002-2003
    Copyright (C) Stefan (metze) Metzmacher     2002
     
    This program is free software; you can redistribute it and/or modify
 #include <lber.h>
 #include <ldap.h>
 
-#ifndef LDAP_OPT_SUCCESS
-#define LDAP_OPT_SUCCESS 0
-#endif
+/*
+ * Work around versions of the LDAP client libs that don't have the OIDs
+ * defined, or have them defined under the old name.  
+ * This functionality is really a factor of the server, not the client 
+ *
+ */
 
 #if defined(LDAP_EXOP_X_MODIFY_PASSWD) && !defined(LDAP_EXOP_MODIFY_PASSWD)
 #define LDAP_EXOP_MODIFY_PASSWD LDAP_EXOP_X_MODIFY_PASSWD
@@ -73,6 +76,7 @@
 #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW       ((ber_tag_t) 0x82U)
 #endif
 
+
 #ifndef SAM_ACCOUNT
 #define SAM_ACCOUNT struct sam_passwd
 #endif
@@ -103,9 +107,6 @@ struct ldapsam_privates {
 
 };
 
-#define SMBLDAP_DONT_PING_TIME 10      /* ping only all 10 seconds */
-#define SMBLDAP_NUM_RETRIES 8          /* retry only 8 times */
-
 /**********************************************************************
  get the attribute name given a user schame version 
  **********************************************************************/
@@ -147,624 +148,6 @@ static char** get_userattr_list( int schema_ver )
        
        return NULL;
 }
-
-/**********************************************************************
- Some varients of the LDAP rebind code do not pass in the third 'arg' 
- pointer to a void*, so we try and work around it by assuming that the 
- value of the 'LDAP *' pointer is the same as the one we had passed in
- **********************************************************************/
-
-struct smbldap_state_lookup {
-       LDAP *ld;
-       struct smbldap_state *smbldap_state;
-       struct smbldap_state_lookup *prev, *next;
-};
-
-static struct smbldap_state_lookup *smbldap_state_lookup_list;
-
-static struct smbldap_state *smbldap_find_state(LDAP *ld) 
-{
-       struct smbldap_state_lookup *t;
-
-       for (t = smbldap_state_lookup_list; t; t = t->next) {
-               if (t->ld == ld) {
-                       return t->smbldap_state;
-               }
-       }
-       return NULL;
-}
-
-static void smbldap_delete_state(struct smbldap_state *smbldap_state) 
-{
-       struct smbldap_state_lookup *t;
-
-       for (t = smbldap_state_lookup_list; t; t = t->next) {
-               if (t->smbldap_state == smbldap_state) {
-                       DLIST_REMOVE(smbldap_state_lookup_list, t);
-                       SAFE_FREE(t);
-                       return;
-               }
-       }
-}
-
-static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state) 
-{
-       struct smbldap_state *tmp_ldap_state;
-       struct smbldap_state_lookup *t;
-       struct smbldap_state_lookup *tmp;
-       
-       if ((tmp_ldap_state = smbldap_find_state(ld))) {
-               SMB_ASSERT(tmp_ldap_state == smbldap_state);
-               return;
-       }
-
-       t = smb_xmalloc(sizeof(*t));
-       ZERO_STRUCTP(t);
-       
-       DLIST_ADD_END(smbldap_state_lookup_list, t, tmp);
-       t->ld = ld;
-       t->smbldap_state = smbldap_state;
-}
-
-/*******************************************************************
- open a connection to the ldap server.
-******************************************************************/
-static int smbldap_open_connection (struct smbldap_state *ldap_state)
-
-{
-       int rc = LDAP_SUCCESS;
-       int version;
-       BOOL ldap_v3 = False;
-       LDAP **ldap_struct = &ldap_state->ldap_struct;
-
-#ifdef HAVE_LDAP_INITIALIZE
-       DEBUG(10, ("smbldap_open_connection: %s\n", ldap_state->uri));
-       
-       if ((rc = ldap_initialize(ldap_struct, ldap_state->uri)) != LDAP_SUCCESS) {
-               DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
-               return rc;
-       }
-#else 
-
-       /* Parse the string manually */
-
-       {
-               int port = 0;
-               fstring protocol;
-               fstring host;
-               const char *p = ldap_state->uri; 
-               SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
-               
-               /* skip leading "URL:" (if any) */
-               if ( strncasecmp( p, "URL:", 4 ) == 0 ) {
-                       p += 4;
-               }
-               
-               sscanf(p, "%10[^:]://%254s[^:]:%d", protocol, host, &port);
-               
-               if (port == 0) {
-                       if (strequal(protocol, "ldap")) {
-                               port = LDAP_PORT;
-                       } else if (strequal(protocol, "ldaps")) {
-                               port = LDAPS_PORT;
-                       } else {
-                               DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
-                       }
-               }
-               
-               if ((*ldap_struct = ldap_init(host, port)) == NULL)     {
-                       DEBUG(0, ("ldap_init failed !\n"));
-                       return LDAP_OPERATIONS_ERROR;
-               }
-               
-               if (strequal(protocol, "ldaps")) {
-#ifdef LDAP_OPT_X_TLS
-                       int tls = LDAP_OPT_X_TLS_HARD;
-                       if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
-                       {
-                               DEBUG(0, ("Failed to setup a TLS session\n"));
-                       }
-                       
-                       DEBUG(3,("LDAPS option set...!\n"));
-#else
-                       DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
-                       return LDAP_OPERATIONS_ERROR;
-#endif
-               }
-       }
-#endif
-
-       /* Store the LDAP pointer in a lookup list */
-
-       smbldap_store_state(*ldap_struct, ldap_state);
-
-       /* Upgrade to LDAPv3 if possible */
-
-       if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
-       {
-               if (version != LDAP_VERSION3)
-               {
-                       version = LDAP_VERSION3;
-                       if (ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) {
-                               ldap_v3 = True;
-                       }
-               } else {
-                       ldap_v3 = True;
-               }
-       }
-
-       if (lp_ldap_ssl() == LDAP_SSL_START_TLS) {
-#ifdef LDAP_OPT_X_TLS
-               if (ldap_v3) {
-                       if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
-                       {
-                               DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
-                                        ldap_err2string(rc)));
-                               return rc;
-                       }
-                       DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
-               } else {
-                       
-                       DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
-                       return LDAP_OPERATIONS_ERROR;
-               }
-#else
-               DEBUG(0,("smbldap_open_connection: StartTLS not supported by LDAP client libraries!\n"));
-               return LDAP_OPERATIONS_ERROR;
-#endif
-       }
-
-       DEBUG(2, ("smbldap_open_connection: connection opened\n"));
-       return rc;
-}
-
-
-/*******************************************************************
- a rebind function for authenticated referrals
- This version takes a void* that we can shove useful stuff in :-)
-******************************************************************/
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-#else
-static int rebindproc_with_state  (LDAP * ld, char **whop, char **credp, 
-                                  int *methodp, int freeit, void *arg)
-{
-       struct smbldap_state *ldap_state = arg;
-       
-       /** @TODO Should we be doing something to check what servers we rebind to?
-           Could we get a referral to a machine that we don't want to give our
-           username and password to? */
-       
-       if (freeit) {
-               SAFE_FREE(*whop);
-               memset(*credp, '\0', strlen(*credp));
-               SAFE_FREE(*credp);
-       } else {
-               DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n", 
-                         ldap_state->bind_dn));
-
-               *whop = strdup(ldap_state->bind_dn);
-               if (!*whop) {
-                       return LDAP_NO_MEMORY;
-               }
-               *credp = strdup(ldap_state->bind_secret);
-               if (!*credp) {
-                       SAFE_FREE(*whop);
-                       return LDAP_NO_MEMORY;
-               }
-               *methodp = LDAP_AUTH_SIMPLE;
-       }
-       return 0;
-}
-#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-
-/*******************************************************************
- a rebind function for authenticated referrals
- This version takes a void* that we can shove useful stuff in :-)
- and actually does the connection.
-******************************************************************/
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-static int rebindproc_connect_with_state (LDAP *ldap_struct, 
-                                         LDAP_CONST char *url, 
-                                         ber_tag_t request,
-                                         ber_int_t msgid, void *arg)
-{
-       struct smbldap_state *ldap_state = arg;
-       int rc;
-       DEBUG(5,("rebindproc_connect_with_state: Rebinding as \"%s\"\n", 
-                ldap_state->bind_dn));
-       
-       /** @TODO Should we be doing something to check what servers we rebind to?
-           Could we get a referral to a machine that we don't want to give our
-           username and password to? */
-
-       rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
-       
-       return rc;
-}
-#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-
-/*******************************************************************
- Add a rebind function for authenticated referrals
-******************************************************************/
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-#else
-# if LDAP_SET_REBIND_PROC_ARGS == 2
-static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
-                      int *method, int freeit )
-{
-       struct smbldap_state *ldap_state = smbldap_find_state(ldap_struct);
-
-       return rebindproc_with_state(ldap_struct, whop, credp,
-                                    method, freeit, ldap_state);
-       
-}
-# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
-#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-
-/*******************************************************************
- a rebind function for authenticated referrals
- this also does the connection, but no void*.
-******************************************************************/
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-# if LDAP_SET_REBIND_PROC_ARGS == 2
-static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
-                              ber_int_t msgid)
-{
-       struct smbldap_state *ldap_state = smbldap_find_state(ld);
-
-       return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid, 
-                                            ldap_state);
-}
-# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
-#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-
-/*******************************************************************
- connect to the ldap server under system privilege.
-******************************************************************/
-static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_struct)
-{
-       int rc;
-       char *ldap_dn;
-       char *ldap_secret;
-
-       /* get the password */
-       if (!fetch_ldap_pw(&ldap_dn, &ldap_secret))
-       {
-               DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
-               return LDAP_INVALID_CREDENTIALS;
-       }
-
-       ldap_state->bind_dn = ldap_dn;
-       ldap_state->bind_secret = ldap_secret;
-
-       /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite 
-          (OpenLDAP) doesnt' seem to support it */
-          
-       DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
-                 ldap_state->uri, ldap_dn));
-
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-# if LDAP_SET_REBIND_PROC_ARGS == 2    
-       ldap_set_rebind_proc(ldap_struct, &rebindproc_connect); 
-# endif
-# if LDAP_SET_REBIND_PROC_ARGS == 3    
-       ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);  
-# endif
-#else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-# if LDAP_SET_REBIND_PROC_ARGS == 2    
-       ldap_set_rebind_proc(ldap_struct, &rebindproc); 
-# endif
-# if LDAP_SET_REBIND_PROC_ARGS == 3    
-       ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);  
-# endif
-#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-
-       rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
-
-       if (rc != LDAP_SUCCESS) {
-               char *ld_error = NULL;
-               ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
-                               &ld_error);
-               DEBUG(ldap_state->num_failures ? 2 : 0,
-                     ("failed to bind to server with dn= %s Error: %s\n\t%s\n",
-                              ldap_dn ? ldap_dn : "(unknown)", ldap_err2string(rc),
-                              ld_error ? ld_error : "(unknown)"));
-               SAFE_FREE(ld_error);
-               ldap_state->num_failures++;
-               return rc;
-       }
-
-       ldap_state->num_failures = 0;
-
-       DEBUG(3, ("ldap_connect_system: succesful connection to the LDAP server\n"));
-       return rc;
-}
-
-/**********************************************************************
-Connect to LDAP server (called before every ldap operation)
-*********************************************************************/
-static int smbldap_open(struct smbldap_state *ldap_state)
-{
-       int rc;
-       SMB_ASSERT(ldap_state);
-               
-#ifndef NO_LDAP_SECURITY
-       if (geteuid() != 0) {
-               DEBUG(0, ("smbldap_open: cannot access LDAP when not root..\n"));
-               return  LDAP_INSUFFICIENT_ACCESS;
-       }
-#endif
-
-               if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time(NULL))) {
-               struct sockaddr_un addr;
-               socklen_t len = sizeof(addr);
-               int sd;
-               if (ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd) == 0 &&
-                   getpeername(sd, (struct sockaddr *) &addr, &len) < 0) {
-                       /* the other end has died. reopen. */
-                       ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
-                       ldap_state->ldap_struct = NULL;
-                       ldap_state->last_ping = (time_t)0;
-               } else {
-                       ldap_state->last_ping = time(NULL);
-               } 
-       }
-
-       if (ldap_state->ldap_struct != NULL) {
-               DEBUG(5,("smbldap_open: already connected to the LDAP server\n"));
-               return LDAP_SUCCESS;
-       }
-
-       if ((rc = smbldap_open_connection(ldap_state))) {
-               return rc;
-       }
-
-       if ((rc = smbldap_connect_system(ldap_state, ldap_state->ldap_struct))) {
-               ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
-               ldap_state->ldap_struct = NULL;
-               return rc;
-       }
-
-
-       ldap_state->last_ping = time(NULL);
-       DEBUG(4,("The LDAP server is succesful connected\n"));
-
-       return LDAP_SUCCESS;
-}
-
-/**********************************************************************
-Disconnect from LDAP server 
-*********************************************************************/
-static NTSTATUS smbldap_close(struct smbldap_state *ldap_state)
-{
-       if (!ldap_state)
-               return NT_STATUS_INVALID_PARAMETER;
-               
-       if (ldap_state->ldap_struct != NULL) {
-               ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
-               ldap_state->ldap_struct = NULL;
-       }
-
-       smbldap_delete_state(ldap_state);
-       
-       DEBUG(5,("The connection to the LDAP server was closed\n"));
-       /* maybe free the results here --metze */
-       
-       
-
-       return NT_STATUS_OK;
-}
-
-static int smbldap_retry_open(struct smbldap_state *ldap_state, int *attempts)
-{
-       int rc;
-
-       SMB_ASSERT(ldap_state && attempts);
-               
-       if (*attempts != 0) {
-               unsigned int sleep_time;
-               uint8 rand_byte;
-
-               /* Sleep for a random timeout */
-               rand_byte = (char)(sys_random());
-
-               sleep_time = (((*attempts)*(*attempts))/2)*rand_byte*2; 
-               /* we retry after (0.5, 1, 2, 3, 4.5, 6) seconds
-                  on average.  
-                */
-               DEBUG(3, ("Sleeping for %u milliseconds before reconnecting\n", 
-                         sleep_time));
-               msleep(sleep_time);
-       }
-       (*attempts)++;
-
-       if ((rc = smbldap_open(ldap_state))) {
-               DEBUG(1,("Connection to LDAP Server failed for the %d try!\n",*attempts));
-               return rc;
-       } 
-       
-       return LDAP_SUCCESS;            
-}
-
-
-/*********************************************************************
- ********************************************************************/
-
-static int smbldap_search(struct smbldap_state *ldap_state, 
-                         const char *base, int scope, const char *filter, 
-                         char *attrs[], int attrsonly, 
-                         LDAPMessage **res)
-{
-       int             rc = LDAP_SERVER_DOWN;
-       int             attempts = 0;
-       char           *utf8_filter;
-
-       SMB_ASSERT(ldap_state);
-
-       if (push_utf8_allocate(&utf8_filter, filter) == (size_t)-1) {
-               return LDAP_NO_MEMORY;
-       }
-
-       while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-               
-               if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
-                       continue;
-               
-               rc = ldap_search_s(ldap_state->ldap_struct, base, scope, 
-                                  utf8_filter, attrs, attrsonly, res);
-       }
-       
-       if (rc == LDAP_SERVER_DOWN) {
-               DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
-               smbldap_close(ldap_state);      
-       }
-
-       SAFE_FREE(utf8_filter);
-       return rc;
-}
-
-static int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
-{
-       int             rc = LDAP_SERVER_DOWN;
-       int             attempts = 0;
-       char           *utf8_dn;
-
-       SMB_ASSERT(ldap_state);
-
-       if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
-               return LDAP_NO_MEMORY;
-       }
-
-       while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-               
-               if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
-                       continue;
-               
-               rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs);
-       }
-       
-       if (rc == LDAP_SERVER_DOWN) {
-               DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
-               smbldap_close(ldap_state);      
-       }
-       
-       SAFE_FREE(utf8_dn);
-       return rc;
-}
-
-static int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
-{
-       int             rc = LDAP_SERVER_DOWN;
-       int             attempts = 0;
-       char           *utf8_dn;
-       
-       SMB_ASSERT(ldap_state);
-
-       if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
-               return LDAP_NO_MEMORY;
-       }
-
-       while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-               
-               if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
-                       continue;
-               
-               rc = ldap_add_s(ldap_state->ldap_struct, utf8_dn, attrs);
-       }
-       
-       if (rc == LDAP_SERVER_DOWN) {
-               DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
-               smbldap_close(ldap_state);      
-       }
-               
-       SAFE_FREE(utf8_dn);
-       return rc;
-}
-
-static int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
-{
-       int             rc = LDAP_SERVER_DOWN;
-       int             attempts = 0;
-       char           *utf8_dn;
-       
-       SMB_ASSERT(ldap_state);
-
-       if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
-               return LDAP_NO_MEMORY;
-       }
-
-       while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-               
-               if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
-                       continue;
-               
-               rc = ldap_delete_s(ldap_state->ldap_struct, utf8_dn);
-       }
-       
-       if (rc == LDAP_SERVER_DOWN) {
-               DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
-               smbldap_close(ldap_state);      
-       }
-               
-       SAFE_FREE(utf8_dn);
-       return rc;
-}
-
-static int smbldap_extended_operation(struct smbldap_state *ldap_state, 
-                                     LDAP_CONST char *reqoid, struct berval *reqdata, 
-                                     LDAPControl **serverctrls, LDAPControl **clientctrls, 
-                                     char **retoidp, struct berval **retdatap)
-{
-       int             rc = LDAP_SERVER_DOWN;
-       int             attempts = 0;
-       
-       if (!ldap_state)
-               return (-1);
-
-       while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-               
-               if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
-                       continue;
-               
-               rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata, 
-                                              serverctrls, clientctrls, retoidp, retdatap);
-       }
-       
-       if (rc == LDAP_SERVER_DOWN) {
-               DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
-               smbldap_close(ldap_state);      
-       }
-               
-       return rc;
-}
-
-/*******************************************************************
- run the search by name.
-******************************************************************/
-static int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter, 
-                               char **search_attr, LDAPMessage ** result)
-{
-       int scope = LDAP_SCOPE_SUBTREE;
-       int rc;
-
-       DEBUG(2, ("smbldap_search_suffix: searching for:[%s]\n", filter));
-
-       rc = smbldap_search(ldap_state, lp_ldap_suffix(), scope, filter, search_attr, 0, result);
-
-       if (rc != LDAP_SUCCESS) {
-               char *ld_error = NULL;
-               ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
-                               &ld_error);
-               DEBUG(0,("smbldap_search_suffix: Problem during the LDAP search: %s (%s)\n", 
-                       ld_error?ld_error:"(unknown)", ldap_err2string (rc)));
-               DEBUG(3,("smbldap_search_suffix: Query was: %s, %s\n", lp_ldap_suffix(), 
-                       filter));
-               SAFE_FREE(ld_error);
-       }
-       
-       return rc;
-}
-
 /*******************************************************************
  generate the LDAP search filter for the objectclass based on the 
  version of the schema we are using 
@@ -900,58 +283,6 @@ static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
        return True;
 }
 
-/**********************************************************************
-  Set attribute to newval in LDAP, regardless of what value the
-  attribute had in LDAP before.
-*********************************************************************/
-static void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing,
-                         LDAPMod ***mods,
-                         const char *attribute, const char *newval)
-{
-       char **values = NULL;
-
-       if (existing != NULL) {
-               values = ldap_get_values(ldap_struct, existing, attribute);
-       }
-
-       /* all of our string attributes are case insensitive */
-       
-       if ((values != NULL) && (values[0] != NULL) &&
-           StrCaseCmp(values[0], newval) == 0) 
-       {
-               
-               /* Believe it or not, but LDAP will deny a delete and
-                  an add at the same time if the values are the
-                  same... */
-
-               ldap_value_free(values);
-               return;
-       }
-
-       /* Regardless of the real operation (add or modify)
-          we add the new value here. We rely on deleting
-          the old value, should it exist. */
-
-       if ((newval != NULL) && (strlen(newval) > 0)) {
-               smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval);
-       }
-
-       if (values == NULL) {
-               /* There has been no value before, so don't delete it.
-                  Here's a possible race: We might end up with
-                  duplicate attributes */
-               return;
-       }
-
-       /* By deleting exactly the value we found in the entry this
-          should be race-free in the sense that the LDAP-Server will
-          deny the complete operation if somebody changed the
-          attribute behind our back. */
-
-       smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, values[0]);
-       ldap_value_free(values);
-}
-
 /*******************************************************************
  Delete complete object or objectclass and attrs from
  object found in search_result depending on lp_ldap_delete_dn
@@ -2758,27 +2089,6 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
        return NT_STATUS_OK;
 }
 
-/**********************************************************************
- Housekeeping
- *********************************************************************/
-
-static void smbldap_free_struct(struct smbldap_state **ldap_state) 
-{
-       smbldap_close(*ldap_state);
-       
-       if ((*ldap_state)->bind_secret) {
-               memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
-       }
-
-       SAFE_FREE((*ldap_state)->bind_dn);
-       SAFE_FREE((*ldap_state)->bind_secret);
-
-       *ldap_state = NULL;
-
-       /* No need to free any further, as it is talloc()ed */
-}
-
-
 /**********************************************************************
  Housekeeping
  *********************************************************************/
@@ -3340,26 +2650,6 @@ static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
        return NT_STATUS_OK;
 }
 
-/**********************************************************************
- Intitalise the 'general' ldap structures, on which ldap operations may be conducted
- *********************************************************************/
-
-static NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_state **smbldap_state) 
-{
-       *smbldap_state = talloc_zero(mem_ctx, sizeof(**smbldap_state));
-       if (!*smbldap_state) {
-               DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (location) {
-               (*smbldap_state)->uri = talloc_strdup(mem_ctx, location);
-       } else {
-               (*smbldap_state)->uri = "ldap://localhost";
-       }
-       return NT_STATUS_OK;
-}
-
 /**********************************************************************
  Intitalise the parts of the pdb_context that are common to all pdb_ldap modes
  *********************************************************************/