diff options
| author | Adam <Adam@anope.org> | 2011-03-14 13:52:26 -0400 |
|---|---|---|
| committer | Adam <Adam@anope.org> | 2011-03-14 13:52:26 -0400 |
| commit | ed73d7675152ccc66f20daedca8586a8de254a84 (patch) | |
| tree | 18f7a1a53a717f24d061550c6670ca6f0ed54f9f | |
| parent | 4fe49af8401b956249d924b89b3e69bce5fb6744 (diff) | |
Rewrote some of the opertype system, added os_login
65 files changed, 393 insertions, 201 deletions
diff --git a/data/example.conf b/data/example.conf index 28ca69dc7..ee624022e 100644 --- a/data/example.conf +++ b/data/example.conf @@ -799,6 +799,12 @@ oper /* The opertype this person will have */ type = "Services Root" + + /* An optional password. If defined the user must login using /operserv login first */ + #password = "secret" + + /* An optional SSL fingerprint. If defined is required to use this opertype. */ + #certfp = "ed3383b3f7d74e89433ddaa4a6e5b2d7" } oper @@ -1493,7 +1499,7 @@ operserv * * This directive is optional, but highly recommended. */ - modules = "os_help os_global os_stats os_staff os_mode os_kick os_akill os_snline os_sqline os_szline os_chanlist os_userlist os_news os_session os_noop os_jupe os_ignore os_set os_reload os_update os_restart os_quit os_shutdown os_defcon os_chankill os_svsnick os_oline os_modload os_modunload os_modreload os_modlist os_modinfo os_config" + modules = "os_help os_global os_stats os_staff os_mode os_kick os_akill os_snline os_sqline os_szline os_chanlist os_userlist os_news os_session os_noop os_jupe os_ignore os_set os_reload os_update os_restart os_quit os_shutdown os_defcon os_chankill os_svsnick os_oline os_modload os_modunload os_modreload os_modlist os_modinfo os_config os_login" /* * If set, Services Admins will be able to use SUPERADMIN [ON|OFF] which will temporarily grant diff --git a/docs/Changes b/docs/Changes index 9d9b8be36..cde85bbd0 100644 --- a/docs/Changes +++ b/docs/Changes @@ -14,6 +14,8 @@ A Added m_alias A Added support for XMLRPC queries A Added /botserv set msg A Added /operserv config +A Added /ns cert +A Added /operserv login F Changed the GHOST command to not allow ghosting unidentified users if the RECOVER command exists F Some failed logic in /operserv exception that prevents proper exceptions from being added F Fixed the anope_os_sxlines MySQL table and code to work after restarting diff --git a/docs/Changes.conf b/docs/Changes.conf index eaf99cdd4..b07b99ce1 100644 --- a/docs/Changes.conf +++ b/docs/Changes.conf @@ -6,11 +6,11 @@ chanserv:modules added cs_clone and cs_mode nickserv:suspendexpire and nickserv:forbidexpire added chanserv:suspendexpire and chanserv:forbidexpire added module added cs_entrymsg -nickserv:modules added ns_ajoin +nickserv:modules added ns_ajoin, ns_cert options:nomlock added log:target added globops nickserv:confirmemailchanges added -operserv:modules added os_config +operserv:modules added os_config, os_login ** MODIFIED CONFIGURATION DIRECTIVES ** operserv:notifications removed osglobal, osmode, oskick, osakill, ossnline, ossqline, osszline, osnoop, osjupe, getpass, setpass, forbid, drop diff --git a/include/account.h b/include/account.h index 635606f62..01ec082dd 100644 --- a/include/account.h +++ b/include/account.h @@ -156,29 +156,17 @@ class CoreExport NickCore : public Extensible, public Flags<NickCoreFlag, NI_END MemoInfo memos; uint16 channelcount; /* Number of channels currently registered */ - OperType *ot; + Oper *o; /* Unsaved data */ time_t lastmail; /* Last time this nick record got a mail */ std::list<NickAlias *> aliases; /* List of aliases */ - /** Check whether this opertype has access to run the given command string. - * @param cmdstr The string to check, e.g. botserv/set/private. - * @return True if this opertype may run the specified command, false otherwise. - */ - virtual bool HasCommand(const Anope::string &cmdstr) const; - /** Checks whether this account is a services oper or not. * @return True if this account is a services oper, false otherwise. */ virtual bool IsServicesOper() const; - /** Check whether this opertype has access to the given special permission. - * @param privstr The priv to check for, e.g. users/auspex. - * @return True if this opertype has the specified priv, false otherwise. - */ - virtual bool HasPriv(const Anope::string &privstr) const; - /** Add an entry to the nick's access list * * @param entry The nick!ident@host entry to add to the access list diff --git a/include/config.h b/include/config.h index 4a8d8411f..aee6f44e5 100644 --- a/include/config.h +++ b/include/config.h @@ -757,7 +757,7 @@ class CoreExport ServerConfig /* List of available opertypes */ std::list<OperType *> MyOperTypes; /* List of pairs of opers and their opertype from the config */ - std::list<std::pair<Anope::string, Anope::string> > Opers; + std::vector<Oper *> Opers; }; /** This class can be used on its own to represent an exception, or derived to represent a module-specific exception. diff --git a/include/opertype.h b/include/opertype.h index 6f48b7831..bf76d71eb 100644 --- a/include/opertype.h +++ b/include/opertype.h @@ -10,6 +10,25 @@ #include "hashcomp.h" +class OperType; + +struct Oper +{ + Anope::string name; + Anope::string password; + Anope::string certfp; + OperType *ot; + + Oper(const Anope::string &n, const Anope::string &p, const Anope::string &c, OperType *o) : + name(n), password(p), certfp(c), ot(o) { } + + /** Find an oper block by name + * @param name The name + * @return the oper block + */ + static Oper *Find(const Anope::string &name); +}; + class CoreExport OperType { private: @@ -36,6 +55,12 @@ class CoreExport OperType */ std::set<OperType *> inheritances; public: + /** Find an oper type by name + * @param name The name + * @return The oper type + */ + static OperType *Find(const Anope::string &name); + /** Create a new opertype of the given name. * @param nname The opertype name, e.g. "sra". */ diff --git a/include/users.h b/include/users.h index 30f5c8275..9f6e250e5 100644 --- a/include/users.h +++ b/include/users.h @@ -197,6 +197,23 @@ class CoreExport User : public Extensible */ virtual bool IsRecognized(bool CheckSecure = false); + /** Check if the user is a services oper + * @return true if they are an oper + */ + bool IsServicesOper(); + + /** Check whether this user has access to run the given command string. + * @param cmdstr The string to check, e.g. botserv/set/private. + * @return True if this user may run the specified command, false otherwise. + */ + bool HasCommand(const Anope::string &cmdstr); + + /** Check whether this user has access to the given special permission. + * @param privstr The priv to check for, e.g. users/auspex. + * @return True if this user has the specified priv, false otherwise. + */ + bool HasPriv(const Anope::string &privstr); + /** Update the last usermask stored for a user, and check to see if they are recognized */ void UpdateHost(); diff --git a/modules/core/bs_assign.cpp b/modules/core/bs_assign.cpp index d86a07c23..f1000cb11 100644 --- a/modules/core/bs_assign.cpp +++ b/modules/core/bs_assign.cpp @@ -41,13 +41,13 @@ class CommandBSAssign : public Command return MOD_CONT; } - if (ci->botflags.HasFlag(BS_NOBOT) || (!check_access(u, ci, CA_ASSIGN) && !u->Account()->HasPriv("botserv/administration"))) + if (ci->botflags.HasFlag(BS_NOBOT) || (!check_access(u, ci, CA_ASSIGN) && !u->HasPriv("botserv/administration"))) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; } - if (bi->HasFlag(BI_PRIVATE) && !u->Account()->HasCommand("botserv/assign/private")) + if (bi->HasFlag(BI_PRIVATE) && !u->HasCommand("botserv/assign/private")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; diff --git a/modules/core/bs_badwords.cpp b/modules/core/bs_badwords.cpp index 7de30afe2..5117055a3 100644 --- a/modules/core/bs_badwords.cpp +++ b/modules/core/bs_badwords.cpp @@ -58,7 +58,7 @@ class BadwordsDelCallback : public NumberList public: BadwordsDelCallback(CommandSource &_source, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), c(_c), Deleted(0), override(false) { - if (!check_access(source.u, source.ci, CA_BADWORDS) && source.u->Account()->HasPriv("botserv/administration")) + if (!check_access(source.u, source.ci, CA_BADWORDS) && source.u->HasPriv("botserv/administration")) this->override = true; } @@ -245,7 +245,7 @@ class CommandBSBadwords : public Command return MOD_CONT; } - if (!check_access(u, ci, CA_BADWORDS) && (!need_args || !u->Account()->HasPriv("botserv/administration"))) + if (!check_access(u, ci, CA_BADWORDS) && (!need_args || !u->HasPriv("botserv/administration"))) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; diff --git a/modules/core/bs_bot.cpp b/modules/core/bs_bot.cpp index 50812d0d0..d35d90ec1 100644 --- a/modules/core/bs_bot.cpp +++ b/modules/core/bs_bot.cpp @@ -321,7 +321,7 @@ class CommandBSBot : public Command if (cmd.equals_ci("ADD")) { // ADD nick user host real - 5 - if (!u->Account()->HasCommand("botserv/bot/add")) + if (!u->HasCommand("botserv/bot/add")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; @@ -344,7 +344,7 @@ class CommandBSBot : public Command { // CHANGE oldn newn user host real - 6 // but only oldn and newn are required - if (!u->Account()->HasCommand("botserv/bot/change")) + if (!u->HasCommand("botserv/bot/change")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; @@ -361,7 +361,7 @@ class CommandBSBot : public Command else if (cmd.equals_ci("DEL")) { // DEL nick - if (!u->Account()->HasCommand("botserv/bot/del")) + if (!u->HasCommand("botserv/bot/del")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; diff --git a/modules/core/bs_botlist.cpp b/modules/core/bs_botlist.cpp index b9c1f9287..bd2413b36 100644 --- a/modules/core/bs_botlist.cpp +++ b/modules/core/bs_botlist.cpp @@ -39,7 +39,7 @@ class CommandBSBotList : public Command } } - if (u->Account()->HasCommand("botserv/botlist") && count < BotListByNick.size()) + if (u->HasCommand("botserv/botlist") && count < BotListByNick.size()) { source.Reply(_("Bots reserved to IRC operators:")); diff --git a/modules/core/bs_help.cpp b/modules/core/bs_help.cpp index 7c0d2da70..f8fc414b5 100644 --- a/modules/core/bs_help.cpp +++ b/modules/core/bs_help.cpp @@ -41,7 +41,7 @@ class CommandBSHelp : public Command "%s HELP \037command\037\002."), BotServ->nick.c_str(), BotServ->nick.c_str(), BotServ->nick.c_str()); for (CommandMap::const_iterator it = BotServ->Commands.begin(), it_end = BotServ->Commands.end(); it != it_end; ++it) - if (!Config->HidePrivilegedCommands || it->second->permission.empty() || (u->Account() && u->Account()->HasCommand(it->second->permission))) + if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission)) it->second->OnServHelp(source); source.Reply(_("Bot will join a channel whenever there is at least\n" "\002%d\002 user(s) on it. Additionally, all %s commands\n" diff --git a/modules/core/bs_info.cpp b/modules/core/bs_info.cpp index 828a1bf2d..a5853f611 100644 --- a/modules/core/bs_info.cpp +++ b/modules/core/bs_info.cpp @@ -65,12 +65,12 @@ class CommandBSInfo : public Command source.Reply(_(" Options : %s"), bi->HasFlag(BI_PRIVATE) ? _("Private") : _("None")); source.Reply(_(" Used on : %d channel(s)"), bi->chancount); - if (u->Account()->HasPriv("botserv/administration")) + if (u->HasPriv("botserv/administration")) this->send_bot_channels(source, bi); } else if ((ci = cs_findchan(query))) { - if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("botserv/administration")) + if (!check_access(u, ci, CA_FOUNDER) && !u->HasPriv("botserv/administration")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; diff --git a/modules/core/bs_kick.cpp b/modules/core/bs_kick.cpp index 7ca21f9ce..316b50be6 100644 --- a/modules/core/bs_kick.cpp +++ b/modules/core/bs_kick.cpp @@ -38,7 +38,7 @@ class CommandBSKick : public Command SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]")); else if (!value.equals_ci("ON") && !value.equals_ci("OFF")) SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]")); - else if (!check_access(u, ci, CA_SET) && !u->Account()->HasPriv("botserv/administration")) + else if (!check_access(u, ci, CA_SET) && !u->HasPriv("botserv/administration")) source.Reply(_(ACCESS_DENIED)); else if (!ci->bi) source.Reply(_(BOT_NOT_ASSIGNED)); diff --git a/modules/core/bs_set.cpp b/modules/core/bs_set.cpp index b149857d0..96a8c2b83 100644 --- a/modules/core/bs_set.cpp +++ b/modules/core/bs_set.cpp @@ -33,7 +33,7 @@ class CommandBSSet : public Command if (readonly) source.Reply(_("Sorry, bot option setting is temporarily disabled.")); - else if (u->Account()->HasCommand("botserv/set/private") && option.equals_ci("PRIVATE")) + else if (u->HasCommand("botserv/set/private") && option.equals_ci("PRIVATE")) { BotInfo *bi; @@ -59,7 +59,7 @@ class CommandBSSet : public Command } else if (!(ci = cs_findchan(chan))) source.Reply(_(CHAN_X_NOT_REGISTERED), chan.c_str()); - else if (!u->Account()->HasPriv("botserv/administration") && !check_access(u, ci, CA_SET)) + else if (!u->HasPriv("botserv/administration") && !check_access(u, ci, CA_SET)) source.Reply(_(ACCESS_DENIED)); else { @@ -126,7 +126,7 @@ class CommandBSSet : public Command else SyntaxError(source, "SET GREET", _("SET \037channel\037 GREET {\037ON|\037}")); } - else if (u->Account()->HasCommand("botserv/set/nobot") && option.equals_ci("NOBOT")) + else if (u->HasCommand("botserv/set/nobot") && option.equals_ci("NOBOT")) { if (value.equals_ci("ON")) { @@ -218,7 +218,7 @@ class CommandBSSet : public Command "Note: access to this command is controlled by the\n" "level SET."), BotServ->nick.c_str()); User *u = source.u; - if (u->Account() && u->Account()->IsServicesOper()) + if (u->IsServicesOper()) source.Reply(_("These options are reserved to Services Operators:\n" " \n" " NOBOT Prevent a bot from being assigned to \n" diff --git a/modules/core/bs_unassign.cpp b/modules/core/bs_unassign.cpp index 884939f84..f64cb526d 100644 --- a/modules/core/bs_unassign.cpp +++ b/modules/core/bs_unassign.cpp @@ -30,7 +30,7 @@ class CommandBSUnassign : public Command if (readonly) source.Reply(_(BOT_ASSIGN_READONLY)); - else if (!u->Account()->HasPriv("botserv/administration") && !check_access(u, ci, CA_ASSIGN)) + else if (!u->HasPriv("botserv/administration") && !check_access(u, ci, CA_ASSIGN)) source.Reply(_(ACCESS_DENIED)); else if (!ci->bi) source.Reply(_(BOT_NOT_ASSIGNED)); diff --git a/modules/core/cs_access.cpp b/modules/core/cs_access.cpp index d65f0b718..e2e2a946e 100644 --- a/modules/core/cs_access.cpp +++ b/modules/core/cs_access.cpp @@ -110,7 +110,7 @@ class AccessDelCallback : public NumberList public: AccessDelCallback(CommandSource &_source, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), source(_source), c(_c), Deleted(0), Denied(false) { - if (!check_access(source.u, source.ci, CA_ACCESS_CHANGE) && source.u->Account()->HasPriv("chanserv/access/modify")) + if (!check_access(source.u, source.ci, CA_ACCESS_CHANGE) && source.u->HasPriv("chanserv/access/modify")) this->override = true; } @@ -143,7 +143,7 @@ class AccessDelCallback : public NumberList ChanAccess *u_access = ci->GetAccess(u); int16 u_level = u_access ? u_access->level : 0; - if (u_level <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) + if (u_level <= access->level && !u->HasPriv("chanserv/access/modify")) { Denied = true; return; @@ -179,7 +179,7 @@ class CommandCSAccess : public Command ChanAccess *u_access = ci->GetAccess(u); int16 u_level = u_access ? u_access->level : 0; - if (level >= u_level && !u->Account()->HasPriv("chanserv/access/modify")) + if (level >= u_level && !u->HasPriv("chanserv/access/modify")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; @@ -211,7 +211,7 @@ class CommandCSAccess : public Command if (access) { /* Don't allow lowering from a level >= u_level */ - if (access->level >= u_level && !u->Account()->HasPriv("chanserv/access/modify")) + if (access->level >= u_level && !u->HasPriv("chanserv/access/modify")) { source.Reply(_(ACCESS_DENIED)); return MOD_CONT; @@ -267,7 +267,7 @@ class CommandCSAccess : public Command int16 u_level = u_access ? u_access->level : 0; if (!access) source.Reply(_("\002%s\002 not found on %s access list."), mask.c_str(), ci->name.c_str()); - else if (access->nc != u->Account() && check_access(u, ci, CA_NOJOIN) && u_level <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) + else if (access->nc != u->Account() && check_access(u, ci, CA_NOJOIN) && u_level <= access->level && !u->HasPriv("chanserv/access/modify")) source.Reply(_(ACCESS_DENIED)); else { @@ -373,7 +373,7 @@ class CommandCSAccess : public Command User *u = source.u; ChannelInfo *ci = source.ci; - if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify")) + if (!IsFounder(u, ci) && !u->HasPriv("chanserv/access/modify")) source.Reply(_(ACCESS_DENIED)); else { @@ -688,7 +688,7 @@ class CommandCSLevels : public Command this->OnSyntaxError(source, cmd); else if (ci->HasFlag(CI_XOP)) source.Reply(_("Levels are not available as xOP is enabled on this channel.")); - else if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("chanserv/access/modify")) + else if (!check_access(u, ci, CA_FOUNDER) && !u->HasPriv("chanserv/access/modify")) source.Reply(_(ACCESS_DENIED)); else if (cmd.equals_ci("SET")) this->DoSet(source, params); diff --git a/modules/core/cs_akick.cpp b/modules/core/cs_akick.cpp index 920dfc6f7..bad0e6d22 100644 --- a/modules/core/cs_akick.cpp +++ b/modules/core/cs_aki |
