--- rlm_ldap.c	2008-01-05 18:51:50.000000000 +0000
+++ rlm_ldap_mozilla.c	2008-01-23 16:27:55.000000000 +0000
@@ -102,6 +102,10 @@
 
 #endif
 
+#ifndef LDAP_OPT_SUCCESS
+#define LDAP_OPT_SUCCESS LDAP_SUCCESS
+#endif
+
 /* linked list of mappings between RADIUS attributes and LDAP attributes */
 struct TLDAP_RADIUS {
 	char*                 attr;
@@ -406,11 +410,13 @@
 
 	inst->timeout.tv_usec = 0;
 	inst->net_timeout.tv_usec = 0;
+#ifdef LDAP_OPT_X_TLS_HARD
 	/* workaround for servers which support LDAPS but not START TLS */
 	if(inst->port == LDAPS_PORT || inst->tls_mode)
 		inst->tls_mode = LDAP_OPT_X_TLS_HARD;
 	else
 		inst->tls_mode = 0;
+#endif
 	inst->reply_item_map = NULL;
 	inst->check_item_map = NULL;
 	inst->conns = NULL;
@@ -2153,7 +2159,12 @@
 	int             msgid, rc, ldap_version;
 	int		ldap_errno = 0;
 	LDAPMessage    *res;
-
+#ifdef LDAP_X_OPT_CONNECT_TIMEOUT
+	int		ctimeout;
+#endif
+#ifdef HAVE_LDAPSSL_ADVCLIENTAUTH_INIT
+	int		sslstrength;
+#endif
 	if (inst->is_url){
 #ifdef HAVE_LDAP_INITIALIZE
 		DEBUG("rlm_ldap: (re)connect to %s, authentication %d", inst->server, auth);
@@ -2164,27 +2175,50 @@
 		}
 #endif
 	} else {
+#ifdef HAVE_LDAPSSL_ADVCLIENTAUTH_INIT
+	        if(inst->port != LDAPS_PORT && !inst->tls_mode) {
+			DEBUG("rlm_ldap: (re)connect to %s:%d, authentication %d", inst->server, inst->port, auth);
+			if ((ld = ldap_init(inst->server, inst->port)) == NULL) {
+				radlog(L_ERR, "rlm_ldap: ldap_init() failed");
+				*result = RLM_MODULE_FAIL;
+				return (NULL);
+			}
+		}
+#else
 		DEBUG("rlm_ldap: (re)connect to %s:%d, authentication %d", inst->server, inst->port, auth);
 		if ((ld = ldap_init(inst->server, inst->port)) == NULL) {
 			radlog(L_ERR, "rlm_ldap: ldap_init() failed");
 			*result = RLM_MODULE_FAIL;
 			return (NULL);
 		}
+#endif
 	}
+
+#ifdef LDAP_X_OPT_CONNECT_TIMEOUT
+	ctimeout=inst->net_timeout.tv_sec*1000;
+        if (ldap_set_option(ld, LDAP_X_OPT_CONNECT_TIMEOUT,
+                            (void *) &ctimeout) != LDAP_OPT_SUCCESS) {
+                radlog(L_ERR, "rlm_ldap: Could not set LDAP_OPT_NETWORK_TIMEOUT %ld", ctimeout); 
+        }
+#endif
+
+#ifdef LDAP_OPT_NETWORK_TIMEOUT
 	if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT,
 			    (void *) &(inst->net_timeout)) != LDAP_OPT_SUCCESS) {
 		radlog(L_ERR, "rlm_ldap: Could not set LDAP_OPT_NETWORK_TIMEOUT %ld.%ld", inst->net_timeout.tv_sec, inst->net_timeout.tv_usec);
 	}
-
+#endif
+#ifdef LDAP_OPT_TIMELIMIT
 	if (ldap_set_option(ld, LDAP_OPT_TIMELIMIT,
 			    (void *) &(inst->timelimit)) != LDAP_OPT_SUCCESS) {
 		radlog(L_ERR, "rlm_ldap: Could not set LDAP_OPT_TIMELIMIT %d", inst->timelimit);
 	}
-
+#endif
+#ifdef LDAP_OPT_DEBUG_LEVEL
 	if (inst->ldap_debug && ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &(inst->ldap_debug)) != LDAP_OPT_SUCCESS) {
 		radlog(L_ERR, "rlm_ldap: Could not set LDAP_OPT_DEBUG_LEVEL %d", inst->ldap_debug);
 	}
-
+#endif
 	ldap_version = LDAP_VERSION3;
 	if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
 			    &ldap_version) != LDAP_OPT_SUCCESS) {
@@ -2292,6 +2326,56 @@
 	}
 #endif /* HAVE_LDAP_START_TLS */
 
+#ifdef HAVE_LDAPSSL_ADVCLIENTAUTH_INIT
+        if (inst->tls_cacertdir != NULL) {
+                DEBUG("rlm_ldap: setting TLS CACert Directory to %s", inst->tls_cacertdir);
+        }
+/* 
+ * allow => 
+ * LDAPSSL_AUTH_WEAK indicates that you accept the server's certificate without checking 
+ *                   the CA who issued the certificate.
+ * demand =>
+ * LDAPSSL_AUTH_CERT indicates that you accept the server's certificate only if you trust 
+ *                   the CA who issued the certificate.
+ * strict =>
+ * LDAPSSL_AUTH_CNCHECK indicates that you accept the server's certificate only if you trust
+ *                      the CA who issued the certificate and if the value of the cn attribute
+ *                      is the DNS hostname of the server. 
+ * try,never => invalid
+ */
+	sslstrength = LDAPSSL_AUTH_WEAK;
+        if (strcmp(TLS_DEFAULT_VERIFY, inst->tls_require_cert ) != 0 ) {
+                DEBUG("rlm_ldap: setting TLS Require Cert to %s",
+                      inst->tls_require_cert);
+		if (strcmp(inst->tls_require_cert,"demand") == 0)
+			sslstrength=LDAPSSL_AUTH_CERT;
+		else if (strcmp(inst->tls_require_cert,"strict") == 0)
+			sslstrength=LDAPSSL_AUTH_CNCHECK;
+		else
+			DEBUG("rlm_ldap: invalid TLS Require Cert value %s",
+		                        inst->tls_require_cert);
+        }
+        if(inst->port == LDAPS_PORT || inst->tls_mode) {
+        	DEBUG("rlm_ldap: starting SSL");
+        	rc = ldapssl_advclientauth_init( inst->tls_cacertdir, NULL , 0 , NULL, NULL, 0, NULL, sslstrength);
+        	if (rc != LDAP_SUCCESS) {
+			DEBUG("rlm_ldap: ldapssl_advclientauth_init()");
+                	ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER,
+                                	&ldap_errno);
+                	radlog(L_ERR, "rlm_ldap: could not start SSL %s",
+                       	       ldap_err2string(ldap_errno));
+                	*result = RLM_MODULE_FAIL;
+                	return (NULL);
+		}
+		DEBUG("rlm_ldap: (re)connect to %s:%d, authentication %d", inst->server, inst->port, auth);
+		if ((ld = ldapssl_init(inst->server, inst->port, 1)) == NULL) {
+			radlog(L_ERR, "rlm_ldap: ldap_init() failed");
+			*result = RLM_MODULE_FAIL;
+			return (NULL);
+		}
+        }
+#endif /* HAVE_LDAPSSL_ADVCLIENTAUTH_INIT */
+
 	if (inst->is_url){
 		DEBUG("rlm_ldap: bind as %s/%s to %s",
 		      dn, password, inst->server);
