summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/opers.conf.example3
-rw-r--r--include/configreader.h12
-rw-r--r--include/users.h3
-rw-r--r--src/commands/cmd_notice.cpp5
-rw-r--r--src/configreader.cpp10
-rw-r--r--src/inspircd.cpp2
-rw-r--r--src/users.cpp74
7 files changed, 93 insertions, 16 deletions
diff --git a/conf/opers.conf.example b/conf/opers.conf.example
index c8bdc0a64..d1e317aad 100644
--- a/conf/opers.conf.example
+++ b/conf/opers.conf.example
@@ -17,6 +17,9 @@
# commands: oper commands that users of this class can run.
commands="DIE RESTART REHASH LOADMODULE UNLOADMODULE RELOAD"
+ # privs: special priviledges that users with this class may utilise.
+# privs="users/mass-message"
+
# usermodes: Oper-only usermodes that opers with this class can use.
usermodes="*"
diff --git a/include/configreader.h b/include/configreader.h
index 41a0fc9b1..89116c5c5 100644
--- a/include/configreader.h
+++ b/include/configreader.h
@@ -232,13 +232,19 @@ struct operclass_data : public Extensible
{
/** Command list for the class
*/
- char* commandlist;
+ char *commandlist;
+
/** Channel mode list for the class
*/
- char* cmodelist;
+ char *cmodelist;
+
/** User mode list for the class
*/
- char* umodelist;
+ char *umodelist;
+
+ /** Priviledges given by this class
+ */
+ char *privs;
};
/** A Set of oper classes
diff --git a/include/users.h b/include/users.h
index 2f8730088..d8a9b3e64 100644
--- a/include/users.h
+++ b/include/users.h
@@ -794,8 +794,9 @@ class CoreExport User : public EventHandler
* all operators, yet are not commands. An example might be oper override, mass messaging (/notice $*), etc.
*
* @param privstr The priv to chec, e.g. "users/override/topic". These are loaded free-form from the config file.
+ * @param noisy If set to true, the user is notified that they do not have the specified permission where applicable. If false, no notification is sent.
* @return True if this user has the permission in question.
- */ bool HasPrivPermission(const std::string &privstr);
+ */ bool HasPrivPermission(const std::string &privstr, bool noisy = true);
/** Returns true or false if a user can set a privileged user or channel mode.
* This is done by looking up their oper type from User::oper, then referencing
diff --git a/src/commands/cmd_notice.cpp b/src/commands/cmd_notice.cpp
index 37f11eeb9..537f8ac78 100644
--- a/src/commands/cmd_notice.cpp
+++ b/src/commands/cmd_notice.cpp
@@ -30,8 +30,11 @@ CmdResult CommandNotice::Handle (const std::vector<std::string>& parameters, Use
if (ServerInstance->Parser->LoopCall(user, this, parameters, 0))
return CMD_SUCCESS;
- if ((parameters[0][0] == '$') && (IS_OPER(user) || ServerInstance->ULine(user->server)))
+ if (parameters[0][0] == '$')
{
+ if (!user->HasPrivPermission("users/mass-message"))
+ return CMD_SUCCESS;
+
int MOD_RESULT = 0;
std::string temp = parameters[1];
FOREACH_RESULT(I_OnUserPreNotice,OnUserPreNotice(user, (void*)parameters[0].c_str(), TYPE_SERVER, temp, 0, exempt_list));
diff --git a/src/configreader.cpp b/src/configreader.cpp
index 118507861..189146137 100644
--- a/src/configreader.cpp
+++ b/src/configreader.cpp
@@ -913,9 +913,9 @@ void ServerConfig::Read(bool bail, const std::string &useruid)
InitTypes, DoType, DoneClassesAndTypes},
{"class",
- {"name", "commands", "usermodes", "chanmodes", NULL},
- {"", "", "", "", NULL},
- {DT_NOSPACES, DT_CHARPTR, DT_CHARPTR, DT_CHARPTR},
+ {"name", "commands", "usermodes", "chanmodes", "privs", NULL},
+ {"", "", "", "", "", NULL},
+ {DT_NOSPACES, DT_CHARPTR, DT_CHARPTR, DT_CHARPTR, DT_CHARPTR},
InitClasses, DoClass, DoneClassesAndTypes},
{NULL,
@@ -2224,6 +2224,8 @@ bool InitClasses(ServerConfig* conf, const char*)
delete[] n->second.cmodelist;
if (n->second.umodelist)
delete[] n->second.umodelist;
+ if (n->second.privs)
+ delete[] n->second.privs;
}
}
@@ -2252,6 +2254,7 @@ bool DoClass(ServerConfig* conf, const char* tag, char**, ValueList &values, int
const char* CommandList = values[1].GetString();
const char* UModeList = values[2].GetString();
const char* CModeList = values[3].GetString();
+ const char *PrivsList = values[4].GetString();
for (const char* c = UModeList; *c; ++c)
{
@@ -2271,6 +2274,7 @@ bool DoClass(ServerConfig* conf, const char* tag, char**, ValueList &values, int
conf->operclass[ClassName].commandlist = strnewdup(CommandList);
conf->operclass[ClassName].umodelist = strnewdup(UModeList);
conf->operclass[ClassName].cmodelist = strnewdup(CModeList);
+ conf->operclass[ClassName].privs = strnewdup(PrivsList);
return true;
}
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 3a2392ee6..463f9d82f 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -656,8 +656,6 @@ InspIRCd::InspIRCd(int argc, char** argv)
/* set up fake client again this time with the correct uid */
this->FakeClient = new User(this, "#INVALID");
this->FakeClient->SetFd(FD_MAGIC_NUMBER);
- this->FakeClient->HasPrivPermission("users/override/topic");
- exit(0);
// Get XLine to do it's thing.
this->XLines->CheckELines();
diff --git a/src/users.cpp b/src/users.cpp
index 3b69c1a25..2b6e00e0e 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -216,7 +216,7 @@ User::User(InspIRCd* Instance, const std::string &uid) : ServerInstance(Instance
Visibility = NULL;
ip = NULL;
MyClass = NULL;
- AllowedOperCommands = NULL;
+ AllowedPrivs = AllowedOperCommands = NULL;
chans.clear();
invites.clear();
@@ -242,12 +242,19 @@ User::~User()
this->MyClass->RefCount--;
ServerInstance->Logs->Log("USERS", DEBUG, "User destructor -- connect refcount now: %lu", this->MyClass->RefCount);
}
+
if (this->AllowedOperCommands)
{
delete AllowedOperCommands;
AllowedOperCommands = NULL;
}
+ if (this->AllowedPrivs)
+ {
+ delete AllowedPrivs;
+ AllowedPrivs = NULL;
+ }
+
this->InvalidateCache();
this->DecrementModes();
@@ -505,10 +512,46 @@ bool User::HasPermission(const std::string &command)
}
-bool User::HasPrivPermission(const std::string &privstr)
+bool User::HasPrivPermission(const std::string &privstr, bool noisy)
{
- ServerInstance->Logs->Log("CRAP", DEBUG, "Checking if I have " + privstr);
- return true;
+ ServerInstance->Logs->Log("PRIVS", DEBUG, "Checking if I have " + privstr);
+ if (!IS_LOCAL(this))
+ {
+ ServerInstance->Logs->Log("PRIVS", DEBUG, "Remote (yes)");
+ return true;
+ }
+
+ if (!IS_OPER(this))
+ {
+ if (noisy)
+ this->WriteServ("NOTICE %s :You are not an oper", this->nick.c_str());
+ ServerInstance->Logs->Log("PRIVS", DEBUG, "Not oper (no)");
+ return false;
+ }
+
+ if (!AllowedPrivs)
+ {
+ if (noisy)
+ this->WriteServ("NOTICE %s :Privset empty(!?)", this->nick.c_str());
+ ServerInstance->Logs->Log("PRIVS", DEBUG, "No privs(?) (no)");
+ return false;
+ }
+
+ if (AllowedPrivs->find(privstr) != AllowedPrivs->end())
+ {
+ ServerInstance->Logs->Log("PRIVS", DEBUG, "I do have it.");
+ return true;
+ }
+ else if (AllowedPrivs->find("*") != AllowedPrivs->end())
+ {
+ ServerInstance->Logs->Log("PRIVS", DEBUG, "I allow all.");
+ return true;
+ }
+
+ if (noisy)
+ this->WriteServ("NOTICE %s :Oper type %s does not have access to priv %s", this->nick.c_str(), this->oper.c_str(), privstr.c_str());
+ ServerInstance->Logs->Log("PRIVS", DEBUG, "I don't have it...");
+ return false;
}
bool User::AddBuffer(const std::string &a)
@@ -717,28 +760,40 @@ void User::Oper(const std::string &opertype, const std::string &opername)
opertype_t::iterator iter_opertype = ServerInstance->Config->opertypes.find(this->oper.c_str());
if (iter_opertype != ServerInstance->Config->opertypes.end())
{
-
if (AllowedOperCommands)
AllowedOperCommands->clear();
else
AllowedOperCommands = new std::set<std::string>;
+ if (AllowedPrivs)
+ AllowedPrivs->clear();
+ else
+ AllowedPrivs = new std::set<std::string>;
+
AllowedUserModes.reset();
AllowedChanModes.reset();
this->AllowedUserModes['o' - 'A'] = true; // Call me paranoid if you want.
- std::string myclass, mycmd;
+ std::string myclass, mycmd, mypriv;
irc::spacesepstream Classes(iter_opertype->second);
while (Classes.GetToken(myclass))
{
operclass_t::iterator iter_operclass = ServerInstance->Config->operclass.find(myclass.c_str());
if (iter_operclass != ServerInstance->Config->operclass.end())
{
+ /* Process commands */
irc::spacesepstream CommandList(iter_operclass->second.commandlist);
while (CommandList.GetToken(mycmd))
{
this->AllowedOperCommands->insert(mycmd);
}
+
+ irc::spacesepstream PrivList(iter_operclass->second.privs);
+ while (PrivList.GetToken(mypriv))
+ {
+ this->AllowedPrivs->insert(mypriv);
+ }
+
for (unsigned char* c = (unsigned char*)iter_operclass->second.umodelist; *c; ++c)
{
if (*c == '*')
@@ -750,6 +805,7 @@ void User::Oper(const std::string &opertype, const std::string &opername)
this->AllowedUserModes[*c - 'A'] = true;
}
}
+
for (unsigned char* c = (unsigned char*)iter_operclass->second.cmodelist; *c; ++c)
{
if (*c == '*')
@@ -804,6 +860,12 @@ void User::UnOper()
AllowedOperCommands = NULL;
}
+ if (AllowedPrivs)
+ {
+ delete AllowedPrivs;
+ AllowedPrivs = NULL;
+ }
+
AllowedUserModes.reset();
AllowedChanModes.reset();
}