aboutsummaryrefslogtreecommitdiffstats
path: root/auth_ldap.c
diff options
context:
space:
mode:
authorDennis Kaarsemaker <dennis@kaarsemaker.net>2016-02-23 20:14:57 +0100
committerDennis Kaarsemaker <dennis@kaarsemaker.net>2016-03-25 19:07:53 +0100
commit50bb49039b264ac599ad1ddee2be86cfc7cb68ce (patch)
treecf8bbc7389ba680db21a68209d0298a35a7ebac2 /auth_ldap.c
parenta6005da78ae1563ae4577179d1e54fff74cfe21a (diff)
ldap authentication backend
We only support the openldap scheme for now, with users that are posixAccounts. Moreover, as the plugin cannot be configured directly, you must configure libldap correctly in /etc/openldap/ldap.conf
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,
+};