<?
/*
 * Copyright 2007 Edmundo Carmona <eantoranz at gmail dot com>
 *
 * This file is a squid helper that authenticates users against
 * ActiveDirectory through LDAP.
 *
 * This helper is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2 of the License,
 * or (at your option) any later version.
 *
 * This helper is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this helper; if not, write to the Free Software
 * Foundation, Inc., * 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA
 */

$PERMIT = "OK\n";
$FORBID = "ERR\n";

$realm = 'MYREALM'; // realm in case it's not provided by the user
$server = '192.168.0.1'; // ldap server
$baseDN = 'DC=MYDOMAIN,DC=ORG'; // base DN

$allUsersPermitted = false; // all authenticated users are permitted to go through. If not, set the next two variables
$usernameField = 'sAMAccountName'; // sAMAccountName works for ActiveDirectory
$internetAccessGroup = "CN=Internet,$baseDN"; // group where internet users belong in the Active Directory

if (! defined(STDIN)) {
	define("STDIN", fopen("php://stdin", "r"));
}

function check($link, $baseDN, $realm, $allUsersPermitted, $usernameField, $internetAccessGroup, $username, $password) {

	
	if (! @ldap_bind($link, $username, $password)) {
		// not a valid user
		return false;
	} 
	// it's a valid username / password pair
	if ($allUsersPermitted) {
		// all domain users are allowed to go through
		return true;
	}

	// let's strip the username from the realm
	$username = explode("\\", $username);
	$username = $username[1];

	$query = @ldap_search($link, $baseDN, "(&($usernameField=$username)(memberOf=$internetAccessGroup))");
	if (! $query) {
		// query was wrong
		return false;
	}

	// query was correct
	return @ldap_first_entry($link, $query);
}

while (!feof(STDIN)) {
        $line = trim(fgets(STDIN)); // the line will be received with a \n at the end, so we trim it
        $fields = explode(' ', $line); // username and password are separated by a white space
	if (count($fields) < 2) {
		// not enough fields
		echo $FORBID;
		continue;
	}
        $username = rawurldecode($fields[0]); // RFC 1738
        $password = rawurldecode($fields[1]); // RFC 1738

	// does the username have the realm?
	if (! strpos($username, "\\")) {
		// it doesn't. Let's add it
		$username = $realm . "\\" . $username;
	}

	// the link will never fail
	$link = @ldap_connect($server);

	if (check($link, $baseDN, $realm, $allUsersPermitted, $usernameField, $internetAccessGroup, $username, $password)) {
		echo $PERMIT;
	} else {
		echo $FORBID;
	}
}
?>
