--- a/source3/param/loadparm.c 2013-03-18 01:59:37.000000000 -0700 +++ b/source3/param/loadparm.c 2013-05-10 23:59:37.528279300 +0200 @@ -278,6 +278,9 @@ int ldap_follow_referral; char *szLdapSuffix; char *szLdapAdminDn; + char *szLdapCertDBdir; + char *szLdapKeyDBdir; + bool ldap_privkey_open; int ldap_debug_level; int ldap_debug_threshold; int iAclCompat; @@ -3701,6 +3704,33 @@ .flags = FLAG_ADVANCED, }, { + .label = "ldap certdb dir", + .type = P_STRING, + .p_class = P_GLOBAL, + .ptr = &Globals.szLdapCertDBdir, + .special = NULL, + .enum_list = NULL, + .flags = FLAG_ADVANCED, + }, + { + .label = "ldap keydb dir", + .type = P_STRING, + .p_class = P_GLOBAL, + .ptr = &Globals.szLdapKeyDBdir, + .special = NULL, + .enum_list = NULL, + .flags = FLAG_ADVANCED, + }, + { + .label = "ldap privkey open", + .type = P_BOOL, + .p_class = P_GLOBAL, + .ptr = &Globals.ldap_privkey_open, + .special = NULL, + .enum_list = NULL, + .flags = FLAG_ADVANCED, + }, + { .label = "ldap delete dn", .type = P_BOOL, .p_class = P_GLOBAL, @@ -5366,6 +5396,9 @@ string_set(&Globals.szLdapIdmapSuffix, ""); string_set(&Globals.szLdapAdminDn, ""); + string_set(&Globals.szLdapCertDBdir, get_dyn_PRIVATE_DIR()); + string_set(&Globals.szLdapKeyDBdir, get_dyn_PRIVATE_DIR()); + Globals.ldap_privkey_open = False; Globals.ldap_ssl = LDAP_SSL_START_TLS; Globals.ldap_ssl_ads = False; Globals.ldap_deref = -1; @@ -5747,6 +5780,9 @@ FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix) FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn) +FN_GLOBAL_STRING(lp_ldap_certdb_dir, &Globals.szLdapCertDBdir) +FN_GLOBAL_STRING(lp_ldap_keydb_dir, &Globals.szLdapKeyDBdir) +FN_GLOBAL_BOOL(lp_ldap_privkey_open, &Globals.ldap_privkey_open) FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl) FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads) FN_GLOBAL_INTEGER(lp_ldap_deref, &Globals.ldap_deref) --- a/source3/include/proto.h 2013-03-18 01:59:37.000000000 -0700 +++ b/source3/include/proto.h 2013-05-11 00:04:26.565521200 +0200 @@ -1429,6 +1429,9 @@ bool lp_passdb_expand_explicit(void); char *lp_ldap_suffix(void); char *lp_ldap_admin_dn(void); +char *lp_ldap_certdb_dir(void); +char *lp_ldap_keydb_dir(void); +bool lp_ldap_privkey_open(void); int lp_ldap_ssl(void); bool lp_ldap_ssl_ads(void); int lp_ldap_deref(void); --- a/source3/include/smb_ldap.h 2013-03-18 01:59:37.000000000 -0700 +++ b/source3/include/smb_ldap.h 2013-04-29 13:33:34.602541500 -0700 @@ -63,6 +63,10 @@ #endif /* HAVE_LDAP_H */ +#if HAVE_LDAP_SSL_H +#include +#endif /* HAVE_LDAP_SSL_H */ + #ifndef HAVE_LDAP #define LDAP void #define LDAPMessage void --- a/source3/lib/smbldap.c 2013-05-08 10:16:26.000000000 +0200 +++ b/source3/lib/smbldap.c 2013-07-03 09:00:28.482477500 +0200 @@ -780,7 +780,7 @@ int smb_ldap_start_tls(LDAP *ldap_struct, int version) { -#ifdef LDAP_OPT_X_TLS +#ifdef HAVE_LDAP_START_TLS_S int rc; #endif @@ -788,12 +788,24 @@ return LDAP_SUCCESS; } -#ifdef LDAP_OPT_X_TLS +#ifdef HAVE_LDAP_START_TLS_S if (version != LDAP_VERSION3) { DEBUG(0, ("Need LDAPv3 for Start TLS\n")); return LDAP_OPERATIONS_ERROR; } +#ifdef HAVE_LDAPSSL_INIT /* Netscape */ + rc = ldapssl_clientauth_init(lp_ldap_certdb_dir(), NULL, + lp_ldap_privkey_open(), lp_ldap_keydb_dir(), NULL); + if (rc != LDAP_SUCCESS) { + DEBUG(0,("ldapssl_clientauth_init with '%s' cert db, " + "%s key db, failed: %s\n", + lp_ldap_certdb_dir(), lp_ldap_keydb_dir(), + ldap_err2string(rc))); + return rc; + } +#endif /* HAVE_LDAPSSL_INIT */ + 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))); @@ -802,12 +814,14 @@ DEBUG (3, ("StartTLS issued: using a TLS connection\n")); return LDAP_SUCCESS; -#else + +#else /* ! HAVE_LDAP_START_TLS_S */ DEBUG(0,("StartTLS not supported by LDAP client libraries!\n")); return LDAP_OPERATIONS_ERROR; -#endif +#endif /* HAVE_LDAP_START_TLS_S */ } + /******************************************************************** setup a connection to the LDAP server based on a uri *******************************************************************/ @@ -815,8 +829,24 @@ static int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri) { int rc; +#ifdef LDAP_OPT_TIMELIMIT + int ot = lp_ldap_timeout(); +#endif +#ifdef LDAP_X_OPT_CONNECT_TIMEOUT /* Netscape */ + int ct = lp_ldap_connection_timeout() * 1000; +#elif defined (LDAP_OPT_NETWORK_TIMEOUT) /* OpenLDAP */ + struct timeval ct; +#endif +#ifndef HAVE_LDAP_INITIALIZE + int port = 0; + fstring protocol; + fstring host; + /* Following symbols are only available if Mozldap */ + /* is compiled with LDAP_DEBUG on */ + /* extern int lber_debug, ldap_debug; */ +#endif - DEBUG(10, ("smb_ldap_setup_connection: %s\n", uri)); + DEBUG(10, ("smb_ldap_setup_conn: %s\n", uri)); #ifdef HAVE_LDAP_INITIALIZE @@ -837,74 +867,105 @@ return LDAP_SUCCESS; #else + /* lber_debug = 255 ; */ + /* ldap_debug = 1023 | 0x4000 ; */ + /* Parse the string manually */ - { - int port = 0; - fstring protocol; - fstring host; - SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254); + SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254); - /* skip leading "URL:" (if any) */ - if ( strnequal( uri, "URL:", 4 ) ) { - uri += 4; - } + /* skip leading "URL:" (if any) */ + if ( strnequal( uri, "URL:", 4 ) ) { + uri += 4; + } - sscanf(uri, "%10[^:]://%254[^:/]:%d", protocol, host, &port); + sscanf(uri, "%10[^:]://%254[^:/]:%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 (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)); + return LDAP_OPERATIONS_ERROR; } + } + if (strequal(protocol, "ldap")) { if ((*ldap_struct = ldap_init(host, port)) == NULL) { DEBUG(0, ("ldap_init failed !\n")); return LDAP_OPERATIONS_ERROR; } - - if (strequal(protocol, "ldaps")) { + } else 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")); + int tls = LDAP_OPT_X_TLS_HARD; + if ((*ldap_struct = ldap_init(host, port)) == NULL) { + DEBUG(0, ("ldap_init failed !\n")); + return LDAP_OPERATIONS_ERROR; + } + 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")); + +#elif defined(HAVE_LDAPSSL_INIT) /* Netscape */ + if (*ldap_struct != NULL) { + rc = ldap_unbind_s(*ldap_struct); + if (rc == LDAP_SUCCESS) { + DEBUG(10, ("LDAP already bound... unbound.\n")); + } else { + DEBUG(10, ("ldap_unbind_s failed: %s\n", + ldap_err2string(rc))); } + *ldap_struct = NULL; + } + rc = ldapssl_clientauth_init(lp_ldap_certdb_dir(), NULL, + lp_ldap_privkey_open(), lp_ldap_keydb_dir(), NULL); + if (rc != LDAP_SUCCESS) { + DEBUG(0,("ldapssl_clientauth_init with '%s' cert db, " + "%s key db, failed: %s\n", + lp_ldap_certdb_dir(), lp_ldap_keydb_dir(), + ldap_err2string(rc))); + return rc; + } - DEBUG(3,("LDAPS option set...!\n")); + if ((*ldap_struct = ldapssl_init(host, port, True)) == NULL) { + DEBUG(0, ("ldapssl_init to %s:%d failed!\n", host, + port)); + return LDAP_OPERATIONS_ERROR; + } #else - DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n")); + DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n")); return LDAP_OPERATIONS_ERROR; #endif /* LDAP_OPT_X_TLS */ - } } #endif /* HAVE_LDAP_INITIALIZE */ +#ifdef LDAP_OPT_TIMELIMIT + rc = ldap_set_option(*ldap_struct, LDAP_OPT_TIMELIMIT, &ot); + if (rc != LDAP_SUCCESS) { + DEBUG(0,("Failed to setup a ldap operation timeout %d: %s\n", + ot, ldap_err2string(rc))); + } +#endif + /* now set connection timeout */ #ifdef LDAP_X_OPT_CONNECT_TIMEOUT /* Netscape */ - { - int ct = lp_ldap_connection_timeout()*1000; - rc = ldap_set_option(*ldap_struct, LDAP_X_OPT_CONNECT_TIMEOUT, &ct); - if (rc != LDAP_SUCCESS) { - DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n", - ct, ldap_err2string(rc))); - } + rc = ldap_set_option(*ldap_struct, LDAP_X_OPT_CONNECT_TIMEOUT, &ct); + if (rc != LDAP_SUCCESS) { + DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n", + ct, ldap_err2string(rc))); } #elif defined (LDAP_OPT_NETWORK_TIMEOUT) /* OpenLDAP */ - { - struct timeval ct; - ct.tv_usec = 0; - ct.tv_sec = lp_ldap_connection_timeout(); - rc = ldap_set_option(*ldap_struct, LDAP_OPT_NETWORK_TIMEOUT, &ct); - if (rc != LDAP_SUCCESS) { - DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n", - (int)ct.tv_sec, ldap_err2string(rc))); - } + ct.tv_usec = 0; + ct.tv_sec = lp_ldap_connection_timeout(); + rc = ldap_set_option(*ldap_struct, LDAP_OPT_NETWORK_TIMEOUT, &ct); + if (rc != LDAP_SUCCESS) { + DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n", + (int)ct.tv_sec, ldap_err2string(rc))); } #endif @@ -1094,7 +1155,7 @@ * our credentials. At least *try* to secure the connection - Guenther */ smb_ldap_upgrade_conn(ldap_struct, &version); - smb_ldap_start_tls(ldap_struct, version); + /* smb_ldap_start_tls(ldap_struct, version); */ /** @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 --- a/source3/configure.in 2013-04-26 03:05:37.000000000 -0700 +++ b/source3/configure.in 2013-05-09 13:54:35.613605329 -0700 @@ -3485,6 +3485,14 @@ fi ################################################################## + # check for ldap_ssl.h (Mozldap) + AC_CHECK_HEADERS([ldap_ssl.h], [], [], + [[#if HAVE_LDAP_H + #include + #endif + ]]) + + ################################################################## # HP/UX does not have ber_tag_t in lber.h - it must be configured as # unsigned int in include/includes.h case $host_os in @@ -3551,6 +3562,14 @@ AC_CHECK_LIB_EXT(ldap, LDAP_LIBS, ldap_init) ######################################################## + # check for Netscape mozldap SSL API + AC_CHECK_FUNC_EXT(ldapssl_init,$LDAP_LIBS) + + ######################################################## + # check for StartTLS on API + AC_CHECK_FUNC_EXT(ldap_start_tls_s,$LDAP_LIBS) + + ######################################################## # If we have LDAP, does it's rebind procedure take 2 or 3 arguments? # Check found in pam_ldap 145. AC_CHECK_FUNC_EXT(ldap_set_rebind_proc,$LDAP_LIBS) @@ -3627,33 +3646,17 @@ # Check to see whether there is enough LDAP functionality to be able # to build AD support. -# HPUX only has ldap_init; ok, we take care of this in smbldap.c -case "$host_os" in - *hpux*) - AC_CHECK_FUNC_EXT(ldap_init,$LDAP_LIBS) + # URL-open support is added into smbldap.c so ldap_init is enough + AC_CHECK_LIB_EXT(ldap, LDAP_LIBS, ldap_init) - if test x"$ac_cv_func_ext_ldap_init" != x"yes"; then + if test x"$ac_cv_lib_ext_ldap_ldap_init" != x"yes"; then if test x"$with_ads_support" = x"yes"; then - AC_MSG_ERROR(Active Directory support on HPUX requires ldap_init) + AC_MSG_ERROR(Active Directory support requires ldap_init) elif test x"$with_ads_support" = x"auto"; then - AC_MSG_WARN(Disabling Active Directory support (requires ldap_init on HPUX)) + AC_MSG_WARN(Disabling Active Directory support (requires ldap_init)) with_ads_support=no fi fi - ;; - *) - AC_CHECK_FUNC_EXT(ldap_initialize,$LDAP_LIBS) - - if test x"$ac_cv_func_ext_ldap_initialize" != x"yes"; then - if test x"$with_ads_support" = x"yes"; then - AC_MSG_ERROR(Active Directory support requires ldap_initialize) - elif test x"$with_ads_support" = x"auto"; then - AC_MSG_WARN(Disabling Active Directory support (requires ldap_initialize)) - with_ads_support=no - fi - fi - ;; -esac AC_CHECK_FUNC_EXT(ldap_add_result_entry,$LDAP_LIBS)