]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_ldapauth.cpp
Fix a bunch of weird indentation and spacing issues.
[user/henk/code/inspircd.git] / src / modules / m_ldapauth.cpp
index 179fe6fcaa24722a4cec3d88147b206395e7626d..8d4b956e71390277d01bfb3c7edf15206acc330f 100644 (file)
@@ -1,14 +1,12 @@
 /*
  * InspIRCd -- Internet Relay Chat Daemon
  *
- *   Copyright (C) 2013 Adam <Adam@anope.org>
- *   Copyright (C) 2011 Pierre Carrier <pierre@spotify.com>
- *   Copyright (C) 2009-2010 Robin Burchell <robin+git@viroteck.net>
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2008 Pippijn van Steenhoven <pip88nl@gmail.com>
- *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
- *   Copyright (C) 2008 Dennis Friis <peavey@inspircd.org>
- *   Copyright (C) 2007 Carsten Valdemar Munk <carsten.munk+inspircd@gmail.com>
+ *   Copyright (C) 2020 Joel Sing <joel@sing.id.au>
+ *   Copyright (C) 2019 Sadie Powell <sadie@witchery.services>
+ *   Copyright (C) 2019 Robby <robby@chatbelgie.be>
+ *   Copyright (C) 2014-2015 Attila Molnar <attilamolnar@hush.com>
+ *   Copyright (C) 2014 Thiago Crepaldi <thiago@thiagocrepaldi.com>
+ *   Copyright (C) 2013-2014, 2017 Adam <Adam@anope.org>
  *
  * 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
@@ -64,7 +62,7 @@ class BindInterface : public LDAPInterface
                                while (i < text.length() - 1 && isalpha(text[i + 1]))
                                        ++i;
 
-                               std::string key = text.substr(start, (i - start) + 1);
+                               std::string key(text, start, (i - start) + 1);
                                result.append(replacements[key]);
                        }
                        else
@@ -90,8 +88,8 @@ class BindInterface : public LDAPInterface
                                if (pos == std::string::npos) // malformed
                                        continue;
 
-                               std::string key = dnPart.substr(0, pos);
-                               std::string value = dnPart.substr(pos + 1, dnPart.length() - pos + 1); // +1s to skip the = itself
+                               std::string key(dnPart, 0, pos);
+                               std::string value(dnPart, pos + 1, dnPart.length() - pos + 1); // +1s to skip the = itself
                                dnParts[key] = value;
                        }
 
@@ -121,6 +119,9 @@ class BindInterface : public LDAPInterface
 
                if (!checkingAttributes && requiredattributes.empty())
                {
+                       if (verbose)
+                               ServerInstance->SNO->WriteToSnoMask('c', "Successful connection from %s (dn=%s)", user->GetFullRealHost().c_str(), DN.c_str());
+
                        // We're done, there are no attributes to check
                        SetVHost(user, DN);
                        authed->set(user, 1);
@@ -137,6 +138,9 @@ class BindInterface : public LDAPInterface
                                // Only one has to pass
                                passed = true;
 
+                               if (verbose)
+                                       ServerInstance->SNO->WriteToSnoMask('c', "Successful connection from %s (dn=%s)", user->GetFullRealHost().c_str(), DN.c_str());
+
                                SetVHost(user, DN);
                                authed->set(user, 1);
                        }
@@ -174,7 +178,7 @@ class BindInterface : public LDAPInterface
                if (!attrCount)
                {
                        if (verbose)
-                               ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s (unable to validate attributes)", user->GetFullRealHost().c_str());
+                               ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s (dn=%s) (unable to validate attributes)", user->GetFullRealHost().c_str(), DN.c_str());
                        ServerInstance->Users->QuitUser(user, killreason);
                        delete this;
                }
@@ -216,7 +220,7 @@ class SearchInterface : public LDAPInterface
 
        void OnResult(const LDAPResult& r) CXX11_OVERRIDE
        {
-               LocalUser* user = static_cast<LocalUser*>(ServerInstance->FindUUID(uid));
+               LocalUser* user = IS_LOCAL(ServerInstance->FindUUID(uid));
                dynamic_reference<LDAPProvider> LDAP(me, provider);
                if (!LDAP || r.empty() || !user)
                {
@@ -232,8 +236,7 @@ class SearchInterface : public LDAPInterface
                        std::string bindDn = a.get("dn");
                        if (bindDn.empty())
                        {
-                               if (user)
-                                       ServerInstance->Users->QuitUser(user, killreason);
+                               ServerInstance->Users->QuitUser(user, killreason);
                                delete this;
                                return;
                        }
@@ -257,6 +260,43 @@ class SearchInterface : public LDAPInterface
        }
 };
 
+class AdminBindInterface : public LDAPInterface
+{
+       const std::string provider;
+       const std::string uuid;
+       const std::string base;
+       const std::string what;
+
+ public:
+       AdminBindInterface(Module* c, const std::string& p, const std::string& u, const std::string& b, const std::string& w)
+               : LDAPInterface(c), provider(p), uuid(u), base(b), what(w)
+       {
+       }
+
+       void OnResult(const LDAPResult& r) CXX11_OVERRIDE
+       {
+               dynamic_reference<LDAPProvider> LDAP(me, provider);
+               if (LDAP)
+               {
+                       try
+                       {
+                               LDAP->Search(new SearchInterface(this->creator, provider, uuid), base, what);
+                       }
+                       catch (LDAPException& ex)
+                       {
+                               ServerInstance->SNO->WriteToSnoMask('a', "Error searching LDAP server: " + ex.GetReason());
+                       }
+               }
+               delete this;
+       }
+
+       void OnError(const LDAPResult& err) CXX11_OVERRIDE
+       {
+               ServerInstance->SNO->WriteToSnoMask('a', "Error binding as manager to LDAP server: " + err.getError());
+               delete this;
+       }
+};
+
 class ModuleLDAPAuth : public Module
 {
        dynamic_reference<LDAPProvider> LDAP;
@@ -271,8 +311,8 @@ class ModuleLDAPAuth : public Module
 public:
        ModuleLDAPAuth()
                : LDAP(this, "LDAP")
-               , ldapAuthed("ldapauth", this)
-               , ldapVhost("ldapauth_vhost", this)
+               , ldapAuthed("ldapauth", ExtensionItem::EXT_USER, this)
+               , ldapVhost("ldapauth_vhost", ExtensionItem::EXT_USER, this)
        {
                me = this;
                authed = &ldapAuthed;
@@ -285,13 +325,13 @@ public:
                whitelistedcidrs.clear();
                requiredattributes.clear();
 
-               base                    = tag->getString("baserdn");
+               base                    = tag->getString("baserdn");
                attribute               = tag->getString("attribute");
                killreason              = tag->getString("killreason");
                vhost                   = tag->getString("host");
                // Set to true if failed connects should be reported to operators
                verbose                 = tag->getBool("verbose");
-               useusername             = tag->getBool("userfield");
+               useusername             = tag->getBool("useusername", tag->getBool("userfield"));
 
                LDAP.SetProvider("LDAP/" + tag->getString("dbid"));
 
@@ -357,7 +397,7 @@ public:
                if (user->password.empty())
                {
                        if (verbose)
-                               ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s (No password provided)", user->GetFullRealHost().c_str());
+                               ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s (no password provided)", user->GetFullRealHost().c_str());
                        ServerInstance->Users->QuitUser(user, killreason);
                        return MOD_RES_DENY;
                }
@@ -365,17 +405,28 @@ public:
                if (!LDAP)
                {
                        if (verbose)
-                               ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s (Unable to find LDAP provider)", user->GetFullRealHost().c_str());
+                               ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s (unable to find LDAP provider)", user->GetFullRealHost().c_str());
                        ServerInstance->Users->QuitUser(user, killreason);
                        return MOD_RES_DENY;
                }
 
-               try
+               std::string what;
+               std::string::size_type pos = user->password.find(':');
+               if (pos != std::string::npos)
                {
-                       LDAP->BindAsManager(NULL);
+                       what = attribute + "=" + user->password.substr(0, pos);
 
-                       std::string what = attribute + "=" + (useusername ? user->ident : user->nick);
-                       LDAP->Search(new SearchInterface(this, LDAP.GetProvider(), user->uuid), base, what);
+                       // Trim the user: prefix, leaving just 'pass' for later password check
+                       user->password = user->password.substr(pos + 1);
+               }
+               else
+               {
+                       what = attribute + "=" + (useusername ? user->ident : user->nick);
+               }
+
+               try
+               {
+                       LDAP->BindAsManager(new AdminBindInterface(this, LDAP.GetProvider(), user->uuid, base, what));
                }
                catch (LDAPException &ex)
                {
@@ -393,7 +444,7 @@ public:
 
        Version GetVersion() CXX11_OVERRIDE
        {
-               return Version("Allow/Deny connections based upon answer from LDAP server", VF_VENDOR);
+               return Version("Allows connecting users to be authenticated against an LDAP database.", VF_VENDOR);
        }
 };