}
wrap_flags = lp_client_ldap_sasl_wrapping();
- if (wrap_flags == -1) {
- wrap_flags = 0;
+
+ if (wrap_flags & ADS_AUTH_SASL_LDAPS) {
+ sasl_state = ADS_SASL_PLAIN;
+ } else if (wrap_flags & ADS_AUTH_SASL_STARTTLS) {
+ sasl_state = ADS_SASL_PLAIN;
}
switch (sasl_state) {
bool ads_set_sasl_wrap_flags(ADS_STRUCT *ads, unsigned flags)
{
+ unsigned reset_flags;
unsigned other_flags;
if (!ads) {
return false;
}
- other_flags = ads->auth.flags & ~(ADS_AUTH_SASL_SIGN|ADS_AUTH_SASL_SEAL);
+ reset_flags = ADS_AUTH_SASL_SIGN |
+ ADS_AUTH_SASL_SEAL |
+ ADS_AUTH_SASL_LDAPS |
+ ADS_AUTH_SASL_STARTTLS;
+
+ other_flags = ads->auth.flags & ~reset_flags;
ads->auth.flags = flags | other_flags;
NTSTATUS ntstatus;
char addr[INET6_ADDRSTRLEN];
struct sockaddr_storage existing_ss;
+ bool tls = false;
+ bool start_tls = false;
zero_sockaddr(&existing_ss);
/* Otherwise setup the TCP LDAP session */
+ if (ads->auth.flags & ADS_AUTH_SASL_LDAPS) {
+ tls = true;
+ ads->ldap.port = 636;
+ } else if (ads->auth.flags & ADS_AUTH_SASL_STARTTLS) {
+ tls = true;
+ start_tls = true;
+ ads->ldap.port = 389;
+ } else {
+ ads->ldap.port = 389;
+ }
+
ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name,
&ads->ldap.ss,
ads->ldap.port, lp_ldap_timeout());
ldap_set_option(ads->ldap.ld, LDAP_OPT_PROTOCOL_VERSION, &version);
+ if (start_tls) {
+ unsigned int to = lp_ldap_connection_timeout();
+ struct berval *rspdata = NULL;
+ char *rspoid = NULL;
+ int rc;
+
+ if (to) {
+ /* Setup timeout */
+ gotalarm = 0;
+ CatchSignal(SIGALRM, gotalarm_sig);
+ alarm(to);
+ /* End setup timeout. */
+ }
+
+ rc = ldap_extended_operation_s(ads->ldap.ld,
+ LDAP_EXOP_START_TLS,
+ NULL,
+ NULL,
+ NULL,
+ &rspoid,
+ &rspdata);
+ if (gotalarm != 0 && rc == LDAP_SUCCESS) {
+ rc = LDAP_TIMEOUT;
+ }
+
+ if (to) {
+ /* Teardown timeout. */
+ alarm(0);
+ CatchSignal(SIGALRM, SIG_IGN);
+ }
+
+ if (rspoid != NULL) {
+ ldap_memfree(rspoid);
+ }
+
+ if (rspdata != NULL) {
+ ber_bvfree(rspdata);
+ }
+
+ if (rc != LDAP_SUCCESS) {
+ status = ADS_ERROR_LDAP(rc);
+ goto out;
+ }
+ }
+
+ if (tls) {
+ unsigned int to = lp_ldap_connection_timeout();
+
+ if (to) {
+ /* Setup timeout */
+ gotalarm = 0;
+ CatchSignal(SIGALRM, gotalarm_sig);
+ alarm(to);
+ /* End setup timeout. */
+ }
+
+ status = ads_setup_tls_wrapping(&ads->ldap_tls_data,
+ ads->ldap.ld,
+ ads->config.ldap_server_name);
+
+ if (to) {
+ /* Teardown timeout. */
+ alarm(0);
+ CatchSignal(SIGALRM, SIG_IGN);
+ }
+
+ if ( !ADS_ERR_OK(status) ) {
+ goto out;
+ }
+ }
+
/* cache the successful connection for workgroup and realm */
if (ads_closest_dc(ads)) {
saf_store( ads->server.workgroup, ads->config.ldap_server_name);
nt_errstr(nt_status));
return ADS_ERROR_NT(nt_status);
}
-
- wrap->wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
}
switch (wrap->wrap_type) {
{
ADS_STATUS status;
struct ads_saslwrap *wrap = &ads->ldap_wrap_data;
+ bool tls = false;
- if (ads->auth.flags & ADS_AUTH_SASL_SEAL) {
+ if (ads->auth.flags & ADS_AUTH_SASL_LDAPS) {
+ tls = true;
+ wrap->wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
+ } else if (ads->auth.flags & ADS_AUTH_SASL_STARTTLS) {
+ tls = true;
+ wrap->wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
+ } else if (ads->auth.flags & ADS_AUTH_SASL_SEAL) {
wrap->wrap_type = ADS_SASLWRAP_TYPE_SEAL;
} else if (ads->auth.flags & ADS_AUTH_SASL_SIGN) {
wrap->wrap_type = ADS_SASLWRAP_TYPE_SIGN;
wrap->wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
}
+ if (tls) {
+ const DATA_BLOB *tls_cb = NULL;
+
+ tls_cb = ads_tls_channel_bindings(&ads->ldap_tls_data);
+ if (tls_cb == NULL) {
+ DBG_ERR("No TLS channel bindings available\n");
+ return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR);
+ }
+ }
+
retry:
status = ads_sasl_spnego_bind(ads);
if (status.error_type == ENUM_ADS_ERROR_LDAP &&
status.err.rc == LDAP_STRONG_AUTH_REQUIRED &&
+ !tls &&
wrap->wrap_type == ADS_SASLWRAP_TYPE_PLAIN)
{
DEBUG(3,("SASL bin got LDAP_STRONG_AUTH_REQUIRED "