summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Burchell <robin+git@viroteck.net>2012-11-28 19:59:33 +0100
committerRobin Burchell <robin+git@viroteck.net>2012-11-29 10:07:01 +0100
commite031d194181e09eb9d802f18a415422bb1e61d1c (patch)
treefba687c21c0716aef29c851417ea4d4d90657954
parent2fb2f639ad8b584a6e778569bc871f50d2de2d7e (diff)
ldapauth: Allow setting virtual hosts on identification with m_ldapauth.
<ldapauth:host>, when set, will be applied to users identifying with ldapauth. The host can also take formatters from fields set on the DN of the user.
-rw-r--r--docs/conf/modules.conf.example15
-rw-r--r--src/modules/extra/m_ldapauth.cpp70
2 files changed, 79 insertions, 6 deletions
diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example
index 3f40bc7ce..5ddb21baa 100644
--- a/docs/conf/modules.conf.example
+++ b/docs/conf/modules.conf.example
@@ -972,8 +972,9 @@
# LDAP authentication module: Adds the ability to authenticate users #
# via LDAP. This is an extra module which must be enabled explicitly #
# by symlinking it from modules/extra, and requires the OpenLDAP libs #
-# This modules is in extras. Re-run configure with: ./configure --enable-extras=m_ldapauth.cpp
-# and run make install, then uncomment this module to enable it. #
+# This modules is in extras. To enable it, Re-run configure with: #
+# ./configure --enable-extras=m_ldapauth.cpp #
+# and run make install, then uncomment this module. #
# #
#<module name="m_ldapauth.so"> #
# #
@@ -987,7 +988,8 @@
# searchscope="subtree" #
# binddn="cn=Manager,dc=brainbox,dc=cc" #
# bindauth="mysecretpass" #
-# verbose="yes"> #
+# verbose="yes" #
+# host="$uid.$ou.inspircd.org"> #
# #
# <ldapwhitelist cidr="10.42.0.0/16"> #
# #
@@ -1030,6 +1032,13 @@
# 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. #
+# #
+# host allows you to change the displayed host of users connecting #
+# from ldap. The string supplied takes formatters which are replaced #
+# from the DN. For instance, if your DN looks like: #
+# uid=w00t,ou=people,dc=inspircd,dc=org, then the formatters uid, ou #
+# and dc will be available to you. If a key is given multiple times #
+# in the DN, the last appearance will take precedence. #
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# 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 70a73ffb5..5d4d90d44 100644
--- a/src/modules/extra/m_ldapauth.cpp
+++ b/src/modules/extra/m_ldapauth.cpp
@@ -41,6 +41,7 @@
class ModuleLDAPAuth : public Module
{
LocalIntExt ldapAuthed;
+ LocalStringExt ldapVhost;
std::string base;
std::string attribute;
std::string ldapserver;
@@ -48,6 +49,7 @@ class ModuleLDAPAuth : public Module
std::string killreason;
std::string username;
std::string password;
+ std::string vhost;
std::vector<std::string> whitelistedcidrs;
std::vector<std::pair<std::string, std::string> > requiredattributes;
int searchscope;
@@ -56,15 +58,17 @@ class ModuleLDAPAuth : public Module
LDAP *conn;
public:
- ModuleLDAPAuth() : ldapAuthed("ldapauth", this)
+ ModuleLDAPAuth()
+ : ldapAuthed("ldapauth", this)
+ , ldapVhost("ldapauth_vhost", this)
{
conn = NULL;
}
void init()
{
- Implementation eventlist[] = { I_OnCheckReady, I_OnRehash, I_OnUserRegister };
- ServerInstance->Modules->Attach(eventlist, this, 3);
+ Implementation eventlist[] = { I_OnCheckReady, I_OnRehash,I_OnUserRegister, I_OnUserConnect };
+ ServerInstance->Modules->Attach(eventlist, this, 4);
OnRehash(NULL);
}
@@ -88,6 +92,7 @@ public:
std::string scope = tag->getString("searchscope");
username = tag->getString("binddn");
password = tag->getString("bindauth");
+ vhost = tag->getString("host");
verbose = tag->getBool("verbose"); /* Set to true if failed connects should be reported to operators */
useusername = tag->getBool("userfield");
@@ -147,6 +152,42 @@ public:
return true;
}
+ std::string SafeReplace(const std::string &text, std::map<std::string,
+ std::string> &replacements)
+ {
+ std::string result;
+ result.reserve(MAXBUF);
+
+ for (unsigned int i = 0; i < text.length(); ++i) {
+ char c = text[i];
+ if (c == '$') {
+ // find the first nonalpha
+ i++;
+ unsigned int start = i;
+
+ while (i < text.length() - 1 && isalpha(text[i + 1]))
+ ++i;
+
+ std::string key = text.substr(start, (i - start) + 1);
+ result.append(replacements[key]);
+ } else {
+ result.push_back(c);
+ }
+ }
+
+ return result;
+ }
+
+ virtual void OnUserConnect(LocalUser *user)
+ {
+ std::string* cc = ldapVhost.get(user);
+ if (cc)
+ {
+ user->ChangeDisplayedHost(cc->c_str());
+ ldapVhost.unset(user);
+ }
+ }
+
ModResult OnUserRegister(LocalUser* user)
{
if ((!allowpattern.empty()) && (InspIRCd::Match(user->nick,allowpattern)))
@@ -293,6 +334,29 @@ public:
}
}
+ if (!vhost.empty())
+ {
+ irc::commasepstream stream(ldap_get_dn(conn, entry));
+
+ // mashed map of key:value parts of the DN
+ std::map<std::string, std::string> dnParts;
+
+ std::string dnPart;
+ while (stream.GetToken(dnPart))
+ {
+ std::string::size_type pos = dnPart.find('=');
+ 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
+ dnParts[key] = value;
+ }
+
+ // change host according to config key
+ ldapVhost.set(user, SafeReplace(vhost, dnParts));
+ }
+
ldap_msgfree(msg);
ldapAuthed.set(user,1);
return true;