]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/extra/m_ldapoper.cpp
Change httpd modules to use the MODNAME constant in headers.
[user/henk/code/inspircd.git] / src / modules / extra / m_ldapoper.cpp
index 77e5989db71cc0b32d78884ea6231dcca8eea698..68e4cbf9f6e2c53aafec310bb17707cce06153bb 100644 (file)
@@ -1,26 +1,25 @@
-/*       +------------------------------------+
- *       | Inspire Internet Relay Chat Daemon |
- *       +------------------------------------+
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
  *
- *  InspIRCd: (C) 2002-2010 InspIRCd Development Team
- * See: http://wiki.inspircd.org/Credits
+ *   Copyright (C) 2009 Robin Burchell <robin+git@viroteck.net>
+ *   Copyright (C) 2008 Pippijn van Steenhoven <pip88nl@gmail.com>
+ *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
+ *   Copyright (C) 2007 Carsten Valdemar Munk <carsten.munk+inspircd@gmail.com>
  *
- * This program is free but copyrighted software; see
- *            the file COPYING for details.
+ * This file is part of InspIRCd.  InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
  *
- * ---------------------------------------------------
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
  *
- * Taken from the UnrealIRCd 4.0 SVN version, based on
- * InspIRCd 1.1.x.
- *
- * UnrealIRCd 4.0 (C) 2007 Carsten Valdemar Munk
- * This program is free but copyrighted software; see
- *         the file COPYING for details.
- *
- * ---------------------------------------------------
- * Heavily based on SQLauth
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+
 #include "inspircd.h"
 #include "users.h"
 #include "channels.h"
 
 #include <ldap.h>
 
-#ifdef WINDOWS
+#ifdef _WIN32
 # pragma comment(lib, "ldap.lib")
 # pragma comment(lib, "lber.lib")
 #endif
 
-/* $ModDesc: Allow/Deny connections based upon answer from LDAP server */
 /* $LinkerFlags: -lldap */
 
+struct RAIILDAPString
+{
+       char *str;
+
+       RAIILDAPString(char *Str)
+               : str(Str)
+       {
+       }
+
+       ~RAIILDAPString()
+       {
+               ldap_memfree(str);
+       }
+
+       operator char*()
+       {
+               return str;
+       }
+
+       operator std::string()
+       {
+               return str;
+       }
+};
+
 class ModuleLDAPAuth : public Module
 {
        std::string base;
        std::string ldapserver;
        std::string username;
        std::string password;
+       std::string attribute;
        int searchscope;
        LDAP *conn;
 
+       bool HandleOper(LocalUser* user, const std::string& opername, const std::string& inputpass)
+       {
+               OperIndex::iterator it = ServerInstance->Config->oper_blocks.find(opername);
+               if (it == ServerInstance->Config->oper_blocks.end())
+                       return false;
+
+               ConfigTag* tag = it->second->oper_block;
+               if (!tag)
+                       return false;
+
+               std::string acceptedhosts = tag->getString("host");
+               std::string hostname = user->ident + "@" + user->host;
+               if (!InspIRCd::MatchMask(acceptedhosts, hostname, user->GetIPString()))
+                       return false;
+
+               if (!LookupOper(opername, inputpass))
+                       return false;
+
+               user->Oper(it->second);
+               return true;
+       }
+
 public:
        ModuleLDAPAuth()
-               {
-               conn = NULL;
-               Implementation eventlist[] = { I_OnRehash, I_OnPassCompare };
-               ServerInstance->Modules->Attach(eventlist, this, 2);
+               : conn(NULL)
+       {
+       }
+
+       void init() CXX11_OVERRIDE
+       {
+               Implementation eventlist[] = { I_OnRehash, I_OnPreCommand };
+               ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
                OnRehash(NULL);
        }
 
-       virtual ~ModuleLDAPAuth()
+       ~ModuleLDAPAuth()
        {
                if (conn)
                        ldap_unbind_ext(conn, NULL, NULL);
        }
 
-       virtual void OnRehash(User* user)
+       void OnRehash(User* user) CXX11_OVERRIDE
        {
-               ConfigReader Conf;
+               ConfigTag* tag = ServerInstance->Config->ConfValue("ldapoper");
 
-               base                    = Conf.ReadValue("ldapoper", "baserdn", 0);
-               ldapserver              = Conf.ReadValue("ldapoper", "server", 0);
-               std::string scope       = Conf.ReadValue("ldapoper", "searchscope", 0);
-               username                = Conf.ReadValue("ldapoper", "binddn", 0);
-               password                = Conf.ReadValue("ldapoper", "bindauth", 0);
+               base                    = tag->getString("baserdn");
+               ldapserver              = tag->getString("server");
+               std::string scope       = tag->getString("searchscope");
+               username                = tag->getString("binddn");
+               password                = tag->getString("bindauth");
+               attribute               = tag->getString("attribute");
 
                if (scope == "base")
                        searchscope = LDAP_SCOPE_BASE;
@@ -101,21 +152,17 @@ public:
                return true;
        }
 
-       virtual ModResult OnPassCompare(Extensible* ex, const std::string &data, const std::string &input, const std::string &hashtype)
+       ModResult OnPreCommand(std::string& command, std::vector<std::string>& parameters, LocalUser* user, bool validated, const std::string& original_line) CXX11_OVERRIDE
        {
-               if (hashtype == "ldap")
+               if (validated && command == "OPER" && parameters.size() >= 2)
                {
-                       if (LookupOper(data, input))
-                               /* This is an ldap oper and has been found, claim the OPER command */
-                               return MOD_RES_ALLOW;
-                       else
+                       if (HandleOper(user, parameters[0], parameters[1]))
                                return MOD_RES_DENY;
                }
-               /* We don't know this oper! */
                return MOD_RES_PASSTHRU;
        }
 
-       bool LookupOper(const std::string &what, const std::string &opassword)
+       bool LookupOper(const std::string& opername, const std::string& opassword)
        {
                if (conn == NULL)
                        if (!Connect())
@@ -149,6 +196,7 @@ public:
                free(authpass);
 
                LDAPMessage *msg, *entry;
+               std::string what = attribute + "=" + opername;
                if ((res = ldap_search_ext_s(conn, base.c_str(), searchscope, what.c_str(), NULL, 0, NULL, NULL, NULL, 0, &msg)) != LDAP_SUCCESS)
                {
                        return false;
@@ -166,7 +214,8 @@ public:
                authpass = strdup(opassword.c_str());
                cred.bv_val = authpass;
                cred.bv_len = opassword.length();
-               if ((res = ldap_sasl_bind_s(conn, ldap_get_dn(conn, entry), LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL)) == LDAP_SUCCESS)
+               RAIILDAPString DN(ldap_get_dn(conn, entry));
+               if ((res = ldap_sasl_bind_s(conn, DN, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL)) == LDAP_SUCCESS)
                {
                        free(authpass);
                        ldap_msgfree(msg);
@@ -180,9 +229,9 @@ public:
                }
        }
 
-       virtual Version GetVersion()
+       Version GetVersion() CXX11_OVERRIDE
        {
-               return Version("Allow/Deny connections based upon answer from LDAP server", VF_VENDOR);
+               return Version("Adds the ability to authenticate opers via LDAP", VF_VENDOR);
        }
 
 };