2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2013 Adam <Adam@anope.org>
5 * Copyright (C) 2009 Robin Burchell <robin+git@viroteck.net>
6 * Copyright (C) 2008 Pippijn van Steenhoven <pip88nl@gmail.com>
7 * Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
8 * Copyright (C) 2007 Carsten Valdemar Munk <carsten.munk+inspircd@gmail.com>
10 * This file is part of InspIRCd. InspIRCd is free software: you can
11 * redistribute it and/or modify it under the terms of the GNU General Public
12 * License as published by the Free Software Foundation, version 2.
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "modules/ldap.h"
32 class LDAPOperBase : public LDAPInterface
35 const std::string uid;
36 const std::string opername;
37 const std::string password;
39 void Fallback(User* user)
44 Command* oper_command = ServerInstance->Parser.GetHandler("OPER");
48 CommandBase::Params params;
49 params.push_back(opername);
50 params.push_back(password);
51 ClientProtocol::TagMap tags;
52 oper_command->Handle(user, CommandBase::Params(params, tags));
57 User* user = ServerInstance->FindUUID(uid);
62 LDAPOperBase(Module* mod, const std::string& uuid, const std::string& oper, const std::string& pass)
64 , uid(uuid), opername(oper), password(pass)
68 void OnError(const LDAPResult& err) CXX11_OVERRIDE
70 ServerInstance->SNO->WriteToSnoMask('a', "Error searching LDAP server: %s", err.getError().c_str());
76 class BindInterface : public LDAPOperBase
79 BindInterface(Module* mod, const std::string& uuid, const std::string& oper, const std::string& pass)
80 : LDAPOperBase(mod, uuid, oper, pass)
84 void OnResult(const LDAPResult& r) CXX11_OVERRIDE
86 User* user = ServerInstance->FindUUID(uid);
87 ServerConfig::OperIndex::const_iterator iter = ServerInstance->Config->oper_blocks.find(opername);
89 if (!user || iter == ServerInstance->Config->oper_blocks.end())
96 OperInfo* ifo = iter->second;
102 class SearchInterface : public LDAPOperBase
104 const std::string provider;
106 bool HandleResult(const LDAPResult& result)
108 dynamic_reference<LDAPProvider> LDAP(me, provider);
109 if (!LDAP || result.empty())
114 const LDAPAttributes& attr = result.get(0);
115 std::string bindDn = attr.get("dn");
119 LDAP->Bind(new BindInterface(this->creator, uid, opername, password), bindDn, password);
121 catch (LDAPException& ex)
123 ServerInstance->SNO->WriteToSnoMask('a', "Error searching LDAP server: " + ex.GetReason());
130 SearchInterface(Module* mod, const std::string& prov, const std::string &uuid, const std::string& oper, const std::string& pass)
131 : LDAPOperBase(mod, uuid, oper, pass)
136 void OnResult(const LDAPResult& result) CXX11_OVERRIDE
138 if (!HandleResult(result))
144 class AdminBindInterface : public LDAPInterface
146 const std::string provider;
147 const std::string user;
148 const std::string opername;
149 const std::string password;
150 const std::string base;
151 const std::string what;
154 AdminBindInterface(Module* c, const std::string& p, const std::string& u, const std::string& o, const std::string& pa, const std::string& b, const std::string& w)
155 : LDAPInterface(c), provider(p), user(u), opername(p), password(pa), base(b), what(w)
159 void OnResult(const LDAPResult& r) CXX11_OVERRIDE
161 dynamic_reference<LDAPProvider> LDAP(me, provider);
166 LDAP->Search(new SearchInterface(this->creator, provider, user, opername, password), base, what);
168 catch (LDAPException& ex)
170 ServerInstance->SNO->WriteToSnoMask('a', "Error searching LDAP server: " + ex.GetReason());
176 void OnError(const LDAPResult& err) CXX11_OVERRIDE
178 ServerInstance->SNO->WriteToSnoMask('a', "Error binding as manager to LDAP server: " + err.getError());
183 class ModuleLDAPAuth : public Module
185 dynamic_reference<LDAPProvider> LDAP;
187 std::string attribute;
196 void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
198 ConfigTag* tag = ServerInstance->Config->ConfValue("ldapoper");
200 LDAP.SetProvider("LDAP/" + tag->getString("dbid"));
201 base = tag->getString("baserdn");
202 attribute = tag->getString("attribute");
205 ModResult OnPreCommand(std::string& command, CommandBase::Params& parameters, LocalUser* user, bool validated) CXX11_OVERRIDE
207 if (validated && command == "OPER" && parameters.size() >= 2)
209 const std::string& opername = parameters[0];
210 const std::string& password = parameters[1];
212 ServerConfig::OperIndex::const_iterator it = ServerInstance->Config->oper_blocks.find(opername);
213 if (it == ServerInstance->Config->oper_blocks.end())
214 return MOD_RES_PASSTHRU;
216 ConfigTag* tag = it->second->oper_block;
218 return MOD_RES_PASSTHRU;
220 std::string acceptedhosts = tag->getString("host");
221 std::string hostname = user->ident + "@" + user->GetRealHost();
222 if (!InspIRCd::MatchMask(acceptedhosts, hostname, user->GetIPString()))
223 return MOD_RES_PASSTHRU;
226 return MOD_RES_PASSTHRU;
230 std::string what = attribute + "=" + opername;
231 LDAP->BindAsManager(new AdminBindInterface(this, LDAP.GetProvider(), user->uuid, opername, password, base, what));
234 catch (LDAPException& ex)
236 ServerInstance->SNO->WriteToSnoMask('a', "LDAP exception: " + ex.GetReason());
240 return MOD_RES_PASSTHRU;
243 Version GetVersion() CXX11_OVERRIDE
245 return Version("Adds the ability to authenticate opers via LDAP", VF_VENDOR);
249 MODULE_INIT(ModuleLDAPAuth)