I've developed a patch against Exim 3.33 that adds a lookup type
called 'ldapauth'. It's similar to the other LDAP lookups except
this one returns a "yes" or a "no" depending on if the connection
to the LDAP server sucessfully completes a non-anonymous bind.
Here's an example of how I use it:
login:
driver = plaintext
public_name = LOGIN
server_prompts = "Username:: : Password::"
server_condition = ${lookup ldapauth {user="uid=${quote_ldap:$1},ou=people,o=example.org" pass="$2" ldap://ldap.example.org/}{$value} fail}
server_set_id = uid=$1,ou=people,o=example.org
The code has been minimally tested so far, but I'm fairly confident in it.
Here's the patch:
--- src/lookups/ldap.c.orig Wed Oct 3 07:34:12 2001
+++ src/lookups/ldap.c Thu Oct 4 08:46:51 2001
@@ -77,7 +77,7 @@
#define SEARCH_LDAP_MULTIPLE 0 /* Get attributes from multiple entries */
#define SEARCH_LDAP_SINGLE 1 /* Get attributes from one entry only */
#define SEARCH_LDAP_DN 2 /* Get DN from one entry */
-
+#define SEARCH_LDAP_AUTH 3 /* Just checking for authentication */
/* Structure and anchor for caching connections. */
@@ -157,9 +157,16 @@
debug_printf("perform_ldap_search: ldap%s URL =\"%s\" server=%s port=%d "
"sizelimit=%d timelimit=%d\n",
(search_type == SEARCH_LDAP_MULTIPLE)? "m" :
- (search_type == SEARCH_LDAP_DN)? "dn" : "",
+ (search_type == SEARCH_LDAP_DN)? "dn" :
+ (search_type == SEARCH_LDAP_AUTH)? "auth" : "",
ldap_url, server, s_port, sizelimit, timelimit);
+if (search_type == SEARCH_LDAP_AUTH && (user == NULL || password == NULL))
+ {
+ *errmsg = string_copy_malloc("ldapauth lookups must specify the username and password");
+ goto RETURN_ERROR;
+ }
+
/* Check if LDAP thinks the URL is a valid LDAP URL */
if (!ldap_is_ldap_url(ldap_url))
@@ -233,6 +240,8 @@
lcp = store_malloc(sizeof(LDAP_CONNECTION));
lcp->host = (host == NULL)? NULL : string_copy_malloc(host);
lcp->bound = FALSE;
+ lcp->user = NULL;
+ lcp->password = NULL;
lcp->port = port;
lcp->ld = ld;
lcp->next = ldap_connections;
@@ -263,6 +272,11 @@
if ((rc = ldap_bind_s(lcp->ld, user, password, LDAP_AUTH_SIMPLE))
!= LDAP_SUCCESS)
{
+ if (search_type == SEARCH_LDAP_AUTH)
+ {
+ data = string_copy_malloc("no");
+ goto RETURN_OK;
+ }
*errmsg = string_sprintf("failed to bind the LDAP connection to server "
"%s:%d - LDAP error %d: %s", host, port, rc, ldap_err2string(rc));
goto RETURN_ERROR;
@@ -272,6 +286,15 @@
lcp->password = (password == NULL)? NULL : string_copy_malloc(password);
}
+if (search_type == SEARCH_LDAP_AUTH)
+ {
+ if (lcp->bound && lcp->user != NULL && lcp->password != NULL)
+ data = string_copy_malloc("yes");
+ else
+ data = string_copy_malloc("no");
+ goto RETURN_OK;
+ }
+
/* Before doing the search, set the time and size limits (if given). Here again
the different implementations of LDAP have chosen to do things differently. */
@@ -515,7 +538,7 @@
}
/* Otherwise, it's all worked */
-
+RETURN_OK:
DEBUG(9) debug_printf("LDAP search: returning: %s\n", data);
*res = data;
ldap_free_urldesc(ludp);
@@ -672,6 +695,13 @@
return(control_ldap_search(ldap_url, SEARCH_LDAP_DN, result, errmsg));
}
+int
+eldapauth_find(void *handle, char *filename, char *ldap_url, int length,
+ char **result, char **errmsg)
+{
+return(control_ldap_search(ldap_url, SEARCH_LDAP_AUTH, result, errmsg));
+}
+
/*************************************************
@@ -705,6 +735,8 @@
ldap_unbind(lcp->ld);
ldap_connections = lcp->next;
if (lcp->host != NULL) store_free(lcp->host);
+ if (lcp->user != NULL) store_free(lcp->user);
+ if (lcp->password != NULL) store_free(lcp->password);
store_free(lcp);
}
}
--- src/lookups/ldap.h.orig Wed Oct 3 07:34:21 2001
+++ src/lookups/ldap.h Wed Oct 3 08:06:19 2001
@@ -11,6 +11,7 @@
extern int eldap_find(void *, char *, char *, int, char **, char **);
extern int eldapdn_find(void *, char *, char *, int, char **, char **);
extern int eldapm_find(void *, char *, char *, int, char **, char **);
+extern int eldapauth_find(void *, char *, char *, int, char **, char **);
extern void eldap_tidy(void);
extern char *eldap_quote(char *);
--- src/drtables.c.orig Wed Aug 15 06:09:08 2001
+++ src/drtables.c Wed Oct 3 08:05:01 2001
@@ -174,6 +174,23 @@
#endif
},
+/* LDAP lookup, just checking for authentication */
+
+ {
+ "ldapauth", /* lookup name */
+ lookup_querystyle, /* query-style lookup */
+#ifdef LOOKUP_LDAP
+ eldap_open, /* sic */ /* open function */
+ NULL, /* check function */
+ eldapauth_find, /* find function */
+ NULL, /* no close function */
+ eldap_tidy, /* sic */ /* tidy function */
+ eldap_quote /* sic */ /* quoting function */
+#else
+ NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
+#endif
+ },
+
/* LDAP lookup, allowing data from more than one entry to be returned */
{