diff options
-rw-r--r-- | data/chanserv.example.conf | 670 | ||||
-rw-r--r-- | include/access.h | 2 | ||||
-rw-r--r-- | modules/commands/cs_access.cpp | 27 | ||||
-rw-r--r-- | modules/commands/cs_flags.cpp | 16 | ||||
-rw-r--r-- | src/access.cpp | 43 | ||||
-rw-r--r-- | src/config.cpp | 34 | ||||
-rw-r--r-- | src/init.cpp | 1 |
7 files changed, 644 insertions, 149 deletions
diff --git a/data/chanserv.example.conf b/data/chanserv.example.conf index 7992fef9d..66020aaf6 100644 --- a/data/chanserv.example.conf +++ b/data/chanserv.example.conf @@ -170,98 +170,588 @@ chanserv * This directive is optional. */ #opersonly = yes +} - /* - * ChanServ levels configuration, for use with cs_access. - * - * These levels are used by the chanserv/access access system. - * The levels configured below will be used as a default by newly registered channels. - * - * The level "founder" is a special level that means anyone with the level_founder permission - * can use (which of course defaults to "founder"). Anyone with the founder level permission in - * a channel can do anything in the channel. - * - * The level "disabled" is a special level that means the level is disabled, even from people - * with founder level access. - */ - level_access_change = 10 - level_access_list = 1 - level_akick = 10 - level_assign = "founder" - level_autohalfop = 4 - level_autoop = 5 - level_autoowner = 9999 - level_autoprotect = 10 - level_autovoice = 3 - level_badwords = 10 - level_ban = 4 - level_fantasia = 3 - level_founder = "founder" - level_getkey = 5 - level_greet = 5 - level_halfop = 5 - level_halfopme = 4 - level_info = 9999 - level_invite = 5 - level_kick = 4 - level_memo = 10 - level_mode = 5 - level_nokick = 1 - level_opdeop = 5 - level_opdeopme = 5 - level_owner = "founder" - level_ownerme = 9999 - level_protect = 9999 - level_protectme = 10 - level_say = 5 - level_signkick = 9999 - level_set = 9999 - level_topic = 5 - level_unban = 4 - level_voice = 4 - level_voiceme = 3 +/* + * ChanServ privilege configuration. + * + * ChanServ privileges are used to determine who has what access in channels. By default the core has its own + * set of levels it uses for various ChanServ commands, which are defined below. + * + * If you loaded cs_access, you may define a level for the privilege, which is used by chanserv/access and chanserv/levels. + * The levels defined will be used as the default levels for newly registered channels. + * The level "founder" is a special level which means anyone with the privilege FOUNDER on the channel + * has that permission. Additionally, the level "disabled" means that no one can use the privilege, including founders. + * + * If you loaded cs_flags, you may define a flag associated with that privilege for use in chanserv/flags. + * + * Defining new privileges here is not useful unless you have a module (eg, a third party one) made to check for + * the specific level you are defining. + * + * Sane defaults are provided below that do not need to be edited unless you wish to change the default behavior. + */ - /* - * ChanServ flags configuration, for use with cs_flags. - * - * These flags are used by the chanserv/flags access system. - */ - flag_access_change = "f" - flag_access_list = "l" - flag_akick = "K" - flag_assign = "s" - flag_autohalfop = "H" - flag_autoop = "O" - flag_autoowner = "Q" - flag_autoprotect = "A" - flag_autovoice = "V" - flag_badwords = "k" - flag_ban = "b" - flag_fantasia = "c" - flag_founder = "F" - flag_getkey = "G" - flag_greet = "g" - flag_halfop = "h" - flag_halfopme = "h" - flag_info = "I" - flag_invite = "i" - flag_kick = "k" - flag_memo = "m" - flag_mode = "s" - flag_nokick = "N" - flag_opdeop = "o" - flag_opdeopme = "o" - flag_owner = "q" - flag_ownerme = "q" - flag_protect = "a" - flag_protectme = "a" - flag_say = "B" - flag_set = "s" - flag_signkick = "K" - flag_topic = "t" - flag_unban = "u" - flag_voice = "v" - flag_voiceme = "v" +/* + * ACCESS_CHANGE privilege. + * + * Used by chanserv/access, chanserv/flags and chanserv/xop. + * + * Users with this permission can modify the permissions of others. + */ +privilege +{ + name = "ACCESS_CHANGE" + desc = "Allowed to modify the access list" + level = 10 + flag = "f" +} + +/* + * ACCESS_LIST privilege. + * + * Used by chanserv/access, chanserv/flags, and chanserv/xop. + * + * Users with this permission can view the access list of channels. + */ +privilege +{ + name = "ACCESS_LIST" + desc = "Allowed to view the access list" + level = 10 + flag = "f" +} + +/* + * AKICK privilege. + * + * Used by chanserv/akick and chanserv/enforce. + * + * Users with this permission can modify the AKICK list. + */ +privilege +{ + name = "AKICK" + desc = "Allowed to use the AKICK command" + level = 10 + flag = "K" +} + +/* + * ASSIGN privilege. + * + * Used by botserv/assign. + * + * Users with this permission can assign and unassign BotServ bots to and from the channel. + */ +privilege +{ + name = "ASSIGN" + desc = "Allowed to assign/unassign a bot" + level = "founder" + flag = "s" +} + +/* + * AUTOHALFOP privilege. + * + * Used by the core. + * + * Users with this permission get halfop on join. + */ +privilege +{ + name = "AUTOHALFOP" + desc = "Automatic mode +h" + level = 4 + flag = "H" +} + +/* + * AUTOOP privilege. + * + * Used by the core. + * + * Users with this permission get op on join. + */ +privilege +{ + name = "AUTOOP" + desc = "Automatic channel operator status" + level = 5 + flag = "O" +} + +/* + * AUTOOWNER privilege. + * + * Used by the core. + * + * Users with this permission get owner on join. + */ +privilege +{ + name = "AUTOOWNER" + desc = "Automatic mode +q" + level = 9999 + flag = "Q" +} + +/* + * AUTOPROTECT privilege. + * + * Used by the core. + * + * Users with this permission get admin on join. + */ +privilege +{ + name = "AUTOPROTECT" + desc = "Automatic mode +a" + level = 10 + flag = "A" +} + +/* + * AUTOVOICE privilege. + * + * Used by the core. + * + * Users with this permission get voice on join. + */ +privilege +{ + name = "AUTOVOICE" + desc = "Automatic mode +v" + level = 3 + flag = "V" +} + +/* + * BADWORDS privilege. + * + * Used by botserv/badwords. + * + * Users with this permission can modify BotServ's BADWORDS list. + */ +privilege +{ + name = "BADWORDS" + desc = "Allowed to modify channel badwords list" + level = 10 + flag = "K" +} + +/* + * BAN privilege. + * + * Used by chanserv/ban and chanserv/tban. + * + * Users with this permission can use the BAN command. + */ +privilege +{ + name = "BAN" + desc = "Allowed to use ban users" + level = 4 + flag = "b" +} + +/* + * FANTASIA privilege. + * + * Used by botserv/main and chanserv/xop. + * + * Users with this permission can use fantasy commands in the channel. + */ +privilege +{ + name = "FANTASIA" + desc = "Allowed to use fantasy commands" + level = 3 + flag = "c" +} + +/* + * FOUNDER privilege. + * + * Used by botserv/info, chanserv/access, chanserv/akick, + * chanserv/clearusers, chanserv/drop, chanserv/set/founder, + * chanserv/set/securefounder, chanserv/set/successor and chanserv/xop. + * + * Users with this permission are treated as founders and can use + * commands restricted to founders. + */ +privilege +{ + name = "FOUNDER" + desc = "Allowed to issue commands restricted to channel founders" + level = "founder" + flag = "F" +} + +/* + * GETKEY privilege. + * + * Used by chanserv/getkey and nickserv/ajoin. + * + * Users with this permission can get they channel key with GETKEY and + * can use nickserv/ajoin to join channels with keys. + */ +privilege +{ + name = "GETKEY" + desc = "Allowed to use GETKEY command" + level = 5 + flag = "G" +} + +/* + * GREET privilege. + * + * Used by botserv/main. + * + * Users with this permission get their greet shown on join. + */ +privilege +{ + name = "GREET" + desc = "Greet message displayede on join" + level = 5 + flag = "g" +} + +/* + * HALFOP privilege. + * + * Used by chanserv/mode, chanserv/halfop and chanserv/dehalfop. + * + * Users with this permission can use ChanServ to halfop and dehalfop + * others in the channel. + */ +privilege +{ + name = "HALFOP" + desc = "Allowed to (de)halfop users" + level = 5 + flag = "h" +} + +/* + * HALFOPME privilege. + * + * Used by chanserv/mode, chanserv/halfop and chanserv/dehalfop. + * + * Users with this permission can use ChanServ to halfop and dehalfop + * themselves in the channel. + */ +privilege +{ + name = "HALFOPME" + desc = "Allowed to (de)halfop him/herself" + level = 4 + flag = "h" +} + +/* + * INFO privilege. + * + * Used by botserv/info and chanserv/info. + * + * Users with this permission are allowed to get the full INFO output + * from BotServ and ChanServ. + */ +privilege +{ + name = "INFO" + desc = "Allowed to get full INFO output" + level = 9999 + flag = "I" +} + +/* + * INVITE privilege. + * + * Used by chanserv/invite and nickserv/ajoin. + * + * Users with this permission can invite users through ChanServ and + * join invite only channels with nickserv/ajoin. + */ +privilege +{ + name = "INVITE" + desc = "Allowed to use the INVITE command" + level = 5 + flag = "i" +} + +/* + * KICK privilege. + * + * Used by chanserv/kick. + * + * Users with this permission can use the KICK command. + */ +privilege +{ + name = "KICK" + desc = "Allowed to use the KICK command" + level = 4 + flag = "k" +} + +/* + * MEMO privilege. + * + * Used by memoserv/del, memoserv/ignore, memoserv/info, memoserv/list, + * memoserv/main, memoserv/read and memoserv/set. + * + * Users with this permission can manage channel memos. + */ +privilege +{ + name = "MEMO" + desc = "Allowed to read channel memos" + level = 10 + flag = "m" +} + +/* + * MODE privilege. + * + * Used by chanserv/mode. + * + * Users with this permission can set modes through ChanServ and change + * the mode lock. + */ +privilege +{ + name = "MODE" + desc = "Allowed to use the MODE command" + level = 5 + flag = "s" +} + +/* + * NOKICK privilege. + * + * Used by botserv/kick. + * + * Users with this permission are spared from automated BotServ kicks. + */ +privilege +{ + name = "NOKICK" + desc = "Prevents users being kicked by Services" + level = 1 + flag = "N" +} + +/* + * OPDEOP privilege. + * + * Used by chanserv/mode, chanserv/op and chanserv/deop. + * + * Users with this permission can use ChanServ to op and deop + * others in the channel. + */ +privilege +{ + name = "OPDEOP" + desc = "Allowed to (de)op users" + level = 5 + flag = "o" +} + +/* + * OPDEOPME privilege. + * + * Used by chanserv/mode, chanserv/op and chanserv/deop. + * + * Users with this permission can use ChanServ to op and deop + * themselves in the channel. + */ +privilege +{ + name = "OPDEOPME" + desc = "Allowed to (de)op him/herself" + level = 5 + flag = "o" +} + +/* + * OWNER privilege. + * + * Used by chanserv/mode, chanserv/owner and chanserv/deowner. + * + * Users with this permission can use ChanServ to owner and deowner + * others in the channel. + */ +privilege +{ + name = "OWNER" + desc = "Allowed to (de)owner users" + level = "founder" + flag = "q" +} + +/* + * OWNERME privilege. + * + * Used by chanserv/mode, chanserv/owner and chanserv/deowner. + * + * Users with this permission can use ChanServ to owner and deowner + * themselves in the channel. + */ +privilege +{ + name = "OWNERME" + desc = "Allowed to (de)owner him/herself" + level = "9999" + flag = "q" +} + +/* + * PROTECT privilege. + * + * Used by chanserv/mode, chanserv/protect and chanserv/deprotect. + * + * Users with this permission can use ChanServ to protect and deprotect + * others in the channel. + */ +privilege +{ + name = "PROTECT" + desc = "Allowed to (de)protect users" + level = 9999 + flag = "a" +} + +/* + * PROTECTME privilege. + * + * Used by chanserv/mode, chanserv/protect and chanserv/deprotect. + * + * Users with this permission can use ChanServ to protect and deprotect + * themselves in the channel. + */ +privilege +{ + name = "PROTECTME" + desc = "Allowed to (de)protect him/herself" + level = 10 + flag = "a" +} + +/* + * SAY privilege. + * + * Used by botserv/control. + * + * Users with this permission can use the BotServ bot in the channel to + * say or do a /me with the provided message. + */ +privilege +{ + name = "SAY" + desc = "Allowed to use SAY and ACT commands" + level = 5 + flag = "B" +} + +/* + * SET privilege. + * + * Used by botserv/kick, botserv/set, chanserv/clone, chanserv/log, + * chanserv/saset/noexpire and chanserv/set. + * + * Users with this permission can set what BotServ will kick for, change + * BotServ and ChanServ settings, clone ChanServ channel setings, and + * set ChanServ logging options. + */ +privilege +{ + name = "SET" + desc = "Allowed to set channel settings" + level = 9999 + flag = "s" +} + +/* + * SIGNKICK privilege. + * + * Used by chanserv/ban and chanserv/kick. + * + * Users with this permission won't get their nick shown in the kick + * through ChanServ when the setting SIGNKICK is set to LEVEL. + */ +privilege +{ + name = "SIGNKICK" + desc = "No signed kick when SIGNKICK LEVEL is used" + level = 9999 + flag = "K" +} + +/* + * TOPIC privilege. + * + * Used by chanserv/appendtopic and chanserv/topic. + * + * Users with this permission can change the channel topic through ChanServ. + */ +privilege +{ + name = "TOPIC" + desc = "Allowed to change channel topics" + level = 5 + flag = "t" +} + +/* + * UNBAN privilege. + * + * Used by chanserv/unban. + * + * Users with this permission can unban themselves and others through ChanServ. + */ +privilege +{ + name = "UNBAN" + desc = "Allowed to unban users" + level = 4 + flag = "u" +} + +/* + * VOICE privilege. + * + * Used by chanserv/mode, chanserv/voice and chanserv/devoice. + * + * Users with this permission can use ChanServ to voice and devoice + * others in the channel. + */ +privilege +{ + name = "VOICE" + desc = "Allowed to (de)voice users" + level = 4 + flag = "v" +} + +/* + * VOICEME privilege. + * + * Used by chanserv/mode, chanserv/voice and chanserv/devoice. + * + * Users with this permission can use ChanServ to voice and devoice + * themselves in the channel. + */ +privilege +{ + name = "VOICEME" + desc = "Allowed to (de)voice him/herself" + level = 3 + flag = "v" } /* diff --git a/include/access.h b/include/access.h index 6557d40c6..229a16f4b 100644 --- a/include/access.h +++ b/include/access.h @@ -17,8 +17,8 @@ class PrivilegeManager static void AddPrivilege(Privilege p, int pos = -1, int def = 0); static void RemovePrivilege(Privilege &p); static Privilege *FindPrivilege(const Anope::string &name); - static void Init(); static std::vector<Privilege> &GetPrivileges(); + static void ClearPrivileges(); }; class ChanAccess; diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp index c5f8313f0..2821ba5c3 100644 --- a/modules/commands/cs_access.cpp +++ b/modules/commands/cs_access.cpp @@ -19,12 +19,12 @@ enum ACCESS_FOUNDER = 10001 }; -static std::map<Anope::string, int16> defaultLevels; +static std::map<Anope::string, int16, std::less<ci::string> > defaultLevels; static void reset_levels(ChannelInfo *ci) { ci->ClearLevels(); - for (std::map<Anope::string, int16>::iterator it = defaultLevels.begin(), it_end = defaultLevels.end(); it != it_end; ++it) + for (std::map<Anope::string, int16, std::less<ci::string> >::iterator it = defaultLevels.begin(), it_end = defaultLevels.end(); it != it_end; ++it) ci->SetLevel(it->first, it->second); } @@ -849,26 +849,27 @@ class CSAccess : public Module void OnReload() { - std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges(); - std::map<Anope::string, int16> tLevels; + defaultLevels.clear(); ConfigReader config; - for (unsigned i = 0; i < privs.size(); ++i) + for (int i = 0; i < config.Enumerate("privilege"); ++i) { - Privilege &p = privs[i]; + const Anope::string &pname = config.ReadValue("privilege", "name", "", i); + + Privilege *p = PrivilegeManager::FindPrivilege(pname); + if (p == NULL) + continue; - const Anope::string &value = config.ReadValue("chanserv", "level_" + p.name.lower(), "", 0); + const Anope::string &value = config.ReadValue("privilege", "level", "", i); if (value.empty()) - throw ConfigException("The value for <chanserv:level_" + p.name.lower() + "> must not be empty!"); + continue; else if (value.equals_ci("founder")) - tLevels[p.name] = ACCESS_FOUNDER; + defaultLevels[p->name] = ACCESS_FOUNDER; else if (value.equals_ci("disabled")) - tLevels[p.name] = ACCESS_INVALID; + defaultLevels[p->name] = ACCESS_INVALID; else - tLevels[p.name] = config.ReadInteger("chanserv", "level_" + p.name.lower(), 0, false); + defaultLevels[p->name] = config.ReadInteger("privilege", "level", i, false); } - - defaultLevels = tLevels; } void OnCreateChan(ChannelInfo *ci) diff --git a/modules/commands/cs_flags.cpp b/modules/commands/cs_flags.cpp index 64ecb7323..5ead6f2d9 100644 --- a/modules/commands/cs_flags.cpp +++ b/modules/commands/cs_flags.cpp @@ -390,15 +390,21 @@ class CSFlags : public Module void OnReload() { ConfigReader config; - std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges(); + defaultFlags.clear(); - for (unsigned i = 0; i < privs.size(); ++i) + for (int i = 0; i < config.Enumerate("privilege"); ++i) { - Privilege &p = privs[i]; - const Anope::string &value = config.ReadValue("chanserv", "flag_" + p.name, "", 0); + const Anope::string &pname = config.ReadValue("privilege", "name", "", i); + + Privilege *p = PrivilegeManager::FindPrivilege(pname); + if (p == NULL) + continue; + + const Anope::string &value = config.ReadValue("privilege", "flag", "", i); if (value.empty()) continue; - defaultFlags[p.name] = value[0]; + + defaultFlags[p->name] = value[0]; } } }; diff --git a/src/access.cpp b/src/access.cpp index 09310d441..8a293a42d 100644 --- a/src/access.cpp +++ b/src/access.cpp @@ -56,49 +56,14 @@ Privilege *PrivilegeManager::FindPrivilege(const Anope::string &name) return NULL; } -void PrivilegeManager::Init() +std::vector<Privilege> &PrivilegeManager::GetPrivileges() { - AddPrivilege(Privilege("ACCESS_LIST", _("Allowed to view the access list"))); - AddPrivilege(Privilege("NOKICK", _("Prevents users being kicked by Services"))); - AddPrivilege(Privilege("FANTASIA", _("Allowed to use fantasy commands"))); - AddPrivilege(Privilege("FOUNDER", _("Allowed to issue commands restricted to channel founders"))); - AddPrivilege(Privilege("GREET", _("Greet message displayed"))); - AddPrivilege(Privilege("AUTOVOICE", _("Automatic mode +v"))); - AddPrivilege(Privilege("VOICEME", _("Allowed to (de)voice him/herself"))); - AddPrivilege(Privilege("VOICE", _("Allowed to (de)voice users"))); - AddPrivilege(Privilege("INFO", _("Allowed to use INFO command with ALL option"))); - AddPrivilege(Privilege("SAY", _("Allowed to use SAY and ACT commands"))); - AddPrivilege(Privilege("AUTOHALFOP", _("Automatic mode +h"))); - AddPrivilege(Privilege("HALFOPME", _("Allowed to (de)halfop him/herself"))); - AddPrivilege(Privilege("HALFOP", _("Allowed to (de)halfop users"))); - AddPrivilege(Privilege("KICK", _("Allowed to use the KICK command"))); - AddPrivilege(Privilege("SIGNKICK", _("No signed kick when SIGNKICK LEVEL is used"))); - AddPrivilege(Privilege("BAN", _("Allowed to use ban users"))); - AddPrivilege(Privilege("TOPIC", _("Allowed to change channel topics"))); - AddPrivilege(Privilege("MODE", _("Allowed to change channel modes"))); - AddPrivilege(Privilege("GETKEY", _("Allowed to use GETKEY command"))); - AddPrivilege(Privilege("INVITE", _("Allowed to use the INVITE command"))); - AddPrivilege(Privilege("UNBAN", _("Allowed to unban users"))); - AddPrivilege(Privilege("AUTOOP", _("Automatic channel operator status"))); - AddPrivilege(Privilege("AUTOOWNER", _("Automatic mode +q"))); - AddPrivilege(Privilege("OPDEOPME", _("Allowed to (de)op him/herself"))); - AddPrivilege(Privilege("OPDEOP", _("Allowed to (de)op users"))); - AddPrivilege(Privilege("AUTOPROTECT", _("Automatic mode +a"))); - AddPrivilege(Privilege("AKICK", _("Allowed to use AKICK command"))); - AddPrivilege(Privilege("BADWORDS", _("Allowed to modify channel badwords list"))); - AddPrivilege(Privilege("ASSIGN", _("Allowed to assign/unassign a bot"))); - AddPrivilege(Privilege("MEMO", _("Allowed to read channel memos"))); - AddPrivilege(Privilege("ACCESS_CHANGE", _("Allowed to modify the access list"))); - AddPrivilege(Privilege("PROTECT", _("Allowed to (de)protect users"))); - AddPrivilege(Privilege("PROTECTME", _("Allowed to (de)protect him/herself"))); - AddPrivilege(Privilege("SET", _("Allowed to set channel settings"))); - AddPrivilege(Privilege("OWNERME", _("Allowed to (de)owner him/herself"))); - AddPrivilege(Privilege("OWNER", _("Allowed to (de)owner users"))); + return privs; } -std::vector<Privilege> &PrivilegeManager::GetPrivileges() +void PrivilegeManager::ClearPrivileges() { - return privs; + privs.clear(); } AccessProvider::AccessProvider(Module *o, const Anope::string &n) : Service<AccessProvider>(o, n) diff --git a/src/config.cpp b/src/config.cpp index 28a0b6a9c..5cb067735 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -872,6 +872,35 @@ static bool DoneCommands(ServerConfig *config, const Anope::string &) return true; } +static bool InitPrivileges(ServerConfig *config, const Anope::string &) +{ + PrivilegeManager::ClearPrivileges(); + return true; +} + +static bool DoPrivileges(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *) +{ + Anope::string name = values[0].GetValue(); + Anope::string desc = values[1].GetValue(); + + ValueItem vi(name); + if (!ValidateNotEmpty(config, "privilege", "name", vi)) + throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information."); + + vi = ValueItem(desc); + if (!ValidateNotEmpty(config, "privilege", "desc", vi)) + throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information."); + + PrivilegeManager::AddPrivilege(Privilege(name, desc)); + return true; +} + +static bool DonePrivileges(ServerConfig *config, const Anope::string &) +{ + Log(LOG_DEBUG) << "Loaded " << PrivilegeManager::GetPrivileges().size() << " privileges"; + return true; +} + /*************************************************************************/ static std::set<Anope::string> services; @@ -1283,6 +1312,11 @@ ConfigItems::ConfigItems(ServerConfig *conf) {"", "", "", "", ""}, {DT_STRING, DT_STRING, DT_STRING, DT_STRING}, InitCommands, DoCommands, DoneCommands}, + {"privilege", + {"name", "desc", ""}, + {"", "", ""}, + {DT_STRING, DT_STRING, DT_STRING}, + InitPrivileges, DoPrivileges, DonePrivileges}, {"", {""}, {""}, diff --git a/src/init.cpp b/src/init.cpp index 76ba350bb..4cff3fc91 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -355,7 +355,6 @@ void Init(int ac, char **av) /* Initialize the socket engine */ SocketEngine::Init(); - PrivilegeManager::Init(); /* Create me */ Me = new Server(NULL, Config->ServerName, 0, Config->ServerDesc, Config->Numeric); |