X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcore%2Fldapauthenticator.cpp;h=e7dc3c0c601662e16f30580c1a9b74538c5d8353;hp=34768faaec601d574473094beac44d78f0cae345;hb=8c6448c2e0048389fbac9e2e9daf22b5b050d5b6;hpb=cfbd4daee17dbb3c4052d938bf33edd08711d728 diff --git a/src/core/ldapauthenticator.cpp b/src/core/ldapauthenticator.cpp index 34768faa..e7dc3c0c 100644 --- a/src/core/ldapauthenticator.cpp +++ b/src/core/ldapauthenticator.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2016 by the Quassel Project * + * Copyright (C) 2005-2018 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -28,7 +28,6 @@ #include "ldapauthenticator.h" -#include "logger.h" #include "network.h" #include "quassel.h" @@ -41,28 +40,24 @@ #include //#endif -LdapAuthenticator::LdapAuthenticator(QObject *parent) - : Authenticator(parent), - _connection(0) -{ -} - +LdapAuthenticator::LdapAuthenticator(QObject* parent) + : Authenticator(parent) + , _connection(nullptr) +{} LdapAuthenticator::~LdapAuthenticator() { - if (_connection != 0) { - ldap_unbind_ext(_connection, 0, 0); + if (_connection != nullptr) { + ldap_unbind_ext(_connection, nullptr, nullptr); } } - bool LdapAuthenticator::isAvailable() const { // FIXME: probably this should test if we can speak to the LDAP server. return true; } - QString LdapAuthenticator::backendId() const { // We identify the backend to use for the monolithic core by this identifier. @@ -71,65 +66,71 @@ QString LdapAuthenticator::backendId() const return QString("LDAP"); } - QString LdapAuthenticator::displayName() const { return tr("LDAP"); } - QString LdapAuthenticator::description() const { return tr("Authenticate users using an LDAP server."); } - QVariantList LdapAuthenticator::setupData() const { // The parameters needed for LDAP. QVariantList data; - data << "Hostname" << tr("Hostname") << QString{"ldap://localhost"} - << "Port" << tr("Port") << DEFAULT_LDAP_PORT - << "BindDN" << tr("Bind DN") << QString{} - << "BindPassword" << tr("Bind Password") << QString{} - << "BaseDN" << tr("Base DN") << QString{} - << "Filter" << tr("Filter") << QString{} - << "UidAttribute" << tr("UID Attribute") << QString{"uid"} - ; + data << "Hostname" << tr("Hostname") << QString{"ldap://localhost"} << "Port" << tr("Port") << DEFAULT_LDAP_PORT << "BindDN" + << tr("Bind DN") << QString{} << "BindPassword" << tr("Bind Password") << QString{} << "BaseDN" << tr("Base DN") << QString{} + << "Filter" << tr("Filter") << QString{} << "UidAttribute" << tr("UID Attribute") << QString{"uid"}; return data; } - -void LdapAuthenticator::setAuthProperties(const QVariantMap &properties) +void LdapAuthenticator::setAuthProperties(const QVariantMap& properties, const QProcessEnvironment& environment, bool loadFromEnvironment) { - _hostName = properties["Hostname"].toString(); - _port = properties["Port"].toInt(); - _bindDN = properties["BindDN"].toString(); - _bindPassword = properties["BindPassword"].toString(); - _baseDN = properties["BaseDN"].toString(); - _filter = properties["Filter"].toString(); - _uidAttribute = properties["UidAttribute"].toString(); + if (loadFromEnvironment) { + _hostName = environment.value("AUTH_LDAP_HOSTNAME"); + _port = environment.value("AUTH_LDAP_PORT").toInt(); + _bindDN = environment.value("AUTH_LDAP_BIND_DN"); + _bindPassword = environment.value("AUTH_LDAP_BIND_PASSWORD"); + _baseDN = environment.value("AUTH_LDAP_BASE_DN"); + _filter = environment.value("AUTH_LDAP_FILTER"); + _uidAttribute = environment.value("AUTH_LDAP_UID_ATTRIBUTE"); + } + else { + _hostName = properties["Hostname"].toString(); + _port = properties["Port"].toInt(); + _bindDN = properties["BindDN"].toString(); + _bindPassword = properties["BindPassword"].toString(); + _baseDN = properties["BaseDN"].toString(); + _filter = properties["Filter"].toString(); + _uidAttribute = properties["UidAttribute"].toString(); + } } // TODO: this code is sufficiently general that in the future, perhaps an abstract // class should be created implementing it. // i.e. a provider that does its own thing and then pokes at the current storage // through the default core method. -UserId LdapAuthenticator::validateUser(const QString &username, const QString &password) +UserId LdapAuthenticator::validateUser(const QString& username, const QString& password) { bool result = ldapAuth(username, password); if (!result) { - return UserId(); + return {}; } + // LDAP is case-insensitive, thus we will lowercase the username, in spite of + // a better solution :( + const QString lUsername = username.toLower(); + // If auth succeeds, but the user has not logged into quassel previously, make // a new user for them and return that ID. // Users created via LDAP have empty passwords, but authenticator column = LDAP. // On the other hand, if auth succeeds and the user already exists, do a final // cross-check to confirm we're using the right auth provider. - UserId quasselId = Core::validateUser(username, QString()); + UserId quasselId = Core::validateUser(lUsername, QString()); if (!quasselId.isValid()) { - return Core::addUser(username, QString(), backendId()); + return Core::addUser(lUsername, QString(), backendId()); } else if (!(Core::checkAuthProvider(quasselId, backendId()))) { return 0; @@ -137,33 +138,31 @@ UserId LdapAuthenticator::validateUser(const QString &username, const QString &p return quasselId; } - -bool LdapAuthenticator::setup(const QVariantMap &settings) +bool LdapAuthenticator::setup(const QVariantMap& settings, const QProcessEnvironment& environment, bool loadFromEnvironment) { - setAuthProperties(settings); + setAuthProperties(settings, environment, loadFromEnvironment); bool status = ldapConnect(); return status; } - -Authenticator::State LdapAuthenticator::init(const QVariantMap &settings) +Authenticator::State LdapAuthenticator::init(const QVariantMap& settings, const QProcessEnvironment& environment, bool loadFromEnvironment) { - setAuthProperties(settings); + setAuthProperties(settings, environment, loadFromEnvironment); bool status = ldapConnect(); if (!status) { - quInfo() << qPrintable(backendId()) << "authenticator cannot connect."; + qInfo() << qPrintable(backendId()) << "authenticator cannot connect."; return NotAvailable; } - quInfo() << qPrintable(backendId()) << "authenticator is ready."; + qInfo() << qPrintable(backendId()) << "authenticator is ready."; return IsReady; } // Method based on abustany LDAP quassel patch. bool LdapAuthenticator::ldapConnect() { - if (_connection != 0) { + if (_connection != nullptr) { ldapDisconnect(); } @@ -177,6 +176,8 @@ bool LdapAuthenticator::ldapConnect() serverURIArray = serverURI.toLocal8Bit(); res = ldap_initialize(&_connection, serverURIArray); + qInfo() << "LDAP: Connecting to" << serverURI; + if (res != LDAP_SUCCESS) { qWarning() << "Could not connect to LDAP server:" << ldap_err2string(res); return false; @@ -186,27 +187,25 @@ bool LdapAuthenticator::ldapConnect() if (res != LDAP_SUCCESS) { qWarning() << "Could not set LDAP protocol version to v3:" << ldap_err2string(res); - ldap_unbind_ext(_connection, 0, 0); - _connection = 0; + ldap_unbind_ext(_connection, nullptr, nullptr); + _connection = nullptr; return false; } return true; } - void LdapAuthenticator::ldapDisconnect() { - if (_connection == 0) { + if (_connection == nullptr) { return; } - ldap_unbind_ext(_connection, 0, 0); - _connection = 0; + ldap_unbind_ext(_connection, nullptr, nullptr); + _connection = nullptr; } - -bool LdapAuthenticator::ldapAuth(const QString &username, const QString &password) +bool LdapAuthenticator::ldapAuth(const QString& username, const QString& password) { if (password.isEmpty()) { return false; @@ -215,7 +214,7 @@ bool LdapAuthenticator::ldapAuth(const QString &username, const QString &passwor int res; // Attempt to establish a connection. - if (_connection == 0) { + if (_connection == nullptr) { if (!ldapConnect()) { return false; } @@ -229,10 +228,10 @@ bool LdapAuthenticator::ldapAuth(const QString &username, const QString &passwor QByteArray baseDN = _baseDN.toLocal8Bit(); QByteArray uidAttribute = _uidAttribute.toLocal8Bit(); - cred.bv_val = (bindPassword.size() > 0 ? bindPassword.data() : NULL); + cred.bv_val = (bindPassword.size() > 0 ? bindPassword.data() : nullptr); cred.bv_len = bindPassword.size(); - res = ldap_sasl_bind_s(_connection, bindDN.size() > 0 ? bindDN.constData() : 0, LDAP_SASL_SIMPLE, &cred, 0, 0, 0); + res = ldap_sasl_bind_s(_connection, bindDN.size() > 0 ? bindDN.constData() : nullptr, LDAP_SASL_SIMPLE, &cred, nullptr, nullptr, nullptr); if (res != LDAP_SUCCESS) { qWarning() << "Refusing connection from" << username << "(LDAP bind failed:" << ldap_err2string(res) << ")"; @@ -240,11 +239,21 @@ bool LdapAuthenticator::ldapAuth(const QString &username, const QString &passwor return false; } - LDAPMessage *msg = NULL, *entry = NULL; + LDAPMessage *msg = nullptr, *entry = nullptr; const QByteArray ldapQuery = "(&(" + uidAttribute + '=' + username.toLocal8Bit() + ")" + _filter.toLocal8Bit() + ")"; - res = ldap_search_ext_s(_connection, baseDN.constData(), LDAP_SCOPE_SUBTREE, ldapQuery.constData(), 0, 0, 0, 0, 0, 0, &msg); + res = ldap_search_ext_s(_connection, + baseDN.constData(), + LDAP_SCOPE_SUBTREE, + ldapQuery.constData(), + nullptr, + 0, + nullptr, + nullptr, + nullptr, + 0, + &msg); if (res != LDAP_SUCCESS) { qWarning() << "Refusing connection from" << username << "(LDAP search failed:" << ldap_err2string(res) << ")"; @@ -259,7 +268,7 @@ bool LdapAuthenticator::ldapAuth(const QString &username, const QString &passwor entry = ldap_first_entry(_connection, msg); - if (entry == 0) { + if (entry == nullptr) { qWarning() << "Refusing connection from" << username << "(LDAP search returned no results)"; ldap_msgfree(msg); return false; @@ -269,9 +278,9 @@ bool LdapAuthenticator::ldapAuth(const QString &username, const QString &passwor cred.bv_val = passwordArray.data(); cred.bv_len = password.size(); - char *userDN = ldap_get_dn(_connection, entry); + char* userDN = ldap_get_dn(_connection, entry); - res = ldap_sasl_bind_s(_connection, userDN, LDAP_SASL_SIMPLE, &cred, 0, 0, 0); + res = ldap_sasl_bind_s(_connection, userDN, LDAP_SASL_SIMPLE, &cred, nullptr, nullptr, nullptr); if (res != LDAP_SUCCESS) { qWarning() << "Refusing connection from" << username << "(LDAP authentication failed)";