2

I'm trying to authenticate to Active Directory using PHP (5.3.2)/Apache (2.0.59)/Windows (2003).

However, I'm getting the following error:

ldap_start_tls() [function.ldap-start-tls]: Unable to start TLS: Connect error in E:\my_page.php on line 15

Here is my current script:

putenv('LDAPTLS_REQCERT=never');

$resource = ldap_connect("xxx") 
    or die("Failed to connect to LDAP server."); 

echo "Connected to LDAP server.<br />"; 

//these options may not be necessary in all environments 
ldap_set_option($resource, LDAP_OPT_PROTOCOL_VERSION, 3);    
ldap_set_option($resource, LDAP_OPT_REFERRALS, 0); 

$result = ldap_start_tls($resource) or die("Failed to start TLS.<br />"); 

echo "Started TLS.<br />"; 

$result = ldap_sasl_bind($resource, NULL, '', 'GSSAPI', 'xxx', '', '') 
    or die("Failed to GSSAPI bind.<br />"); 

echo "GSSAPI bound."; 

I've looked at this question for help, however, I keep seeing references to ldap.conf.

Is this for OpenLDAP as in, the LDAP server your connecting to? If it is, I could ignore it due to using an existing enteprise Active Directory ?

Or is this for the PHP libraries connecting to an LDAP server (ie. ldap_connect())?

Edit #1

Screenshot of Wireshark...

Screenshot of Wireshark

I see in there, unknown CA... how would I go solving this (looking online ATM).

Edit #2

Update, I'm now getting a different error. I created ldap.conf on c:\ and c:\openldap\sysconf

Content of ldap.conf:

#
# LDAP Defaults
#

TLS_REQCERT never

Now, it's stuck at the ldap_sasl_bind method which is normal - it's not installed.

Edit #3

Final product:

function isAuthenticated($user, $pass){
    //init
    $ldap_server = "";
    $ldap_user = "";
    $ldap_pass = "";
    $ldap_dn = "";
    $ldap_filter_fields = array("dn","cn","samaccountname");
    //establish connection
    $ldap_conn = ldap_connect($ldap_server) 
        or die("Failed to connect to LDAP server."); 

    //these options may not be necessary in all environments 
    ldap_set_option($resource, LDAP_OPT_PROTOCOL_VERSION, 3);    
    ldap_set_option($resource, LDAP_OPT_REFERRALS, 0); 

    //Magic happens here, encrypted tunnel starts!
    $result = ldap_start_tls($ldap_conn) or die("Failed to start TLS.<br />"); 

    $out = 0;
    //connect using our known user
    if($bind = ldap_bind($ldap_conn, $ldap_user, $ldap_pass)){  
        //search for the user
        $ldap_search_results = ldap_search($ldap_conn, $ldap_dn, "samaccountname=".$user, $ldap_filter_fields) or die ("Failed to search LDAP");
        //get entry
        $ldap_record = ldap_get_entries($ldap_conn, $ldap_search_results);
        debug($ldap_record);
        if($ldap_record["count"] > 0){
            //try to authenticate user here
            if($bind2 = @ldap_bind($ldap_conn, $ldap_record[0]["dn"], $pass))
                $out = 1;
            else
                //wrong password
                $out = 0;
        }
        else
            //user wasn't found
            $out = 3;       
    }
    else
        //something happened when connecting with our ldap_user
        $out = 2;

    return $out;    
}
Community
  • 1
  • 1
TechFanDan
  • 3,329
  • 6
  • 46
  • 89
  • Post more information, for example, logs from A/D if you can get them for the attempt your LDAP client made to promote the connection to TLS. – Terry Gardner May 10 '12 at 13:28
  • 1
    @TerryGardner See my edits. I have included a screenshot of Wireshark. Seems I have an unknown CA? – TechFanDan May 10 '12 at 13:49

2 Answers2

1

You're on the right track with your unknown CA. I have had a similar issue with PHP on CentOS connecting to AD. I had to export the CA certificate from the AD server and configure it to be trusted on the CentOS system, which involved copying the certificate to /etc/openldap/cacerts and running OpenSSL's c_rehash. Unfortunately, I'm not sure how to tell you to get that same setup working under Windows.

Mattie
  • 20,280
  • 7
  • 36
  • 54
  • couldn't I simply add LDAPTLS_REQCERT never to my ldap.conf (once I Find the proper location) and not have to export the cert? I currently have this specified in my PHP script which doesn't seem to work. Thanks! – TechFanDan May 10 '12 at 15:04
  • I'm not familiar with `TLS_REQCERT` (which is what belongs in `ldap.conf`; `LDAPTLS_REQCERT` appears to be an environment variable with a similar effect), but it sounds like that should work if you're willing to not validate certificates and thus leave yourself vulnerable to a man-in-the-middle attack. In my `ldap.conf`, which is in `/etc/openldap` on CentOS, I have `TLS_CACERTDIR /etc/openldap/cacerts`; that directory, in turn, has all the CA certificates that are trusted for LDAP purposes. Unfortunately, this is still not Windows-specific. :-) – Mattie May 10 '12 at 15:11
  • See update, now it would seem that I'm getting further down my script... not finding the ldap_sasl_bind method. Time to dig even more :) – TechFanDan May 10 '12 at 15:51
  • Good luck! I'm not actually using SASL; I'm doing simple binds instead. – Mattie May 10 '12 at 17:11
  • can I, by simply using TLS, say that the username and password combination match what's in AD in a secure channel? – TechFanDan May 10 '12 at 18:04
  • Yes, I'm doing exactly that. The basics: use a resolver account to look up the DN for the username you have, then `ldap_bind` using that DN and password. If it succeeds, you have authenticated. Actually, this is even simpler... http://stackoverflow.com/questions/171519/authenticating-in-php-using-ldap-through-active-directory – Mattie May 10 '12 at 18:31
  • I have that running now, however, the lack of communications over a secure channel makes me hesitant to implement it. Chat isn't accessible from my workplace unfortunately. Is there such a thing as PMs here? – TechFanDan May 10 '12 at 18:32
0

Yes you are required to change the ldap.conf file and change the value of TLS_REQCERT to demand if you are trying to connect with the AD for which the trust has not been established on your host machine running Apache. If you have certificate from a trusted CA i.e. already installed on the machine OS keystore then it may run with the TLS_REQCERT set to never otherwise you will have to explicitly give the certificates and change the variable TLS_REQCERT.

Deepika Sharma
  • 99
  • 1
  • 11