title: Can't bind in php against Active Directory LDAP over SSL?
body: <p>We have an IIS php site which authenticates against Active Directory using LDAP, specifically using ldap_connect and ldap_bind.  This works fine, but we're gearing up for the pending change to only allow signed LDAP binding to AD.  When I update my code to what I think should work, I get authentication failure, but I can't get an actual error code out to help troubleshoot.</p>
  
  <p>As of right now, TLS binding is disabled on our domain controllers, I just want to use AD SSL binding over 636 (instead of TLS over 389).  We are using PHP 5.6.30 on IIS 6.1 on a Server 2008 R2 server...We have our migration target built which is Server 2016 on IIS 10 and PHP 7.2 and we're seeing the same result.  php_openssl and php_ldap are enabled extensions.</p>
  
  <p>Here's the current code:</p>
  
  <pre><code>    $this-&gt;AD_SERVER = $config['AD_SERVER'];
      assert(is_string($password));
      if ($password == "") {
          throw new \SimpleSAML\Error\Error('NOPASSWORD');
      }
      $ldap = ldap_connect($this-&gt;AD_SERVER);
      $ldaprdn = 'DOMAINPREFIX' . "\\" . $user;
      ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 9);
      ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
      ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
      $bind = @ldap_bind($ldap, $ldaprdn, $password);
  </code></pre>
  
  <p>This works fine.  After this, pulling attributes using "ldap_search" and "ldap_get_entries" is successful.  The username and password are provided by the user attempting to authenticate; the bind happens under the credentials of the authenticating user.</p>
  
  <p>If I change the first line to the following, I just get authentication failure, no more descriptive error:</p>
  
  <pre><code>    $this-&gt;AD_SERVER = 'ldaps://'.$config['AD_SERVER'].':636';
      assert(is_string($password));
      if ($password == "") {
          throw new \SimpleSAML\Error\Error('NOPASSWORD');
      }
      $ldap = ldap_connect($this-&gt;AD_SERVER);
      $ldaprdn = 'DOMAINPREFIX' . "\\" . $user;
      ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 9);
      ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
      ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
      $bind = @ldap_bind($ldap, $ldaprdn, $password);
  </code></pre>
  
  <p>I've messed with "LDAP_OPT_X_TLS_REQUIRE_CERT" and disabling other tls stuff, but it doesn't matter (and I didn't think it would).</p>
  
  <p>On the domain controller, for the failed attempts, I see no eventID's at all from 2280-2290 (which I believe would expose binding errors).  Additionally, I only see 4776 (authentication attempts) when the insecure binding is configured, I never get an attempt at all when the secure binding is failing.  I believe there is a bind problem, however I can't seem to expose any logs to help diagnose it.</p>
  
  <p>I have found many articles indicating how to do this for openldap, but very I've found almost nothing documenting AD LDAP signed binding.  I've seen a lot of people indicate we should switch to TLS as SSL binding over 636 is a non-standard LDAP thing and just applies to AD, however we would really like to avoid that if possible.  Any assistance would be appreciated.</p>