diff options
Diffstat (limited to 'auth_ldap.c')
| -rw-r--r-- | auth_ldap.c | 77 | 
1 files changed, 77 insertions, 0 deletions
| diff --git a/auth_ldap.c b/auth_ldap.c new file mode 100644 index 00000000..e2cff8f7 --- /dev/null +++ b/auth_ldap.c @@ -0,0 +1,77 @@ +#define BITLBEE_CORE +#define LDAP_DEPRECATED 1 +#include "bitlbee.h" +#include <ldap.h> + +static storage_status_t ldap_check_pass(const char *nick, const char *password) +{ +	LDAP *ldap; +	LDAPMessage *msg, *entry; +	char *dn = NULL; +	char *filter; +	char *attrs[1] = { NULL }; +	int ret, count; + +	if((ret = ldap_initialize(&ldap, NULL)) != LDAP_SUCCESS) { +		log_message(LOGLVL_WARNING, "ldap_initialize failed: %s", ldap_err2string(ret)); +		return STORAGE_OTHER_ERROR; +	} + +	/* First we do an anonymous bind to map uid=$nick to a DN*/ +	if((ret = ldap_simple_bind_s(ldap, NULL, NULL)) != LDAP_SUCCESS) { +		ldap_unbind_s(ldap); +		log_message(LOGLVL_WARNING, "Anonymous bind failed: %s", ldap_err2string(ret)); +		return STORAGE_OTHER_ERROR; +	} + + +	/* We search and process the result */ +	filter = g_strdup_printf("(uid=%s)", nick); +	ret = ldap_search_ext_s(ldap, NULL, LDAP_SCOPE_SUBTREE, filter, attrs, 0, NULL, NULL, NULL, 1, &msg); +	g_free(filter); + +	if(ret != LDAP_SUCCESS) { +		ldap_unbind_s(ldap); +		log_message(LOGLVL_WARNING, "uid search failed: %s", ldap_err2string(ret)); +		return STORAGE_OTHER_ERROR; +	} + +	count = ldap_count_entries(ldap, msg); +	if (count == -1) { +		ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &ret); +		ldap_msgfree(msg); +		ldap_unbind_s(ldap); +		log_message(LOGLVL_WARNING, "uid search failed: %s", ldap_err2string(ret)); +		return STORAGE_OTHER_ERROR; +	} + +	if (!count) { +		ldap_msgfree(msg); +		ldap_unbind_s(ldap); +		return STORAGE_NO_SUCH_USER; +	} + +	entry = ldap_first_entry(ldap, msg); +	dn = ldap_get_dn(ldap, entry); +	ldap_msgfree(msg); + +	/* And now we bind as the user to authenticate */ +	ret = ldap_simple_bind_s(ldap, dn, password); +	g_free(dn); +	ldap_unbind_s(ldap); + +	switch (ret) { +		case LDAP_SUCCESS: +			return STORAGE_OK; +		case LDAP_INVALID_CREDENTIALS: +			return STORAGE_INVALID_PASSWORD; +		default: +			log_message(LOGLVL_WARNING, "Authenticated bind failed: %s", ldap_err2string(ret)); +			return STORAGE_OTHER_ERROR; +	} +} + +auth_backend_t auth_ldap = { +	.name = "ldap", +	.check_pass = ldap_check_pass, +}; | 
