r11874: Merge LDAP connection setup in lib/smbldap.c and pdb_nds.c.
authorGünther Deschner <gd@samba.org>
Wed, 23 Nov 2005 11:17:04 +0000 (11:17 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:05:33 +0000 (11:05 -0500)
Also allow to use START_TLS in the pdb_nds_update_login_attempts
function when doing simple binds to eDir.

Guenther
(This used to be commit 04a3ac5e50e93f74dfddfead5cb3f335ce991e9a)

source3/lib/smbldap.c
source3/passdb/pdb_nds.c

index f08a67a22c891f5cbc7c807458818ec1c5405734..75842ec193e60b3e9b0121cfb668b91a03e49a63 100644 (file)
@@ -523,24 +523,56 @@ static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state)
        t->smbldap_state = smbldap_state;
 }
 
-/*******************************************************************
- open a connection to the ldap server.
-******************************************************************/
-static int smbldap_open_connection (struct smbldap_state *ldap_state)
+/********************************************************************
+ start TLS on an existing LDAP connection
+*******************************************************************/
+
+int smb_ldap_start_tls(LDAP *ldap_struct, int version)
+{ 
+       int rc;
+       
+       if (lp_ldap_ssl() != LDAP_SSL_START_TLS) {
+               return LDAP_SUCCESS;
+       }
+       
+#ifdef LDAP_OPT_X_TLS
+       if (version != LDAP_VERSION3) {
+               DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
+               return LDAP_OPERATIONS_ERROR;
+       }
 
+       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"));
+       return LDAP_SUCCESS;
+#else
+       DEBUG(0,("StartTLS not supported by LDAP client libraries!\n"));
+       return LDAP_OPERATIONS_ERROR;
+#endif
+}
+
+/********************************************************************
+ setup a connection to the LDAP server based on a uri
+*******************************************************************/
+
+int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri)
 {
-       int rc = LDAP_SUCCESS;
-       int version;
-       BOOL ldap_v3 = False;
-       LDAP **ldap_struct = &ldap_state->ldap_struct;
+       int rc;
 
+       DEBUG(10, ("smb_ldap_setup_connection: %s\n", uri));
+       
 #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) {
+       rc = ldap_initialize(ldap_struct, uri);
+       if (rc) {
                DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
-               return rc;
        }
+
+       return rc;
 #else 
 
        /* Parse the string manually */
@@ -549,15 +581,15 @@ static int smbldap_open_connection (struct smbldap_state *ldap_state)
                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 ( strnequal( p, "URL:", 4 ) ) {
-                       p += 4;
+               if ( strnequal( uri, "URL:", 4 ) ) {
+                       uri += 4;
                }
                
-               sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, host, &port);
+               sscanf(uri, "%10[^:]://%254[^:/]:%d", protocol, host, &port);
                
                if (port == 0) {
                        if (strequal(protocol, "ldap")) {
@@ -586,10 +618,88 @@ static int smbldap_open_connection (struct smbldap_state *ldap_state)
 #else
                        DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
                        return LDAP_OPERATIONS_ERROR;
-#endif
+#endif /* LDAP_OPT_X_TLS */
                }
+
+       }
+#endif /* HAVE_LDAP_INITIALIZE */
+       return LDAP_SUCCESS;
+}
+
+/********************************************************************
+ try to upgrade to Version 3 LDAP if not already, in either case return current
+ version 
+ *******************************************************************/
+
+int smb_ldap_upgrade_conn(LDAP *ldap_struct, int *new_version) 
+{
+       int version;
+       int rc;
+       
+       /* assume the worst */
+       *new_version = LDAP_VERSION2;
+
+       rc = ldap_get_option(ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
+       if (rc) {
+               return rc;
+       }
+
+       if (version == LDAP_VERSION3) {
+               *new_version = LDAP_VERSION3;
+               return LDAP_SUCCESS;
+       }
+
+       /* try upgrade */
+       version = LDAP_VERSION3;
+       rc = ldap_set_option (ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
+       if (rc) {
+               return rc;
+       }
+               
+       *new_version = LDAP_VERSION3;
+       return LDAP_SUCCESS;
+}
+
+/*******************************************************************
+ open a connection to the ldap server (just until the bind)
+ ******************************************************************/
+
+int smb_ldap_setup_full_conn(LDAP *ldap_struct, const char *uri)
+{
+       int rc, version;
+
+       rc = smb_ldap_setup_conn(&ldap_struct, uri);
+       if (rc) {
+               return rc;
+       }
+
+       rc = smb_ldap_upgrade_conn(ldap_struct, &version);
+       if (rc) {
+               return rc;
+       }
+
+       rc = smb_ldap_start_tls(ldap_struct, version);
+       if (rc) {
+               return rc;
+       }
+
+       return LDAP_SUCCESS;
+}
+
+/*******************************************************************
+ open a connection to the ldap server.
+******************************************************************/
+static int smbldap_open_connection (struct smbldap_state *ldap_state)
+
+{
+       int rc = LDAP_SUCCESS;
+       int version;
+       LDAP **ldap_struct = &ldap_state->ldap_struct;
+
+       rc = smb_ldap_setup_conn(ldap_struct, ldap_state->uri);
+       if (rc) {
+               return rc;
        }
-#endif
 
        /* Store the LDAP pointer in a lookup list */
 
@@ -597,45 +707,22 @@ static int smbldap_open_connection (struct smbldap_state *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;
-               }
+       rc = smb_ldap_upgrade_conn(*ldap_struct, &version);
+       if (rc) {
+               return rc;
        }
 
-       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
-       }
+       /* Start TLS if required */
 
+       rc = smb_ldap_start_tls(*ldap_struct, version);
+       if (rc) {
+               return rc;
+       }
+       
        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 :-)
index 138558308670e6c2a094d321acdfd4fe1a3ae93e..c6d644827c773c7e96408e414b047a5784c1654d 100644 (file)
@@ -762,11 +762,7 @@ static NTSTATUS pdb_nds_update_login_attempts(struct pdb_methods *methods,
                const char **attr_list;
                size_t pwd_len;
                char clear_text_pw[512];
-               const char *p = NULL;
                LDAP *ld = NULL;
-               int ldap_port = 0;
-               char protocol[12];
-               char ldap_server[256];
                const char *username = pdb_get_username(sam_acct);
                BOOL got_clear_text_pw = False;
 
@@ -809,58 +805,13 @@ static NTSTATUS pdb_nds_update_login_attempts(struct pdb_methods *methods,
                        DEBUG(5,("pdb_nds_update_login_attempts: using random password %s\n", clear_text_pw));
                }
 
-               /* Parse the location string */
-               p = ldap_state->location; 
-
-               /* skip leading "URL:" (if any) */
-               if ( strnequal( p, "URL:", 4 ) ) {
-                       p += 4;
-               }
-
-               sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, ldap_server, &ldap_port);
-
-               if (ldap_port == 0) {
-                       if (strequal(protocol, "ldap")) {
-                               ldap_port = LDAP_PORT;
-                       } else if (strequal(protocol, "ldaps")) {
-                               ldap_port = LDAPS_PORT;
-                       } else {
-                               DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
-                       }
-               }
-
-               ld = ldap_init(ldap_server, ldap_port);
-
-               if(ld != NULL) {
-                       int version;
-
-                       /* LDAP version 3 required for ldap_sasl */
-                       if (ldap_get_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) {
-                               if (version != LDAP_VERSION3) {
-                                       version = LDAP_VERSION3;
-                                       if (ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) {
-                                               DEBUG(4, ("pdb_nds_update_login_attempts: Set protocol version to LDAP_VERSION3\n"));
-                                       }
-                               }
-                       }
-
-                       /* Turn on ssl if required */
-                       if(strequal(protocol, "ldaps")) {
-#ifdef LDAP_OPT_X_TLS
-                               int tls = LDAP_OPT_X_TLS_HARD;
-                               if (ldap_set_option (ld, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS) {
-                                       DEBUG(1, ("pdb_nds_update_login_attempts: Failed to setup a TLS session\n"));
-                               } else {
-                                       DEBUG(4, ("pdb_nds_update_login_attempts: Activated TLS on session\n"));
-                               }
-#else
-                               DEBUG(0,("pdb_nds_update_login_attempts: Secure connection not supported by LDAP client libraries!\n"));
-                               return NT_STATUS_INVALID_PARAMETER;
-#endif
+               if((success != True) || (got_clear_text_pw == True)) {
+                       
+                       rc = smb_ldap_setup_full_conn(ld, ldap_state->location);
+                       if (rc) {
+                               return NT_STATUS_INVALID_CONNECTION;
                        }
-               }
 
-               if((success != True) || (got_clear_text_pw == True)) {
                        /* Attempt simple bind with real or bogus password */
                        rc = ldap_simple_bind_s(ld, dn, clear_text_pw);
                        if (rc == LDAP_SUCCESS) {