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
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;
}
std::string bindDn = a.get("dn");
if (bindDn.empty())
{
- if (user)
- ServerInstance->Users->QuitUser(user, killreason);
+ ServerInstance->Users->QuitUser(user, killreason);
delete this;
return;
}
}
};
+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;
LocalStringExt ldapVhost;
std::string base;
std::string attribute;
- std::string allowpattern;
+ std::vector<std::string> allowpatterns;
std::vector<std::string> whitelistedcidrs;
bool useusername;
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;
base = tag->getString("baserdn");
attribute = tag->getString("attribute");
- allowpattern = tag->getString("allowpattern");
killreason = tag->getString("killreason");
vhost = tag->getString("host");
// Set to true if failed connects should be reported to operators
if (!attr.empty() && !val.empty())
requiredattributes.push_back(make_pair(attr, val));
}
+
+ std::string allowpattern = tag->getString("allowpattern");
+ irc::spacesepstream ss(allowpattern);
+ for (std::string more; ss.GetToken(more); )
+ {
+ allowpatterns.push_back(more);
+ }
}
void OnUserConnect(LocalUser *user) CXX11_OVERRIDE
std::string* cc = ldapVhost.get(user);
if (cc)
{
- user->ChangeDisplayedHost(cc->c_str());
+ user->ChangeDisplayedHost(*cc);
ldapVhost.unset(user);
}
}
ModResult OnUserRegister(LocalUser* user) CXX11_OVERRIDE
{
- if ((!allowpattern.empty()) && (InspIRCd::Match(user->nick,allowpattern)))
+ for (std::vector<std::string>::const_iterator i = allowpatterns.begin(); i != allowpatterns.end(); ++i)
{
- ldapAuthed.set(user,1);
- return MOD_RES_PASSTHRU;
+ if (InspIRCd::Match(user->nick, *i))
+ {
+ ldapAuthed.set(user,1);
+ return MOD_RES_PASSTHRU;
+ }
}
for (std::vector<std::string>::iterator i = whitelistedcidrs.begin(); i != whitelistedcidrs.end(); i++)
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;
}
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)
+ {
+ what = attribute + "=" + user->password.substr(0, pos);
+
+ // Trim the user: prefix, leaving just 'pass' for later password check
+ user->password = user->password.substr(pos + 1);
+ }
+ else
{
- LDAP->BindAsManager(NULL);
+ what = attribute + "=" + (useusername ? user->ident : user->nick);
+ }
- std::string what = attribute + "=" + (useusername ? user->ident : user->nick);
- LDAP->Search(new SearchInterface(this, LDAP.GetProvider(), user->uuid), base, what);
+ try
+ {
+ LDAP->BindAsManager(new AdminBindInterface(this, LDAP.GetProvider(), user->uuid, base, what));
}
catch (LDAPException &ex)
{
Version GetVersion() CXX11_OVERRIDE
{
- return Version("Allow/Deny connections based upon answer from LDAP server", VF_VENDOR);
+ return Version("Allow/deny connections based upon answers from an LDAP server", VF_VENDOR);
}
};