diff options
author | Adam <Adam@anope.org> | 2017-03-20 09:35:13 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2017-03-20 09:40:28 -0400 |
commit | 3f1eb79c7fa82737fda9c9a712724ba2f27651e9 (patch) | |
tree | a870a304fea0cee9dab6029d56449198ce4b8ea9 | |
parent | 466ba4100ae8f18470fdf8f1b3def5aa5f9a5cbb (diff) |
m_ldapauth: fix providing username in PASS
This has never worked because it never prepended attribute= to the
search string. It also would prefer matching nick/ident over the user
string provided which is inconsistent, since your ability to
authenticate using PASS would depend on a ldap entry not existing with
your current nick/ident.
Instead, use username provided in PASS and then fallback to nick/ident.
-rw-r--r-- | src/modules/extra/m_ldapauth.cpp | 47 |
1 files changed, 18 insertions, 29 deletions
diff --git a/src/modules/extra/m_ldapauth.cpp b/src/modules/extra/m_ldapauth.cpp index 6c765fb2e..405bab082 100644 --- a/src/modules/extra/m_ldapauth.cpp +++ b/src/modules/extra/m_ldapauth.cpp @@ -310,36 +310,25 @@ public: } RAIILDAPMessage msg; - std::string what = (attribute + "=" + (useusername ? user->ident : user->nick)); - if ((res = ldap_search_ext_s(conn, base.c_str(), searchscope, what.c_str(), NULL, 0, NULL, NULL, NULL, 0, &msg)) != LDAP_SUCCESS) + std::string what; + std::string::size_type pos = user->password.find(':'); + // If a username is provided in PASS, use it, othewrise user their nick or ident + if (pos != std::string::npos) { - // Do a second search, based on password, if it contains a : - // That is, PASS <user>:<password> will work. - size_t pos = user->password.find(":"); - if (pos != std::string::npos) - { - // manpage says we must deallocate regardless of success or failure - // since we're about to do another query (and reset msg), first - // free the old one. - msg.dealloc(); - - std::string cutpassword = user->password.substr(0, pos); - res = ldap_search_ext_s(conn, base.c_str(), searchscope, cutpassword.c_str(), NULL, 0, NULL, NULL, NULL, 0, &msg); - - if (res == LDAP_SUCCESS) - { - // Trim the user: prefix, leaving just 'pass' for later password check - user->password = user->password.substr(pos + 1); - } - } + what = (attribute + "=" + user->password.substr(0, pos)); - // It may have found based on user:pass check above. - if (res != LDAP_SUCCESS) - { - if (verbose) - ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s (LDAP search failed: %s)", user->GetFullRealHost().c_str(), ldap_err2string(res)); - return false; - } + // 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)); + } + if ((res = ldap_search_ext_s(conn, base.c_str(), searchscope, what.c_str(), NULL, 0, NULL, NULL, NULL, 0, &msg)) != LDAP_SUCCESS) + { + if (verbose) + ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s (LDAP search failed: %s)", user->GetFullRealHost().c_str(), ldap_err2string(res)); + return false; } if (ldap_count_entries(conn, msg) > 1) { @@ -404,7 +393,7 @@ public: std::string dnPart; while (stream.GetToken(dnPart)) { - std::string::size_type pos = dnPart.find('='); + pos = dnPart.find('='); if (pos == std::string::npos) // malformed continue; |