From bcd4dbfb5da503fb7dd7df5a50cf40524d833f4a Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Sun, 6 Aug 2023 00:23:50 +0100 Subject: Make ldapauth take an enum field for the username field. --- docs/conf/modules.conf.example | 7 +++--- src/modules/m_ldapauth.cpp | 51 ++++++++++++++++++++++++++++++++---------- 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example index 1cedb05b1..aa9b4c4ee 100644 --- a/docs/conf/modules.conf.example +++ b/docs/conf/modules.conf.example @@ -1477,7 +1477,7 @@ # killreason="Access denied" # # verbose="yes" # # host="$uid.$ou.inspircd.org" # -# useusername="no"> # +# field="nickname"> # # # # # # # @@ -1490,9 +1490,8 @@ # The attribute value indicates the attribute which is used to locate # # a user account by name. On POSIX systems this is usually 'uid'. # # # -# The useusername setting chooses whether the user's username or # -# nickname is used when locating a user account, if a username isn't # -# provided in PASS. # +# The field setting chooses where to select the LDAP username from. # +# Valid options are "nickname", "username", and "password". # # # # Killreason indicates the QUIT reason to give to users if they fail # # to authenticate. # diff --git a/src/modules/m_ldapauth.cpp b/src/modules/m_ldapauth.cpp index 6f5efbc2b..caecdb327 100644 --- a/src/modules/m_ldapauth.cpp +++ b/src/modules/m_ldapauth.cpp @@ -312,6 +312,14 @@ public: } }; +enum class AuthField + : uint8_t +{ + NICKNAME, + USERNAME, + PASSWORD, +}; + class ModuleLDAPAuth final : public Module { @@ -321,7 +329,7 @@ class ModuleLDAPAuth final std::string base; std::string attribute; std::vector exemptions; - bool useusername; + AuthField field; public: ModuleLDAPAuth() @@ -344,7 +352,11 @@ public: vhost = tag->getString("host"); // Set to true if failed connects should be reported to operators verbose = tag->getBool("verbose"); - useusername = tag->getBool("useusername", tag->getBool("userfield")); + field = tag->getEnum("field", tag->getBool("useusername") ? AuthField::USERNAME : AuthField::NICKNAME, { + { "nickname", AuthField::USERNAME }, + { "password", AuthField::PASSWORD }, + { "username", AuthField::NICKNAME }, + }); LDAP.SetProvider("LDAP/" + tag->getString("dbid")); @@ -417,18 +429,33 @@ public: return MOD_RES_DENY; } - std::string what; - std::string::size_type pos = user->password.find(':'); - if (pos != std::string::npos) + std::string what = attribute + "="; + switch (field) { - what = attribute + "=" + user->password.substr(0, pos); + case AuthField::NICKNAME: + what += user->nick; + break; - // Trim the user: prefix, leaving just 'pass' for later password check - user->password = user->password.substr(pos + 1); - } - else - { - what = attribute + "=" + (useusername ? user->GetRealUser() : user->nick); + case AuthField::USERNAME: + what += user->GetRealUser(); + break; + + case AuthField::PASSWORD: + { + auto pos = user->password.find(':'); + if (pos == std::string::npos) + { + if (verbose) + ServerInstance->SNO.WriteToSnoMask('c', "Forbidden connection from {} (no username provided)", user->GetRealMask()); + ServerInstance->Users.QuitUser(user, killreason); + return MOD_RES_DENY; + } + + what += user->password.substr(0, pos); + user->password.erase(0, pos + 1); + user->password.shrink_to_fit(); + break; + } } try -- cgit v1.3.1-10-gc9f91