diff options
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/smbldap.c | 187 |
1 files changed, 137 insertions, 50 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 :-) |