diff options
author | Adrien Bustany <adrien@bustany.org> | 2012-10-10 10:04:18 +0300 |
---|---|---|
committer | attilamolnar <attilamolnar@hush.com> | 2012-10-19 20:40:16 +0200 |
commit | 9451b734fff2fa908747fe26d01e87f81c94292c (patch) | |
tree | 20102d61f229156ef9b9712ee2161043be342144 /src | |
parent | a4ea01a767870574403690b0abd04b1dae85d6b5 (diff) |
m_ldapauth Allow filtering on arbitrary LDAP attributes
This commit implements filtering on LDAP attributes, in a similar way
to what Apache Httpd does with "Require ldap-attribute".
Diffstat (limited to 'src')
-rw-r--r-- | src/modules/extra/m_ldapauth.cpp | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/src/modules/extra/m_ldapauth.cpp b/src/modules/extra/m_ldapauth.cpp index c4e937b9f..f404471ea 100644 --- a/src/modules/extra/m_ldapauth.cpp +++ b/src/modules/extra/m_ldapauth.cpp @@ -49,6 +49,7 @@ class ModuleLDAPAuth : public Module std::string username; std::string password; std::vector<std::string> whitelistedcidrs; + std::vector<std::pair<std::string, std::string> > requiredattributes; int searchscope; bool verbose; bool useusername; @@ -77,6 +78,7 @@ public: { ConfigReader Conf; whitelistedcidrs.clear(); + requiredattributes.clear(); base = Conf.ReadValue("ldapauth", "baserdn", 0); attribute = Conf.ReadValue("ldapauth", "attribute", 0); @@ -99,6 +101,17 @@ public: } } + ConfigTagList attributetags = ServerInstance->Config->ConfTags("ldaprequire"); + + for (ConfigIter i = attributetags.first; i != attributetags.second; ++i) + { + const std::string attr = i->second->getString("attribute"); + const std::string val = i->second->getString("value"); + + if (!attr.empty() && !val.empty()) + requiredattributes.push_back(make_pair(attr, val)); + } + if (scope == "base") searchscope = LDAP_SCOPE_BASE; else if (scope == "onelevel") @@ -242,19 +255,47 @@ public: } cred.bv_val = (char*)user->password.data(); cred.bv_len = user->password.length(); - if ((res = ldap_sasl_bind_s(conn, ldap_get_dn(conn, entry), LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL)) == LDAP_SUCCESS) + if ((res = ldap_sasl_bind_s(conn, ldap_get_dn(conn, entry), LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL)) != LDAP_SUCCESS) + { + if (verbose) + ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s!%s@%s (%s)", user->nick.c_str(), user->ident.c_str(), user->host.c_str(), ldap_err2string(res)); + ldap_msgfree(msg); + return false; + } + + if (requiredattributes.empty()) { ldap_msgfree(msg); ldapAuthed.set(user,1); return true; } - else + + bool authed = false; + + for (std::vector<std::pair<std::string, std::string> >::const_iterator it = requiredattributes.begin(); it != requiredattributes.end(); ++it) { - if (verbose) - ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s!%s@%s (%s)", user->nick.c_str(), user->ident.c_str(), user->host.c_str(), ldap_err2string(res)); - ldap_msgfree(msg); - return false; + const std::string &attr = it->first; + const std::string &val = it->second; + + struct berval attr_value; + attr_value.bv_val = const_cast<char*>(val.c_str()); + attr_value.bv_len = val.length(); + + ServerInstance->Logs->Log("m_ldapauth", DEBUG, "LDAP compare: %s=%s", attr.c_str(), val.c_str()); + + authed = (ldap_compare_ext_s(conn, ldap_get_dn(conn, entry), attr.c_str(), &attr_value, NULL, NULL) == LDAP_COMPARE_TRUE); + + if (authed) + break; } + + ldap_msgfree(msg); + + if (!authed) + return false; + + ldapAuthed.set(user,1); + return true; } ModResult OnCheckReady(LocalUser* user) |