no warnings qw(redefine);

# {{{ sub IsPassword 

# Modification Originally by Marcelo Bartsch <bartschm_cl@hotmail.com>
# Update by Stewart James <stewart.james@vu.edu.au for rt3.
# Drop this file in /opt/rt3/lib/RT/User_Local.pm
# Drop something like below in yout RT_SiteConfig.pm
# $LDAPExternalAuth = 1;
# $LdapServer="ldap.domain.com";
# $LdapUser=""; 
# $LdapPass="";
# $LdapBase="dc=domain,dc=com";
# $LdapUidAttr="uid";
# $LdapFilter="(objectclass=*)";


sub IsPassword {
	my $self  = shift;
	my $value = shift;

	#TODO there isn't any apparent way to legitimately ACL this

	# RT does not allow null passwords 
	if ( ( !defined($value) ) or ( $value eq '' ) ) {
		return (undef);
	}

	if ( $self->PrincipalObj->Disabled ) {
		$RT::Logger->info(
			"Disabled user " . $self->Name . " tried to log in" );
		return (undef);
	}

	if ( ($self->__Value('Password') eq '') || 
		($self->__Value('Password') eq undef) )  {
		return(undef);
	}

	# generate an md5 password 
	if ($self->_GeneratePassword($value) eq $self->__Value('Password')) {
		return(1);
	}

	#  if it's a historical password we say ok.

	if (! $RT::LDAPExternalAuth)
	{
		if ($self->__Value('Password') eq crypt($value, $self->__Value('Password'))) {
			return (1);
		}
		else {
			return (undef);
		}
	}
	else
	{
		if ($self->__Value('Password') eq crypt($value, $self->__Value('Password'))) {
			return (1);
		}
		$RT::Logger->info("Using External Authentication\n");
		use Net::LDAP qw(LDAP_SUCCESS LDAP_PARTIAL_RESULTS);
		use Net::LDAP::Util qw (ldap_error_name);
		
		my $mesg;
		my $ldap = Net::LDAP->new($RT::LdapServer, version=>3) or $RT::Logger->critical("GetExternalUserWithLDAP: " . "Cannot connect to LDAP'\n"), return 0;

		# Iseem to have problems is I try and bind with a NULL username by hand
		# So this now checks to see if we are really going to bind with a 
		# username.
		if (defined($RT::LdapUser) && $RT::LdapUser != '') {
			$mesg = $ldap->bind($RT::LdapUser, password =>$RT::LdapPass );
		} else {
			$mesg = $ldap->bind;
		}
		if ($mesg->code != LDAP_SUCCESS) {
			$RT::Logger->critical("GetExternalUserWithLDAP: Cannot bind to LDAP:",
				$mesg->code, "\n");
			return 0;
		}

		my $filter = "(&(&(objectclass=person)(" . $RT::LdapUidAttr . "=" . $self->Name ."))$RT::LdapFilter)";
		$RT::Logger->debug("GetExternalUserWithLDAP: First search filter '$filter'\n");
		$mesg = $ldap->search(base   => $RT::LdapBase,
			filter => $filter,
			attrs  => ['dn']);
#		if (($mesg->code != LDAP_SUCCESS) or ($mesg->code != LDAP_PARTIAL_RESULTS))
		if (!(($mesg->code == LDAP_SUCCESS) or ($mesg->code == LDAP_PARTIAL_RESULTS)))
		{
			$RT::Logger->debug("GetExternalUserWithLDAP: Could not search for $filter: ",
				$mesg->code, "" , ldap_error_name($mesg->code) ,"\n");
			return 0;
		}
		$RT::Logger->debug("GetExternalUserWithLDAP: First search produced ",
			$mesg->count, " results\n");
		if (! $mesg->count)
		{
			$RT::Logger->info("AUTH FAILED: " . $self->Name . "\n");
			return 0;
		}
		$RT::Logger->debug("LDAP DN: " . $mesg->first_entry->dn . " " . $value . "\n");
		my $mesg2 = $ldap->bind($mesg->first_entry->dn, password =>$value );
		if ($mesg2->code != LDAP_SUCCESS) {
			$RT::Logger->critical("GetExternalUserWithLDAP: Cannot bind to LDAP:",
				$mesg2->code, "\n");
			return 0;
		}
		else
		{
			$RT::Logger->info("AUTH OK: " . $self->Name . " (" .$mesg->first_entry->dn . ")\n");
			return 1;
		}
	}




	# no password check has succeeded. get out

	return (undef);
}

# }}}

1;
