From 50bb49039b264ac599ad1ddee2be86cfc7cb68ce Mon Sep 17 00:00:00 2001 From: Dennis Kaarsemaker Date: Tue, 23 Feb 2016 20:14:57 +0100 Subject: 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 --- .travis.yml | 5 ++-- auth.c | 9 +++++++ auth_ldap.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ bitlbee.conf | 1 + conf.c | 3 ++- configure | 13 ++++++++++ tests/Makefile | 2 +- 7 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 auth_ldap.c diff --git a/.travis.yml b/.travis.yml index 992ede90..9162ca4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ sudo: false language: c script: - - ./configure --pam=1 + - ./configure --pam=1 --ldap=1 - make check - BITLBEE_SKYPE=plugin dpkg-buildpackage -uc -us -d @@ -29,12 +29,13 @@ addons: - libpurple-dev - check - libpam0g-dev + - libldap2-dev coverity_scan: project: name: "bitlbee/bitlbee" description: "An IRC to other chat networks gateway" notification_email: dx@dxzone.com.ar - build_command_prepend: ./configure --otr=1 --debug=1 --pam=1 + build_command_prepend: ./configure --otr=1 --debug=1 --pam=1 --ldap=1 build_command: make branch_pattern: coverity_scan diff --git a/auth.c b/auth.c index 9717acc1..5a9d8bb8 100644 --- a/auth.c +++ b/auth.c @@ -4,6 +4,9 @@ #ifdef WITH_PAM extern auth_backend_t auth_pam; #endif +#ifdef WITH_LDAP +extern auth_backend_t auth_ldap; +#endif GList *auth_init(const char *backend) { @@ -15,6 +18,12 @@ GList *auth_init(const char *backend) ok = 1; } #endif +#ifdef WITH_LDAP + gl = g_list_append(gl, &auth_ldap); + if (backend && !strcmp(backend, "ldap")) { + ok = 1; + } +#endif return ok ? gl : NULL; } 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 + +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, +}; diff --git a/bitlbee.conf b/bitlbee.conf index d781a7b1..b6544378 100644 --- a/bitlbee.conf +++ b/bitlbee.conf @@ -65,6 +65,7 @@ ## ## - storage (internal storage) ## - pam (Linux PAM authentication) +## - ldap (LDAP server configured in the openldap settings) # # AuthBackend = storage # diff --git a/conf.c b/conf.c index 403f417a..8c2439e7 100644 --- a/conf.c +++ b/conf.c @@ -244,7 +244,8 @@ static int conf_loadini(conf_t *conf, char *file) } else if (g_strcasecmp(ini->key, "authbackend") == 0) { if (g_strcasecmp(ini->value, "storage") == 0) { conf->auth_backend = NULL; - } else if (g_strcasecmp(ini->value, "pam") == 0) { + } else if (g_strcasecmp(ini->value, "pam") == 0 || + g_strcasecmp(ini->value, "ldap") == 0) { g_free(conf->auth_backend); conf->auth_backend = g_strdup(ini->value); } else { diff --git a/configure b/configure index 4c08b034..9cc81794 100755 --- a/configure +++ b/configure @@ -52,6 +52,7 @@ events=glib ssl=auto pam=0 +ldap=0 pie=1 @@ -136,6 +137,7 @@ Option Description Default (automatically disables other protocol modules) --pam=0/1 Disable/enable PAM authentication $pam +--ldap=0/1 Disable/enable LDAP authentication $ldap --doc=0/1 Disable/enable help.txt generation $doc --debug=0/1 Disable/enable debugging $debug @@ -645,6 +647,17 @@ else authobjs=$authobjs'auth_pam.o ' authlibs=$authlibs'-lpam ' fi +if [ "$ldap" = 0 ]; then + echo '#undef WITH_LDAP' >> config.h +else + if ! echo '#include ' | $CC -E - >/dev/null 2>/dev/null; then + echo 'Cannot find libldap development libraries, aborting. (Install libldap2-dev?)' + exit 1 + fi + echo '#define WITH_LDAP' >> config.h + authobjs=$authobjs'auth_ldap.o ' + authlibs=$authlibs'-lldap ' +fi echo AUTH_OBJS=$authobjs >> Makefile.settings echo EFLAGS+=$authlibs >> Makefile.settings diff --git a/tests/Makefile b/tests/Makefile index 77ed2273..7756c17f 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -14,7 +14,7 @@ clean: distclean: clean -main_objs = bitlbee.o conf.o dcc.o help.o ipc.o irc.o irc_cap.o irc_channel.o irc_commands.o irc_im.o irc_send.o irc_user.o irc_util.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o auth.o auth_pam.o +main_objs = bitlbee.o conf.o dcc.o help.o ipc.o irc.o irc_cap.o irc_channel.o irc_commands.o irc_im.o irc_send.o irc_user.o irc_util.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o auth.o auth_pam.o auth_ldap.o test_objs = check.o check_util.o check_nick.o check_md5.o check_arc.o check_irc.o check_help.o check_user.o check_set.o check_jabber_sasl.o check_jabber_util.o -- cgit v1.2.3