--- bitlbee.c	Tue Nov  1 09:13:21 2005
+++ bitlbee.c	Fri Nov  4 12:20:59 2005
@@ -33,6 +33,10 @@
 #include <stdio.h>
 #include <errno.h>
 
+#ifdef WITH_LDAP
+#include <ldap.h>
+#endif /* WITH_LDAP */
+
 gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data )
 {
 	size_t size = sizeof( struct sockaddr_in );
@@ -243,6 +247,9 @@
 
 int bitlbee_load( irc_t *irc, char* password )
 {
+#ifdef WITH_LDAP
+	char dn[512 /* XXX */];
+#endif /* WITH_LDAP */
 	char s[512];
 	char *line;
 	int proto;
@@ -258,11 +265,27 @@
    	if( !fp ) return( 0 );
 	
 	fscanf( fp, "%32[^\n]s", s );
-	if( setpass( irc, password, s ) < 0 )
-	{
-		fclose( fp );
-		return( -1 );
-	}
+#ifdef WITH_LDAP
+	/* do we have an LDAP connection? */
+	if( global.conf->ldap != NULL ) {
+		/* yes. try to bind */
+		g_snprintf (dn, sizeof (dn) - 1, global.conf->ldap_basedn, irc->nick);
+		if (ldap_bind_s (global.conf->ldap, dn, password, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS)
+		{
+			/* this failed! bail out */
+			fclose( fp );
+			return -1;
+		}
+
+		/* activate the password */
+		setpassnc( irc, global.conf->ldap_accountpwd );
+	} else
+#endif /* WITH_LDAP */
+		if( setpass( irc, password, s ) < 0 )
+		{
+			fclose( fp );
+			return( -1 );
+		}
 	
 	/* Do this now. If the user runs with AuthMode = Registered, the
 	   account command will not work otherwise. */
--- commands.c	Sun Sep 11 19:22:23 2005
+++ commands.c	Fri Nov  4 12:48:46 2005
@@ -110,6 +110,9 @@
 
 int cmd_register( irc_t *irc, char **cmd )
 {
+#ifdef WITH_LDAP
+	char dn[512 /* XXX */];
+#endif /* WITH_LDAP */
 	int checkie;
 	char path[512];
 	
@@ -118,6 +121,19 @@
 		irc_usermsg( irc, "This server does not allow registering new accounts" );
 		return( 0 );
 	}
+
+#ifdef WITH_LDAP
+	/* do we have an LDAP connection? */
+	if( global.conf->ldap != NULL ) {
+		/* yes. try to bind */
+		g_snprintf (dn, sizeof (dn) - 1, global.conf->ldap_basedn, irc->nick);
+		if (ldap_bind_s (global.conf->ldap, dn, cmd[1], LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) {
+			/* this failed! bail out */
+			irc_usermsg( irc, "You must register with your original password" );
+			return -1;
+		}
+	}
+#endif /* WITH_LDAP */
 	
 	g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
 	checkie = access( path, F_OK );
@@ -127,7 +143,14 @@
 	
 	if( checkie == -2 )
 	{
-		setpassnc( irc, cmd[1] );
+#ifdef WITH_LDAP
+		if( global.conf->ldap != NULL ) {
+			/* we need to use an fixed password. ldap passwords can change,
+			 * but we must ensure that this one doesn't */
+			setpassnc( irc, global.conf->ldap_accountpwd );
+		} else
+#endif /* WITH_LDAP */
+			setpassnc( irc, cmd[1] );
 		root_command_string( irc, user_find( irc, irc->mynick ), "save", 0 );
 		irc->status = USTATUS_IDENTIFIED;
 	}
--- conf.c	Wed Feb 23 16:47:58 2005
+++ conf.c	Fri Nov  4 12:48:15 2005
@@ -34,6 +34,10 @@
 
 #include "protocols/proxy.h"
 
+#ifdef WITH_LDAP
+#include <ldap.h>
+#endif /* WITH_LDAP */
+
 char *CONF_FILE;
 
 static int conf_loadini( conf_t *conf, char *file );
@@ -56,6 +60,12 @@
 	conf->motdfile = g_strdup( ETCDIR "/motd.txt" );
 	conf->ping_interval = 180;
 	conf->ping_timeout = 300;
+#ifdef WITH_LDAP
+	conf->ldap = NULL;
+	conf->ldap_hosts = NULL;
+	conf->ldap_basedn = NULL;
+	conf->ldap_accountpwd = NULL;
+#endif /* WITH_LDAP */
 	
 	i = conf_loadini( conf, CONF_FILE );
 	if( i == 0 )
@@ -143,6 +153,9 @@
 {
 	ini_t *ini;
 	int i;
+#ifdef WITH_LDAP
+	int version, ssl = 0;
+#endif /* WITH_LDAP */
 	
 	ini = ini_open( file );
 	if( ini == NULL ) return( -1 );
@@ -246,6 +259,33 @@
 				/* For now just ignore unknown keys... */
 			}
 		}
+#ifdef WITH_LDAP
+		else if( g_ascii_strcasecmp( ini->section, "ldap" ) == 0 )
+		{
+			if( g_ascii_strcasecmp( ini->key, "hosts" ) == 0 )
+			{
+				conf->ldap_hosts = g_strdup( ini->value );
+			}
+			else if( g_ascii_strcasecmp( ini->key, "basedn" ) == 0 )
+			{
+				conf->ldap_basedn = g_strdup( ini->value );
+			}
+			else if( g_ascii_strcasecmp( ini->key, "ssl" ) == 0 )
+			{
+				ssl = ((!g_ascii_strcasecmp( ini->value, "yes" )) ||
+				       (!g_ascii_strcasecmp( ini->value, "on" ))) ? 1 : 0;
+			}
+			else if( g_ascii_strcasecmp( ini->key, "accountpassword" ) == 0)
+			{
+				conf->ldap_accountpwd = g_strdup( ini->value );
+			}
+			else
+			{
+				fprintf( stderr, "Error: Unknown setting ldap/`%s` in configuration file.\n", ini->key );
+				return( 0 );
+			}
+		}
+#endif /* WITH_LDAP */
 		else if( g_strcasecmp( ini->section, "defaults" ) != 0 )
 		{
 			fprintf( stderr, "Error: Unknown section [%s] in configuration file. "
@@ -254,6 +294,41 @@
 		}
 	}
 	ini_close( ini );
+
+#ifdef WITH_LDAP
+	/* got a ldap box to connect to? */
+	if (conf->ldap_hosts != NULL) {
+		/* yes. got an base dn? */
+		if (conf->ldap_basedn == NULL) {
+			/* no! bail out */
+			fprintf( stderr, "Error: LDAP services specified but no base DN!\n");
+			return( 0 );
+		}
+		if (conf->ldap_accountpwd == NULL) {
+			fprintf( stderr, "Error: LDAP services specified but no account password!\n");
+			return( 0 );
+		}
+
+		/* try to connect to the LDAP server */
+		if (ldap_initialize( &conf->ldap, conf->ldap_hosts ) != LDAP_SUCCESS) {
+			/* this failed. bail out */
+			fprintf( stderr, "Error: Unable to connect to LDAP server\n");
+			return( 0 );
+		}
+
+		/* we want LDAP version 3! */
+		version = LDAP_VERSION3;
+		ldap_set_option (conf->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
+
+		/* do SSL if needed */
+		if (ssl)
+			if (ldap_start_tls_s( conf->ldap, NULL, NULL ) != LDAP_SUCCESS)
+			{
+				fprintf( stderr, "Error: Can't enable LDAP+TLS\n");
+				return( 0 );
+			}
+	}
+#endif /* WITH_LDAP */
 	
 	return( 1 );
 }
--- conf.h	Thu Mar 18 00:17:45 2004
+++ conf.h	Fri Nov  4 12:14:23 2005
@@ -26,6 +26,13 @@
 #ifndef __CONF_H
 #define __CONF_H
 
+#include "config.h"
+
+#ifdef WITH_LDAP
+#include <ldap.h>
+#endif /* WITH_LDAP */
+ 
+
 typedef enum runmode { RUNMODE_DAEMON, RUNMODE_INETD } runmode_t;
 typedef enum authmode { AUTHMODE_OPEN, AUTHMODE_CLOSED, AUTHMODE_REGISTERED } authmode_t;
 
@@ -43,6 +50,12 @@
 	char *motdfile;
 	int ping_interval;
 	int ping_timeout;
+#ifdef WITH_LDAP
+	LDAP* ldap;
+	char* ldap_hosts;
+	char* ldap_basedn;
+	char* ldap_accountpwd;
+#endif /* WITH_LDAP */
 } conf_t;
 
 conf_t *conf_load( int argc, char *argv[] );
--- configure	Thu Nov  3 21:06:28 2005
+++ configure	Fri Nov  4 12:14:23 2005
@@ -18,6 +18,7 @@
 jabber=1
 oscar=1
 yahoo=1
+ldap=0
 
 debug=0
 strip=1
@@ -59,6 +60,8 @@
 
 --ssl=...	SSL library to use (gnutls, nss, openssl, bogus, auto)
 							$ssl
+--ldap=...	LDAP location if not blank
+							$ldap
 EOF
 		exit;
 	fi
@@ -282,6 +285,12 @@
 	echo '#define FLOOD_SEND' >> config.h
 fi
 
+if [ "$ldap" != "" ]; then
+	echo '#define WITH_LDAP' >> config.h
+	echo 'CFLAGS+=-I'$ldap'/include' >> Makefile.settings
+	echo 'LFLAGS+=-L'$ldap'/lib -lldap' >> Makefile.settings
+fi
+
 if [ -n "$BITLBEE_VERSION" ]; then
 	echo
 	echo 'Spoofing version number: '$BITLBEE_VERSION
@@ -390,6 +399,12 @@
 	echo '  Flood protection disabled.';
 else
 	echo '  Flood protection enabled.';
+fi
+
+if [ "$ldap" = "" ]; then
+	echo '  LDAP authentication disabled.';
+else
+	echo '  LDAP authentication enabled.';
 fi
 
 if [ -n "$protocols" ]; then
