summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/configreader.h9
-rw-r--r--src/configreader.cpp26
-rw-r--r--src/mode.cpp11
-rw-r--r--src/modules/m_conn_umodes.cpp7
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);
}
};