aboutsummaryrefslogtreecommitdiffstats
path: root/auth_ldap.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth_ldap.c')
-rw-r--r--auth_ldap.c77
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,
+};