Share via


ntlm.php

 <?php

// This a copy taken 2008-08-21 from https://siphon9.net/loune/f/ntlm.php.txt to make sure the code is not lost.
// For more information see:
// https://blogs.msdn.com/cellfish/archive/2008/08/26/getting-the-logged-on-windows-user-in-your-apache-server.aspx

// NTLM specs https://davenport.sourceforge.net/ntlm.html

$headers = apache_request_headers();

if (!isset($headers['Authorization'])){
    header('HTTP/1.1 401 Unauthorized');
    header('WWW-Authenticate: NTLM');
   exit;
}

$auth = $headers['Authorization'];

if (substr($auth,0,5) == 'NTLM ') {
 $msg = base64_decode(substr($auth, 5));
 if (substr($msg, 0, 8) != "NTLMSSP\x00")
        die('error header not recognised');

 if ($msg[8] == "\x01") {
        $msg2 = "NTLMSSP\x00\x02"."\x00\x00\x00\x00". // target name len/alloc
          "\x00\x00\x00\x00". // target name offset
           "\x01\x02\x81\x01". // flags
            "\x00\x00\x00\x00\x00\x00\x00\x00". // challenge
            "\x00\x00\x00\x00\x00\x00\x00\x00". // context
          "\x00\x00\x00\x00\x30\x00\x00\x00"; // target info len/alloc/offset

     header('HTTP/1.1 401 Unauthorized');
        header('WWW-Authenticate: NTLM '.trim(base64_encode($msg2)));
       exit;
   }
   else if ($msg[8] == "\x03") {
       function get_msg_str($msg, $start, $unicode = true) {
           $len = (ord($msg[$start+1]) * 256) + ord($msg[$start]);
         $off = (ord($msg[$start+5]) * 256) + ord($msg[$start+4]);
           if ($unicode)
               return str_replace("\0", '', substr($msg, $off, $len));
         else
                return substr($msg, $off, $len);
        }
       $user = get_msg_str($msg, 36);
      $domain = get_msg_str($msg, 28);
        $workstation = get_msg_str($msg, 44);


       print "You are $user from $workstation.$domain";
    }
}

?>

Comments

  • Anonymous
    August 25, 2008
    I was recently involved in a discussion where a company was developing an intra-net site using Apache

  • Anonymous
    November 20, 2008
    but this code is not validating the username and password against the windows logged on username. That is in my case , I don't want the user to get into my webpage if he is not a windows valid user.

  • Anonymous
    November 20, 2008
    That is correct SS and exactly what the linked article says. If you want to actually validate the windows users from your LAMP setup you have to do something else like looking up the users using LDAP.

  • Anonymous
    December 01, 2011
    Been looking for something that did this all day, THIS is exactly what I was looking for and it worked first time, thank you !!!! :D

  • Anonymous
    December 09, 2011
    This code doesn't seem to work with Apache mod_auth_sspi on Windows (PHP 5.3.8).  It passes all the ifchecks and grabs the correct authorization header, but it username/domain just return NULL.  I.e. it ends up saying "You are from ."

  • Anonymous
    December 09, 2011
    Kris, this is a pretty old post and I do not have the possibility to test this. Please post a comment if you figure out what is wrong.

  • Anonymous
    August 21, 2012
    This is great!  Being looking for this for a while!

  • Anonymous
    March 15, 2017
    HAHA, it works! Thank You, now I can get the user experience of SSO for an internal only company site because the users are already validated when accessing the VPN. All I have know is the username so I can make the site behave differently for different departments. If anyone is wondering, this does work if the Uniform Server, specifically Coral 8. Wasn't sure it would since it runs a modified version of Apache.