]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/extra/m_ldapoper.cpp
Merge insp20
[user/henk/code/inspircd.git] / src / modules / extra / m_ldapoper.cpp
index 6eade1fbdc1d45404ff8256e9eadce2b000d25c4..79ac13dd56b1a4d223675702b6537e8fe23eedbf 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <ldap.h>
 
-#ifdef WINDOWS
+#ifdef _WIN32
 # pragma comment(lib, "ldap.lib")
 # pragma comment(lib, "lber.lib")
 #endif
 /* $ModDesc: Adds the ability to authenticate opers via LDAP */
 /* $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;
@@ -100,21 +153,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())
@@ -148,6 +197,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;
@@ -165,7 +215,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);
@@ -179,7 +230,7 @@ public:
                }
        }
 
-       virtual Version GetVersion()
+       Version GetVersion() CXX11_OVERRIDE
        {
                return Version("Adds the ability to authenticate opers via LDAP", VF_VENDOR);
        }