From 092e3e514b092f228bfb7970a34b528a3df6d3d7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 23 Nov 2005 11:17:04 +0000 Subject: r11874: Merge LDAP connection setup in lib/smbldap.c and pdb_nds.c. 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 | 187 ++++++++++++++++++++++++++++++++++------------- source3/passdb/pdb_nds.c | 59 ++------------- 2 files changed, 142 insertions(+), 104 deletions(-) diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index f08a67a22c..75842ec193 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -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 :-) diff --git a/source3/passdb/pdb_nds.c b/source3/passdb/pdb_nds.c index 1385583086..c6d644827c 100644 --- a/source3/passdb/pdb_nds.c +++ b/source3/passdb/pdb_nds.c @@ -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) { -- cgit