summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrien Bustany <adrien@bustany.org>2012-10-10 10:04:18 +0300
committerattilamolnar <attilamolnar@hush.com>2012-10-19 20:40:16 +0200
commit9451b734fff2fa908747fe26d01e87f81c94292c (patch)
tree20102d61f229156ef9b9712ee2161043be342144
parenta4ea01a767870574403690b0abd04b1dae85d6b5 (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".
-rw-r--r--docs/conf/modules.conf.example8
-rw-r--r--src/modules/extra/m_ldapauth.cpp53
2 files changed, 55 insertions, 6 deletions
diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example
index 32217138a..e20769373 100644
--- a/docs/conf/modules.conf.example
+++ b/docs/conf/modules.conf.example
@@ -991,6 +991,8 @@
# #
# <ldapwhitelist cidr="10.42.0.0/16"> #
# #
+# <ldaprequire attribute="attr" value="val"> #
+# #
# The baserdn indicates the base DN to search in for users. Usually #
# this is 'ou=People,dc=yourdomain,dc=yourtld'. #
# #
@@ -1022,6 +1024,12 @@
# ldapwhitelist indicates that clients connecting from an IP in the #
# provided CIDR do not need to authenticate against LDAP. It can be #
# repeated to whitelist multiple CIDRs. #
+# #
+# ldaprequire allows further filtering on the LDAP user, by requiring #
+# certain LDAP attibutes to have a given value. It can be repeated, #
+# in which case the list will act as an OR list, that is, the #
+# authentication will succeed if any of the requirements in the list #
+# is satisfied. #
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# LDAP oper configuration module: Adds the ability to authenticate #
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)