# 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="*"
{
/** 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
* 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
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));
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,
delete[] n->second.cmodelist;
if (n->second.umodelist)
delete[] n->second.umodelist;
+ if (n->second.privs)
+ delete[] n->second.privs;
}
}
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)
{
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;
}
/* 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();
Visibility = NULL;
ip = NULL;
MyClass = NULL;
- AllowedOperCommands = NULL;
+ AllowedPrivs = AllowedOperCommands = NULL;
chans.clear();
invites.clear();
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();
}
-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)
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 == '*')
this->AllowedUserModes[*c - 'A'] = true;
}
}
+
for (unsigned char* c = (unsigned char*)iter_operclass->second.cmodelist; *c; ++c)
{
if (*c == '*')
AllowedOperCommands = NULL;
}
+ if (AllowedPrivs)
+ {
+ delete AllowedPrivs;
+ AllowedPrivs = NULL;
+ }
+
AllowedUserModes.reset();
AllowedChanModes.reset();
}