diff options
-rw-r--r-- | include/configreader.h | 9 | ||||
-rw-r--r-- | src/configreader.cpp | 26 | ||||
-rw-r--r-- | src/mode.cpp | 11 | ||||
-rw-r--r-- | src/modules/m_conn_umodes.cpp | 7 |
4 files changed, 53 insertions, 0 deletions
diff --git a/include/configreader.h b/include/configreader.h index 877cb823d..7a753bcc7 100644 --- a/include/configreader.h +++ b/include/configreader.h @@ -446,6 +446,15 @@ class CoreExport ServerConfig : public Extensible */ char DisabledCommands[MAXBUF]; + /** This variable identifies which usermodes have been diabled. + */ + + char DisabledUModes[64]; + + /** This variable identifies which chanmodes have been disabled. + */ + char DisabledCModes[64]; + /** The full path to the modules directory. * This is either set at compile time, or * overridden in the configuration file via diff --git a/src/configreader.cpp b/src/configreader.cpp index 29ee55eb9..a302dd6ea 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -299,6 +299,28 @@ bool InitializeDisabledCommands(const char* data, InspIRCd* ServerInstance) return true; } +bool ValidateDisabledUModes(ServerConfig* conf, const char*, const char*, ValueItem &data) +{ + memset(conf->DisabledUModes, 0, 64); + for (const unsigned char* p = (const unsigned char*)data.GetString(); *p; ++p) + { + if (*p < 'A' || *p > ('A' + 64)) throw CoreException(std::string("Invalid usermode ")+(char)*p+" was found."); + conf->DisabledUModes[*p - 'A'] = 1; + } + return true; +} + +bool ValidateDisabledCModes(ServerConfig* conf, const char*, const char*, ValueItem &data) +{ + memset(conf->DisabledCModes, 0, 64); + for (const unsigned char* p = (const unsigned char*)data.GetString(); *p; ++p) + { + if (*p < 'A' || *p > ('A' + 64)) throw CoreException(std::string("Invalid chanmode ")+(char)*p+" was found."); + conf->DisabledCModes[*p - 'A'] = 1; + } + return true; +} + bool ValidateDnsServer(ServerConfig* conf, const char*, const char*, ValueItem &data) { if (!*(data.GetString())) @@ -763,6 +785,8 @@ void ServerConfig::Read(bool bail, User* user) static char hidemodes[MAXBUF]; /* Modes to not allow listing from users below halfop */ static char exemptchanops[MAXBUF]; /* Exempt channel ops from these modes */ static char announceinvites[MAXBUF]; /* options:announceinvites setting */ + static char disabledumodes[MAXBUF]; /* Disabled usermodes */ + static char disabledcmodes[MAXBUF]; /* Disabled chanmodes */ errstr.clear(); include_stack.clear(); @@ -823,6 +847,8 @@ void ServerConfig::Read(bool bail, User* user) {"dns", "timeout", "5", new ValueContainerInt (&this->dns_timeout), DT_INTEGER, NoValidation}, {"options", "moduledir", MOD_PATH, new ValueContainerChar (this->ModPath), DT_CHARPTR, NoValidation}, {"disabled", "commands", "", new ValueContainerChar (this->DisabledCommands), DT_CHARPTR, NoValidation}, + {"disabled", "usermodes", "", new ValueContainerChar (disabledumodes), DT_CHARPTR, ValidateDisabledUModes}, + {"disabled", "chanmodes", "", new ValueContainerChar (disabledcmodes), DT_CHARPTR, ValidateDisabledCModes}, {"security", "userstats", "", new ValueContainerChar (this->UserStats), DT_CHARPTR, NoValidation}, {"security", "customversion","", new ValueContainerChar (this->CustomVersion), DT_CHARPTR, NoValidation}, {"security", "hidesplits", "0", new ValueContainerBool (&this->HideSplits), DT_BOOLEAN, NoValidation}, diff --git a/src/mode.cpp b/src/mode.cpp index ca30f1b69..bce2b2019 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -641,6 +641,17 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user, if (abort) continue; + /* If it's disabled, they have to be an oper. + */ + if (IS_LOCAL(user) && !IS_OPER(user) && ((type == MODETYPE_CHANNEL ? ServerInstance->Config->DisabledCModes : ServerInstance->Config->DisabledUModes)[modehandlers[handler_id]->GetModeChar() - 'A'])) + { + user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Permission Denied - %s mode %c has been locked by the administrator", + user->nick.c_str(), + type == MODETYPE_CHANNEL ? "channel" : "user", + modehandlers[handler_id]->GetModeChar()); + continue; + } + /* It's an oper only mode, check if theyre an oper. If they arent, * eat any parameter that came with the mode, and continue to next */ diff --git a/src/modules/m_conn_umodes.cpp b/src/modules/m_conn_umodes.cpp index e7ff2c584..42c0ec660 100644 --- a/src/modules/m_conn_umodes.cpp +++ b/src/modules/m_conn_umodes.cpp @@ -54,6 +54,11 @@ class ModuleModesOnConnect : public Module if (!IS_LOCAL(user)) return; + // Backup and zero out the disabled usermodes, so that we can override them here. + char save[64]; + memcpy(save, ServerInstance->Config->DisabledUModes, 64); + memset(ServerInstance->Config->DisabledUModes, 0, 64); + for (int j = 0; j < Conf->Enumerate("connect"); j++) { std::string hostn = Conf->ReadValue("connect","allow",j); @@ -90,6 +95,8 @@ class ModuleModesOnConnect : public Module break; } } + + memcpy(ServerInstance->Config->DisabledUModes, save, 64); } }; |