#!/usr/bin/perl -w

#
# inn-ldapcheck.pl
# 
# Perl version of inn-ldapcheck with additional hacks for ONN
#
# (no admin auth version)
# 
# 2005-12-16 Michael Bussmann <info@mb-net.net>
#

use strict;

use Net::LDAP;		# libnet-ldap-perl 1:0.33-2
use Getopt::Std;
use URI::ldap;

#
# Unhelpful help message
#
sub HELP_MESSAGE()
{
	print <<"EOR";
Usage: inn-ldapcheck.pl [-dwhbHd]
 	-D dn	sets bind DN
 	-h host	sets LDAP server name to connect to
 	-b dn	sets search base DN
 	-H str	ONN hostname
 	-d 	Enables debugging
EOR

	exit 0;
}

#
# Prints debugging info if requested
#
sub debug(@)
{
	print STDERR @_ if ($main::debugp);
}

# -------------------------------------------------------------------------
# Main
# -------------------------------------------------------------------------

my ($username) = "";
my ($password) = "";
my ($ldap);

sub ldap_authenticate();

#
# Parse command line params
#
our($opt_h,$opt_b,$opt_H,$opt_d);
&getopts('h:b:Hd');

our($LDAP_SERVER, $LDAP_SEARCH_BASE, $ONN_HOSTNAME, $debugp);

$LDAP_SERVER=$opt_h || 'XXXX';
$LDAP_SEARCH_BASE=$opt_b || "XXXX";

$ONN_HOSTNAME=$opt_H || "XXX";

$debugp = $opt_d || "";

#
#
# Read from stdin until EOF, parsing INN authentication tokens
#
while (<>) {
	chop;

	debug("Reading: \"$_\"\n");

	if (/^ClientAuthname: (.+)/) { $username="$1"; debug("Found username \"$username\"\n"); }
	if (/^ClientPassword: (.+)/) { $password="$1"; debug("Found password \"$password\"\n"); }
}

debug("End of input\n");

exit(3) if ($username eq "");
exit(3) if ($password eq "");

#
# TODO: Sanitize username
#

debug("About to authenticate user \"$username\" with password \"$password\"\n");

if (ldap_authenticate()) {
	print STDERR "valid passwd\n";
	print "User:$username\n";
	exit(0);
}
exit(1);

sub ldap_authenticate()
{
	my ($count, $entry, $mesg);
	my ($now)=time;
	my ($userdn)="uid=$username,$LDAP_SEARCH_BASE";

	#
	# Bind to LDAP server
	#

	# Open connection to host
	debug("Opening connection to \"$LDAP_SERVER\"\n");
	unless ($ldap=Net::LDAP->new($LDAP_SERVER,
			timeout=> 30,
			version => 3)) {
		print STDERR "cannot connect LDAP server $LDAP_SERVER: $@\n";
		return(0);
	}

	#
	# Perform auth bind
	#
	debug("Performing authbind as DN=\"$userdn\" with password \"$password\"\n");
	$mesg=$ldap->bind("$userdn", password=>"$password",version => 3);
	if ($mesg->code) {
		debug("Could not bind as $userdn: $@\n");
		print STDERR "$username not authenticated with $password\n";
		return(0);
	}
	debug("Authbind succeeded\n");

	#
	# Don't look at this
	#
	debug("Updating time of login to $now for $ONN_HOSTNAME\n");
	#$mesg=$ldap->modify("$userdn", replace => { 'description' => "$ONN_HOSTNAME $now" });

	#if ($mesg->code) {
	#	if ($mesg->error_name() eq "LDAP_REFERRAL") {
	#		my (@ref) = $mesg->referrals();
	#		debug("Received referral (as expected)\n");
	#		map {
	#			my $newdn=$_;
	#			debug("Referred to: \"$_\"\n");
	#		} @ref;
	#	} else {
	#		# No referral, print (but ignore error)
	#		debug("Could not change login time of \"$userdn\" to $now: " . $mesg->error() . "\n");
	#	}
	#}

	# Close connection
	$ldap->unbind;
	return(1);
}
