Regarding to a recent post I put here about Kerberos and Apache, there is a way to replace Kerberos when the Active Directory cannot be properly configured to accept Kerberos connections. You can simulate the NTLM auth process with the browser by 6 steps in PHP :
function get_login() {
/*
step: | type:
-------|----------------|------------------------------------
1 | C --> S | GET ...
-------|----------------|------------------------------------
2 | C <-- S | 401 Unauthorized
| | WWW-Authenticate: NTLM
-------|----------------|------------------------------------
3 | C --> S | GET ...
| | Authorization: NTLM
| | <base64-encoded type-1-message>
-------|----------------|------------------------------------
4 | C <-- S | 401 Unauthorized
| | WWW-Authenticate: NTLM
| | <base64-encoded type-2-message>
-------|----------------|------------------------------------
5 | C --> S | GET ...
| | Authorization: NTLM <base64-encoded type-3-message>
-------|----------------|------------------------------------
6 | C <-- S | 200 Ok
-------|----------------|------------------------------------
*/
$headers = apache_request_headers();
if($headers['Authorization'] == NULL) { // step 1
header( "HTTP/1.1 401 Unauthorized" ); // step 2
header( "WWW-Authenticate: NTLM" );
exit;
};
if(isset($headers['Authorization'])
&& substr($headers['Authorization'],0,5) == 'NTLM ') {
// step 3 to 6
$chaine=$headers['Authorization'];
$chaine=substr($chaine, 5); // type1 message
$chained64=base64_decode($chaine);
if(ord($chained64{8}) == 1) { // step 3
// check NTLM flag "0xb2",
// offset 13 in type-1-message :
if (ord($chained64[13]) != 178) {
echo "Please use NTLM compatible browser";
return null;
}
$retAuth = "NTLMSSP";
$retAuth .= chr(0).chr(2).chr(0).chr(0);
$retAuth .= chr(0).chr(0).chr(0).chr(0);
$retAuth .= chr(0).chr(40).chr(0).chr(0);
$retAuth .= chr(0).chr(1).chr(130).chr(0);
$retAuth .= chr(0).chr(0).chr(2).chr(2);
$retAuth .= chr(2).chr(0).chr(0).chr(0);
$retAuth .= chr(0).chr(0).chr(0).chr(0);
$retAuth .= chr(0).chr(0).chr(0).chr(0).chr(0);
$retAuth64 =base64_encode($retAuth);
$retAuth64 = trim($retAuth64);
header( "HTTP/1.1 401 Unauthorized" ); // step 4
header( "WWW-Authenticate: NTLM $retAuth64" );
exit;
}
else if(ord($chained64{8}) == 3) { // step 5
$lenght_domain = (ord($chained64[31])*256 + ord($chained64[30]));
$offset_domain = (ord($chained64[33])*256 + ord($chained64[32]));
$domain = substr($chained64, $offset_domain, $lenght_domain);
$lenght_login = (ord($chained64[39])*256 + ord($chained64[38]));
$offset_login = (ord($chained64[41])*256 + ord($chained64[40]));
$login = substr($chained64, $offset_login, $lenght_login);
$lenght_host = (ord($chained64[47])*256 + ord($chained64[46]));
$offset_host = (ord($chained64[49])*256 + ord($chained64[48]));
$host = substr($chained64, $offset_host, $lenght_host);
}
}
$login = preg_replace("/(.)(.)/","$1",$login);
$domain = preg_replace("/(.)(.)/","$1",$domain);
$login = strtolower($login);
$domain = strtoupper($domain);
return array($login,$domain); // step 6 : accept
}