summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2011-03-14 13:52:26 -0400
committerAdam <Adam@anope.org>2011-03-14 13:52:26 -0400
commited73d7675152ccc66f20daedca8586a8de254a84 (patch)
tree18f7a1a53a717f24d061550c6670ca6f0ed54f9f
parent4fe49af8401b956249d924b89b3e69bce5fb6744 (diff)
Rewrote some of the opertype system, added os_login
-rw-r--r--data/example.conf8
-rw-r--r--docs/Changes2
-rw-r--r--docs/Changes.conf4
-rw-r--r--include/account.h14
-rw-r--r--include/config.h2
-rw-r--r--include/opertype.h25
-rw-r--r--include/users.h17
-rw-r--r--modules/core/bs_assign.cpp4
-rw-r--r--modules/core/bs_badwords.cpp4
-rw-r--r--modules/core/bs_bot.cpp6
-rw-r--r--modules/core/bs_botlist.cpp2
-rw-r--r--modules/core/bs_help.cpp2
-rw-r--r--modules/core/bs_info.cpp4
-rw-r--r--modules/core/bs_kick.cpp2
-rw-r--r--modules/core/bs_set.cpp8
-rw-r--r--modules/core/bs_unassign.cpp2
-rw-r--r--modules/core/cs_access.cpp14
-rw-r--r--modules/core/cs_akick.cpp2
-rw-r--r--modules/core/cs_clone.cpp2
-rw-r--r--modules/core/cs_drop.cpp8
-rw-r--r--modules/core/cs_getkey.cpp2
-rw-r--r--modules/core/cs_help.cpp4
-rw-r--r--modules/core/cs_info.cpp2
-rw-r--r--modules/core/cs_list.cpp2
-rw-r--r--modules/core/cs_mode.cpp2
-rw-r--r--modules/core/cs_register.cpp2
-rw-r--r--modules/core/cs_set_founder.cpp2
-rw-r--r--modules/core/cs_topic.cpp2
-rw-r--r--modules/core/cs_xop.cpp12
-rw-r--r--modules/core/hs_help.cpp2
-rw-r--r--modules/core/ms_help.cpp2
-rw-r--r--modules/core/ms_info.cpp8
-rw-r--r--modules/core/ms_rsend.cpp2
-rw-r--r--modules/core/ms_set.cpp4
-rw-r--r--modules/core/ns_access.cpp2
-rw-r--r--modules/core/ns_alist.cpp4
-rw-r--r--modules/core/ns_cert.cpp2
-rw-r--r--modules/core/ns_drop.cpp4
-rw-r--r--modules/core/ns_group.cpp12
-rw-r--r--modules/core/ns_help.cpp4
-rw-r--r--modules/core/ns_info.cpp4
-rw-r--r--modules/core/ns_list.cpp6
-rw-r--r--modules/core/ns_logout.cpp6
-rw-r--r--modules/core/ns_register.cpp12
-rw-r--r--modules/core/ns_resetpass.cpp2
-rw-r--r--modules/core/ns_sendpass.cpp2
-rw-r--r--modules/core/ns_set_email.cpp2
-rw-r--r--modules/core/os_help.cpp2
-rw-r--r--modules/core/os_login.cpp82
-rw-r--r--modules/core/os_staff.cpp12
-rw-r--r--modules/extra/cs_entrymsg.cpp2
-rw-r--r--modules/extra/db_mysql.cpp10
-rw-r--r--modules/extra/hs_request.cpp11
-rw-r--r--modules/extra/m_async_commands.cpp2
-rw-r--r--modules/extra/m_ldap_oper.cpp45
-rw-r--r--modules/extra/m_xmlrpc_main.cpp4
-rw-r--r--src/commands.cpp6
-rw-r--r--src/config.cpp44
-rw-r--r--src/memoserv.cpp4
-rw-r--r--src/messages.cpp12
-rw-r--r--src/nickalias.cpp22
-rw-r--r--src/nickcore.cpp25
-rw-r--r--src/nickserv.cpp2
-rw-r--r--src/opertype.cpp27
-rw-r--r--src/users.cpp40
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_akick.cpp
@@ -488,7 +488,7 @@ class CommandCSAKick : public Command
if (mask.empty() && (cmd.equals_ci("ADD") || cmd.equals_ci("DEL")))
this->OnSyntaxError(source, cmd);
- else if (!check_access(u, ci, CA_AKICK) && !u->Account()->HasPriv("chanserv/access/modify"))
+ else if (!check_access(u, ci, CA_AKICK) && !u->HasPriv("chanserv/access/modify"))
source.Reply(_(ACCESS_DENIED));
else if (!cmd.equals_ci("LIST") && !cmd.equals_ci("VIEW") && !cmd.equals_ci("ENFORCE") && readonly)
source.Reply(_("Sorry, channel autokick list modification is temporarily disabled."));
diff --git a/modules/core/cs_clone.cpp b/modules/core/cs_clone.cpp
index f816eb2f5..5b264c8df 100644
--- a/modules/core/cs_clone.cpp
+++ b/modules/core/cs_clone.cpp
@@ -47,7 +47,7 @@ public:
return MOD_CONT;
}
- if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit"))
+ if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit"))
{
source.Reply(u->Account()->channelcount > Config->CSMaxReg ? _(CHAN_EXCEEDED_CHANNEL_LIMIT) : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg);
return MOD_CONT;
diff --git a/modules/core/cs_drop.cpp b/modules/core/cs_drop.cpp
index 44e58693e..248cfa37e 100644
--- a/modules/core/cs_drop.cpp
+++ b/modules/core/cs_drop.cpp
@@ -38,19 +38,19 @@ class CommandCSDrop : public Command
ci = cs_findchan(chan);
- if (ci->HasFlag(CI_FORBIDDEN) && !u->Account()->HasCommand("chanserv/drop"))
+ if (ci->HasFlag(CI_FORBIDDEN) && !u->HasCommand("chanserv/drop"))
{
source.Reply(_(CHAN_X_FORBIDDEN), chan.c_str());
return MOD_CONT;
}
- if (ci->HasFlag(CI_SUSPENDED) && !u->Account()->HasCommand("chanserv/drop"))
+ if (ci->HasFlag(CI_SUSPENDED) && !u->HasCommand("chanserv/drop"))
{
source.Reply(_(CHAN_X_FORBIDDEN), chan.c_str());
return MOD_CONT;
}
- if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) && !u->Account()->HasCommand("chanserv/drop"))
+ if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) && !u->HasCommand("chanserv/drop"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
@@ -82,7 +82,7 @@ class CommandCSDrop : public Command
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
User *u = source.u;
- if (u->Account() && u->Account()->IsServicesOper())
+ if (u->IsServicesOper())
source.Reply(_("Syntax: \002DROP \037channel\037\002\n"
" \n"
"Unregisters the named channel. Only \002Services Operators\002\n"
diff --git a/modules/core/cs_getkey.cpp b/modules/core/cs_getkey.cpp
index e9b685a34..da71e690e 100644
--- a/modules/core/cs_getkey.cpp
+++ b/modules/core/cs_getkey.cpp
@@ -28,7 +28,7 @@ class CommandCSGetKey : public Command
User *u = source.u;
ChannelInfo *ci = source.ci;
- if (!check_access(u, ci, CA_GETKEY) && !u->Account()->HasCommand("chanserv/getkey"))
+ if (!check_access(u, ci, CA_GETKEY) && !u->HasCommand("chanserv/getkey"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
diff --git a/modules/core/cs_help.cpp b/modules/core/cs_help.cpp
index db34fc8ea..67b2354f9 100644
--- a/modules/core/cs_help.cpp
+++ b/modules/core/cs_help.cpp
@@ -42,13 +42,13 @@ class CommandCSHelp : public Command
ChanServ->nick.c_str(), ChanServ->nick.c_str(), ChanServ->nick.c_str(),
ChanServ->nick.c_str());
for (CommandMap::const_iterator it = ChanServ->Commands.begin(); it != ChanServ->Commands.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);
if (Config->CSExpire >= 86400)
source.Reply(_("Note that any channel which is not used for %d days\n"
"(i.e. which no user on the channel's access list enters\n"
"for that period of time) will be automatically dropped."), Config->CSExpire / 86400);
- if (u->Account() && u->Account()->IsServicesOper())
+ if (u->IsServicesOper())
source.Reply(_(" \n"
"Services Operators can also drop any channel without needing\n"
"to identify via password, and may view the access, AKICK,\n"
diff --git a/modules/core/cs_info.cpp b/modules/core/cs_info.cpp
index a0b07d759..48baa67ae 100644
--- a/modules/core/cs_info.cpp
+++ b/modules/core/cs_info.cpp
@@ -42,7 +42,7 @@ class CommandCSInfo : public Command
User *u = source.u;
ChannelInfo *ci = source.ci;
- bool has_auspex = u->IsIdentified() && u->Account()->HasPriv("chanserv/auspex");
+ bool has_auspex = u->IsIdentified() && u->HasPriv("chanserv/auspex");
bool show_all = false;
if (ci->HasFlag(CI_FORBIDDEN))
diff --git a/modules/core/cs_list.cpp b/modules/core/cs_list.cpp
index 32894242b..8e3d75e5f 100644
--- a/modules/core/cs_list.cpp
+++ b/modules/core/cs_list.cpp
@@ -30,7 +30,7 @@ class CommandCSList : public Command
Anope::string pattern = params[0];
unsigned nchans;
char buf[BUFSIZE];
- bool is_servadmin = u->Account()->HasCommand("chanserv/list");
+ bool is_servadmin = u->HasCommand("chanserv/list");
int count = 0, from = 0, to = 0;
bool forbidden = false, suspended = false, channoexpire = false;
diff --git a/modules/core/cs_mode.cpp b/modules/core/cs_mode.cpp
index 209ee751f..55da9762c 100644
--- a/modules/core/cs_mode.cpp
+++ b/modules/core/cs_mode.cpp
@@ -314,7 +314,7 @@ class CommandCSMode : public Command
if (!ci || !ci->c)
source.Reply(_(CHAN_X_NOT_IN_USE), ci->name.c_str());
- else if (!check_access(u, ci, CA_MODE) && !u->Account()->HasCommand("chanserv/mode"))
+ else if (!check_access(u, ci, CA_MODE) && !u->HasCommand("chanserv/mode"))
source.Reply(_(ACCESS_DENIED));
else if (subcommand.equals_ci("LOCK"))
this->DoLock(source, params);
diff --git a/modules/core/cs_register.cpp b/modules/core/cs_register.cpp
index 995c0e65b..13aa17d35 100644
--- a/modules/core/cs_register.cpp
+++ b/modules/core/cs_register.cpp
@@ -45,7 +45,7 @@ class CommandCSRegister : public Command
source.Reply(_("Channel \002%s\002 is already registered!"), chan.c_str());
else if (c && !c->HasUserStatus(u, CMODE_OP))
source.Reply(_("You must be a channel operator to register the channel."));
- else if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit"))
+ else if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit"))
source.Reply(u->Account()->channelcount > Config->CSMaxReg ? _(CHAN_EXCEEDED_CHANNEL_LIMIT) : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg);
else
{
diff --git a/modules/core/cs_set_founder.cpp b/modules/core/cs_set_founder.cpp
index b6f7dab95..200d32e95 100644
--- a/modules/core/cs_set_founder.cpp
+++ b/modules/core/cs_set_founder.cpp
@@ -49,7 +49,7 @@ class CommandCSSetFounder : public Command
}
nc = na->nc;
- if (Config->CSMaxReg && nc->channelcount >= Config->CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit"))
+ if (Config->CSMaxReg && nc->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit"))
{
source.Reply(_("\002%s\002 has too many channels registered."), na->nick.c_str());
return MOD_CONT;
diff --git a/modules/core/cs_topic.cpp b/modules/core/cs_topic.cpp
index 9798a12c0..8fd23f7f1 100644
--- a/modules/core/cs_topic.cpp
+++ b/modules/core/cs_topic.cpp
@@ -31,7 +31,7 @@ class CommandCSTopic : public Command
if (!c)
source.Reply(_(CHAN_X_NOT_IN_USE), ci->name.c_str());
- else if (!check_access(u, ci, CA_TOPIC) && !u->Account()->HasCommand("chanserv/topic"))
+ else if (!check_access(u, ci, CA_TOPIC) && !u->HasCommand("chanserv/topic"))
source.Reply(_(ACCESS_DENIED));
else
{
diff --git a/modules/core/cs_xop.cpp b/modules/core/cs_xop.cpp
index b556e210e..38c82d183 100644
--- a/modules/core/cs_xop.cpp
+++ b/modules/core/cs_xop.cpp
@@ -131,7 +131,7 @@ class XOPBase : public Command
ChanAccess *access = ci->GetAccess(u);
uint16 ulev = access ? access->level : 0;
- if ((level >= ulev || ulev < ACCESS_AOP) && !u->Account()->HasPriv("chanserv/access/modify"))
+ if ((level >= ulev || ulev < ACCESS_AOP) && !u->HasPriv("chanserv/access/modify"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
@@ -152,7 +152,7 @@ class XOPBase : public Command
/**
* Patch provided by PopCorn to prevert AOP's reducing SOP's levels
**/
- if (access->level >= ulev && !u->Account()->HasPriv("chanserv/access/modify"))
+ if (access->level >= ulev && !u->HasPriv("chanserv/access/modify"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
@@ -220,7 +220,7 @@ class XOPBase : public Command
ChanAccess *access = ci->GetAccess(u);
uint16 ulev = access ? access->level : 0;
- if ((!access || access->nc != u->Account()) && (level >= ulev || ulev < ACCESS_AOP) && !u->Account()->HasPriv("chanserv/access/modify"))
+ if ((!access || access->nc != u->Account()) && (level >= ulev || ulev < ACCESS_AOP) && !u->HasPriv("chanserv/access/modify"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
@@ -242,7 +242,7 @@ class XOPBase : public Command
}
else
{
- if (access->nc != u->Account() && ulev <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
+ if (access->nc != u->Account() && ulev <= access->level && !u->HasPriv("chanserv/access/modify"))
source.Reply(_(ACCESS_DENIED));
else
{
@@ -270,7 +270,7 @@ class XOPBase : public Command
ChanAccess *access = ci->GetAccess(u);
uint16 ulev = access ? access->level : 0;
- if (!ulev && !u->Account()->HasCommand("chanserv/access/list"))
+ if (!ulev && !u->HasCommand("chanserv/access/list"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
@@ -336,7 +336,7 @@ class XOPBase : public Command
return MOD_CONT;
}
- if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("chanserv/access/modify"))
+ if (!check_access(u, ci, CA_FOUNDER) && !u->HasPriv("chanserv/access/modify"))
{
source.Reply(_(ACCESS_DENIED));
return MOD_CONT;
diff --git a/modules/core/hs_help.cpp b/modules/core/hs_help.cpp
index 35d2b99cb..c360376c7 100644
--- a/modules/core/hs_help.cpp
+++ b/modules/core/hs_help.cpp
@@ -32,7 +32,7 @@ class CommandHSHelp : public Command
User *u = source.u;
source.Reply(_("%s commands"), Config->s_HostServ.c_str());
for (CommandMap::const_iterator it = HostServ->Commands.begin(), it_end = HostServ->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);
}
};
diff --git a/modules/core/ms_help.cpp b/modules/core/ms_help.cpp
index c27f1791b..54210e4fe 100644
--- a/modules/core/ms_help.cpp
+++ b/modules/core/ms_help.cpp
@@ -37,7 +37,7 @@ class CommandMSHelp : public Command
"registered in order to send a memo.\n"
"%s's commands include:"), MemoServ->nick.c_str(), MemoServ->nick.c_str());
for (CommandMap::const_iterator it = MemoServ->Commands.begin(), it_end = MemoServ->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(_("Type \002%R%s HELP \037command\037\002 for help on any of the\n"
"above commands.\n"
diff --git a/modules/core/ms_info.cpp b/modules/core/ms_info.cpp
index af0dddd21..f87b8af60 100644
--- a/modules/core/ms_info.cpp
+++ b/modules/core/ms_info.cpp
@@ -31,7 +31,7 @@ class CommandMSInfo : public Command
const Anope::string &nname = !params.empty() ? params[0] : "";
int hardmax = 0;
- if (!nname.empty() && nname[0] != '#' && u->Account()->HasPriv("memoserv/info"))
+ if (!nname.empty() && nname[0] != '#' && u->HasPriv("memoserv/info"))
{
na = findnick(nname);
if (!na)
@@ -159,14 +159,14 @@ class CommandMSInfo : public Command
if (!mi->memomax)
{
- if (!u->Account()->IsServicesOper() && hardmax)
+ if (!u->IsServicesOper() && hardmax)
source.Reply(_("Your memo limit is \0020\002; you will not receive any new memos. You cannot change this limit."));
else
source.Reply(_("Your memo limit is \0020\002; you will not receive any new memos."));
}
else if (mi->memomax > 0)
{
- if (!u->Account()->IsServicesOper() && hardmax)
+ if (!u->IsServicesOper() && hardmax)
source.Reply(_("Your memo limit is \002%d\002, and may not be changed."), mi->memomax);
else
source.Reply(_("Your memo limit is \002%d\002."), mi->memomax);
@@ -190,7 +190,7 @@ class CommandMSInfo : public Command
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
User *u = source.u;
- if (u->Account() && u->Account()->IsServicesOper())
+ if (u->IsServicesOper())
source.Reply(_("Syntax: \002INFO [\037nick\037 | \037channel\037]\002\n"
"Without a parameter, displays information on the number of\n"
"memos you have, how many of them are unread, and how many\n"
diff --git a/modules/core/ms_rsend.cpp b/modules/core/ms_rsend.cpp
index 98d7aaba4..7e6af4950 100644
--- a/modules/core/ms_rsend.cpp
+++ b/modules/core/ms_rsend.cpp
@@ -39,7 +39,7 @@ class CommandMSRSend : public Command
if (Config->MSMemoReceipt == 1)
{
/* Services opers and above can use rsend */
- if (u->Account()->IsServicesOper())
+ if (u->IsServicesOper())
memo_send(source, nick, text, 3);
else
source.Reply(_(ACCESS_DENIED));
diff --git a/modules/core/ms_set.cpp b/modules/core/ms_set.cpp
index ecd436079..82524551d 100644
--- a/modules/core/ms_set.cpp
+++ b/modules/core/ms_set.cpp
@@ -78,7 +78,7 @@ class CommandMSSet : public Command
int16 limit;
NickCore *nc = u->Account();
ChannelInfo *ci = NULL;
- bool is_servadmin = u->Account()->HasPriv("memoserv/set-limit");
+ bool is_servadmin = u->HasPriv("memoserv/set-limit");
if (p1[0] == '#')
{
@@ -258,7 +258,7 @@ class CommandMSSet : public Command
else if (subcommand.equals_ci("LIMIT"))
{
User *u = source.u;
- if (u->Account() && u->Account()->IsServicesOper())
+ if (u->IsServicesOper())
source.Reply(_("Syntax: \002SET LIMIT [\037user\037 | \037channel\037] {\037limit\037 | NONE} [HARD]\002\n"
" \n"
"Sets the maximum number of memos a user or channel is\n"
diff --git a/modules/core/ns_access.cpp b/modules/core/ns_access.cpp
index 57cc5f4f2..c3c46297c 100644
--- a/modules/core/ns_access.cpp
+++ b/modules/core/ns_access.cpp
@@ -127,7 +127,7 @@ class CommandNSAccess : public Command
const Anope::string &mask = params.size() > 1 ? params[1] : "";
NickAlias *na;
- if (cmd.equals_ci("LIST") && u->Account()->IsServicesOper() && !mask.empty() && (na = findnick(params[1])))
+ if (cmd.equals_ci("LIST") && u->IsServicesOper() && !mask.empty() && (na = findnick(params[1])))
return this->DoServAdminList(source, params, na->nc);
if (!mask.empty() && mask.find('@') == Anope::string::npos)
diff --git a/modules/core/ns_alist.cpp b/modules/core/ns_alist.cpp
index b2a622c2d..f0fd3f7aa 100644
--- a/modules/core/ns_alist.cpp
+++ b/modules/core/ns_alist.cpp
@@ -36,7 +36,7 @@ class CommandNSAList : public Command
Anope::string nick;
NickAlias *na;
- int is_servadmin = u->Account()->IsServicesOper();
+ int is_servadmin = u->IsServicesOper();
unsigned lev_param = 0;
if (!is_servadmin)
@@ -134,7 +134,7 @@ class CommandNSAList : public Command
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
User *u = source.u;
- if (u->Account() && u->Account()->IsServicesOper())
+ if (u->IsServicesOper())
source.Reply(_("Syntax: \002ALIST [\037nickname\037] [\037level\037]\002\n"
" \n"
"With no parameters, lists channels you have access on. With\n"
diff --git a/modules/core/ns_cert.cpp b/modules/core/ns_cert.cpp
index 5581149f6..5604f680d 100644
--- a/modules/core/ns_cert.cpp
+++ b/modules/core/ns_cert.cpp
@@ -134,7 +134,7 @@ class CommandNSCert : public Command
const Anope::string &mask = params.size() > 1 ? params[1] : "";
NickAlias *na;
- if (cmd.equals_ci("LIST") && u->Account()->IsServicesOper() && !mask.empty() && (na = findnick(mask)))
+ if (cmd.equals_ci("LIST") && u->IsServicesOper() && !mask.empty() && (na = findnick(mask)))
return this->DoServAdminList(source, na->nc);
if (u->Account()->HasFlag(NI_SUSPENDED))
diff --git a/modules/core/ns_drop.cpp b/modules/core/ns_drop.cpp
index 4729bf8d8..2cd134bd2 100644
--- a/modules/core/ns_drop.cpp
+++ b/modules/core/ns_drop.cpp
@@ -51,7 +51,7 @@ class CommandNSDrop : public Command
if (is_mine && nick.empty())
my_nick = na->nick;
- if (!is_mine && !u->Account()->HasPriv("nickserv/drop"))
+ if (!is_mine && !u->HasPriv("nickserv/drop"))
source.Reply(_(ACCESS_DENIED));
else if (Config->NSSecureAdmins && !is_mine && na->nc->IsServicesOper())
source.Reply(_(ACCESS_DENIED));
@@ -90,7 +90,7 @@ class CommandNSDrop : public Command
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
User *u = source.u;
- if (u->Account() && u->Account()->HasPriv("nickserv/drop"))
+ if (u->Account() && u->HasPriv("nickserv/drop"))
source.Reply(_("Syntax: \002DROP [\037nickname\037]\002\n"
" \n"
"Without a parameter, drops your nickname from the\n"
diff --git a/modules/core/ns_group.cpp b/modules/core/ns_group.cpp
index 3aa4b6419..0e51ded66 100644
--- a/modules/core/ns_group.cpp
+++ b/modules/core/ns_group.cpp
@@ -42,12 +42,16 @@ class CommandNSGroup : public Command
}
if (Config->RestrictOperNicks)
- for (std::list<std::pair<Anope::string, Anope::string> >::iterator it = Config->Opers.begin(), it_end = Config->Opers.end(); it != it_end; ++it)
- if (!u->HasMode(UMODE_OPER) && u->nick.find_ci(it->first) != Anope::string::npos)
+ for (unsigned i = 0; i < Config->Opers.size(); ++i)
+ {
+ Oper *o = Config->Opers[i];
+
+ if (!u->HasMode(UMODE_OPER) && u->nick.find_ci(o->name) != Anope::string::npos)
{
source.Reply(_(NICK_CANNOT_BE_REGISTERED), u->nick.c_str());
return MOD_CONT;
}
+ }
NickAlias *target, *na = findnick(u->nick);
if (!(target = findnick(nick)))
@@ -255,7 +259,7 @@ class CommandNSGList : public Command
const NickCore *nc = u->Account();
- if (!nick.empty() && (!nick.equals_ci(u->nick) && !u->Account()->IsServicesOper()))
+ if (!nick.empty() && (!nick.equals_ci(u->nick) && !u->IsServicesOper()))
source.Reply(_(ACCESS_DENIED), Config->s_NickServ.c_str());
else if (!nick.empty() && (!findnick(nick) || !(nc = findnick(nick)->nc)))
source.Reply(nick.empty() ? _(NICK_NOT_REGISTERED) : _(NICK_X_NOT_REGISTERED), nick.c_str());
@@ -276,7 +280,7 @@ class CommandNSGList : public Command
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
User *u = source.u;
- if (u->Account() && u->Account()->IsServicesOper())
+ if (u->IsServicesOper())
source.Reply(_("Syntax: \002GLIST [\037nickname\037]\002\n"
" \n"
"Without a parameter, lists all nicknames that are in\n"
diff --git a/modules/core/ns_help.cpp b/modules/core/ns_help.cpp
index bb16f5594..94442606e 100644
--- a/modules/core/ns_help.cpp
+++ b/modules/core/ns_help.cpp
@@ -38,9 +38,9 @@ class CommandNSHelp : public Command
"\002%R%s HELP \037command\037\002."), NickServ->nick.c_str(), NickServ->nick.c_str(),
NickServ->nick.c_str());
for (CommandMap::const_iterator it = NickServ->Commands.begin(), it_end = NickServ->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);
- if (u->Account() && u->Account()->IsServicesOper())
+ if (u->IsServicesOper())
source.Reply(_(" \n"
"Services Operators can also drop any nickname without needing\n"
"to identify for the nick, and may view the access list for\n"
diff --git a/modules/core/ns_info.cpp b/modules/core/ns_info.cpp
index 4c25179a4..6328341cb 100644
--- a/modules/core/ns_info.cpp
+++ b/modules/core/ns_info.cpp
@@ -40,7 +40,7 @@ class CommandNSInfo : public Command
const Anope::string &nick = params[0];
NickAlias *na = findnick(nick);
- bool has_auspex = u->IsIdentified() && u->Account()->HasPriv("nickserv/auspex");
+ bool has_auspex = u->IsIdentified() && u->HasPriv("nickserv/auspex");
if (!na)
{
@@ -71,7 +71,7 @@ class CommandNSInfo : public Command
source.Reply(_("%s is %s"), na->nick.c_str(), na->last_realname.c_str());
if (na->nc->IsServicesOper() && (show_hidden || !na->nc->HasFlag(NI_HIDE_STATUS)))
- source.Reply(_("%s is a services operator of type %s."), na->nick.c_str(), na->nc->ot->GetName().c_str());
+ source.Reply(_("%s is a services operator of type %s."), na->nick.c_str(), na->nc->o->ot->GetName().c_str());
if (nick_online)
{
diff --git a/modules/core/ns_list.cpp b/modules/core/ns_list.cpp
index 64eef0983..1f48d2f01 100644
--- a/modules/core/ns_list.cpp
+++ b/modules/core/ns_list.cpp
@@ -43,7 +43,7 @@ class CommandNSList : public Command
const NickCore *mync;
unsigned nnicks;
char buf[BUFSIZE];
- bool is_servadmin = u->Account()->IsServicesOper();
+ bool is_servadmin = u->IsServicesOper();
char noexpire_char = ' ';
int count = 0, from = 0, to = 0;
bool suspended, nsnoexpire, forbidden, unconfirmed;
@@ -151,7 +151,7 @@ class CommandNSList : public Command
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
User *u = source.u;
- if (u->Account() && u->Account()->IsServicesOper())
+ if (u->IsServicesOper())
source.Reply(_("Syntax: \002LIST \037pattern\037 [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]\002\n"
" \n"
"Lists all registered nicknames which match the given\n"
@@ -202,7 +202,7 @@ class CommandNSList : public Command
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
User *u = source.u;
- if (u->Account()->IsServicesOper())
+ if (u->IsServicesOper())
SyntaxError(source, "LIST", _("LIST \037pattern\037 [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"));
else
SyntaxError(source, "LIST", _(NICK_LIST_SYNTAX));
diff --git a/modules/core/ns_logout.cpp b/modules/core/ns_logout.cpp
index 798cda80f..c074fecf8 100644
--- a/modules/core/ns_logout.cpp
+++ b/modules/core/ns_logout.cpp
@@ -29,11 +29,11 @@ class CommandNSLogout : public Command
const Anope::string &param = params.size() > 1 ? params[1] : "";
User *u2;
- if (!u->Account()->IsServicesOper() && !nick.empty())
+ if (!u->IsServicesOper() && !nick.empty())
this->OnSyntaxError(source, "");
else if (!(u2 = (!nick.empty() ? finduser(nick) : u)))
source.Reply(_(NICK_X_NOT_IN_USE), nick.c_str());
- else if (!nick.empty() && u2->Account() && !u2->Account()->IsServicesOper())
+ else if (!nick.empty() && !u2->IsServicesOper())
source.Reply(_("You can't logout %s because they are a Services Operator."), nick.c_str());
else
{
@@ -64,7 +64,7 @@ class CommandNSLogout : public Command
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
User *u = source.u;
- if (u->Account() && u->Account()->IsServicesOper())
+ if (u->IsServicesOper())
source.Reply(_("Syntax: \002LOGOUT [\037nickname\037 [REVALIDATE]]\002\n"
" \n"
"Without a parameter, reverses the effect of the \002IDENTIFY\002 \n"
diff --git a/modules/core/ns_register.cpp b/modules/core/ns_register.cpp
index 1cf690f79..531933340 100644
--- a/modules/core/ns_register.cpp
+++ b/modules/core/ns_register.cpp
@@ -29,7 +29,7 @@ class CommandNSConfirm : public Command
User *u = source.u;
const Anope::string &passcode = params[0];
- if (u->Account() && u->Account()->HasPriv("nickserv/confirm"))
+ if (u->Account() && u->HasPriv("nickserv/confirm"))
{
NickAlias *na = findnick(passcode);
if (na == NULL)
@@ -74,7 +74,7 @@ class CommandNSConfirm : public Command
" \n"
"This is also used after the RESETPASS command has been used to\n"
"force identify you to your nick so you may change your password."));
- if (u->Account() && u->Account()->HasPriv("nickserv/confirm"))
+ if (u->Account() && u->HasPriv("nickserv/confirm"))
source.Reply(_("Additionally, Services Operators with the \037nickserv/confirm\037 permission can\n"
"replace \037passcode\037 with a users nick to force validate them."));
return true;
@@ -134,16 +134,16 @@ class CommandNSRegister : public Command
}
if (Config->RestrictOperNicks)
- for (std::list<std::pair<Anope::string, Anope::string> >::iterator it = Config->Opers.begin(), it_end = Config->Opers.end(); it != it_end; ++it)
+ for (unsigned i = 0; i < Config->Opers.size(); ++i)
{
- Anope::string nick = it->first;
+ Oper *o = Config->Opers[i];
- if (u->nick.find_ci(nick) != Anope::string::npos && !u->HasMode(UMODE_OPER))
+ if (!u->HasMode(UMODE_OPER) && u->nick.find_ci(o->name) != Anope::string::npos)
{
source.Reply(_(NICK_CANNOT_BE_REGISTERED), u->nick.c_str());
return MOD_CONT;
}
- }
+ }
if (Config->NSForceEmail && email.empty())
this->OnSyntaxError(source, "");
diff --git a/modules/core/ns_resetpass.cpp b/modules/core/ns_resetpass.cpp
index 09dea3502..70c7dbb6a 100644
--- a/modules/core/ns_resetpass.cpp
+++ b/modules/core/ns_resetpass.cpp
@@ -29,7 +29,7 @@ class CommandNSResetPass : public Command
User *u = source.u;
NickAlias *na;
- if (Config->RestrictMail && (!u->Account() || !u->Account()->HasCommand("nickserv/resetpass")))
+ if (Config->RestrictMail && (!u->Account() || !u->HasCommand("nickserv/resetpass")))
source.Reply(_(ACCESS_DENIED));
else if (!(na = findnick(params[0])))
source.Reply(_(NICK_X_NOT_REGISTERED), params[0].c_str());
diff --git a/modules/core/ns_sendpass.cpp b/modules/core/ns_sendpass.cpp
index 4dc571dfe..9614211c1 100644
--- a/modules/core/ns_sendpass.cpp
+++ b/modules/core/ns_sendpass.cpp
@@ -30,7 +30,7 @@ class CommandNSSendPass : public Command
const Anope::string &nick = params[0];
NickAlias *na;
- if (Config->RestrictMail && (!u->Account() || !u->Account()->HasCommand("nickserv/sendpass")))
+ if (Config->RestrictMail && (!u->Account() || !u->HasCommand("nickserv/sendpass")))
source.Reply(_(ACCESS_DENIED));
else if (!(na = findnick(nick)))
source.Reply(_(NICK_X_NOT_REGISTERED), nick.c_str());
diff --git a/modules/core/ns_set_email.cpp b/modules/core/ns_set_email.cpp
index 1c1836665..2d1d371f5 100644
--- a/modules/core/ns_set_email.cpp
+++ b/modules/core/ns_set_email.cpp
@@ -80,7 +80,7 @@ class CommandNSSetEmail : public Command
return MOD_CONT;
}
- if (!param.empty() && Config->NSConfirmEmailChanges && !u->Account()->IsServicesOper())
+ if (!param.empty() && Config->NSConfirmEmailChanges && !u->IsServicesOper())
{
u->Account()->Extend("ns_set_email", new ExtensibleItemRegular<Anope::string>(param));
Anope::string old = u->Account()->email;
diff --git a/modules/core/os_help.cpp b/modules/core/os_help.cpp
index f455b9079..e58eee435 100644
--- a/modules/core/os_help.cpp
+++ b/modules/core/os_help.cpp
@@ -31,7 +31,7 @@ class CommandOSHelp : public Command
User *u = source.u;
source.Reply(_("%s commands:"), OperServ->nick.c_str());
for (CommandMap::const_iterator it = OperServ->Commands.begin(), it_end = OperServ->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(_("\002Notice:\002 All commands sent to %s are logged!"), OperServ->nick.c_str());
}
diff --git a/modules/core/os_login.cpp b/modules/core/os_login.cpp
new file mode 100644
index 000000000..fe2da3aac
--- /dev/null
+++ b/modules/core/os_login.cpp
@@ -0,0 +1,82 @@
+/* OperServ core functions
+ *
+ * (C) 2003-2011 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandOSLogin : public Command
+{
+ public:
+ CommandOSLogin() : Command("LOGIN", 1, 1)
+ {
+ this->SetDesc(Anope::printf(_("Login to %s"), OperServ->nick.c_str()));
+ }
+
+ CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ const Anope::string &password = params[0];
+
+ Oper *o = source.u->Account()->o;
+ if (o == NULL)
+ source.Reply(_("No oper block for your nick."));
+ else if (o->password.empty())
+ source.Reply(_("Your oper block doesn't require logging in."));
+ else if (source.u->GetExt("os_login_password_correct"))
+ source.Reply(_("You are already identified."));
+ else if (o->password != password)
+ {
+ source.Reply(_(PASSWORD_INCORRECT));
+ if (bad_password(source.u))
+ return MOD_STOP;
+ }
+ else
+ {
+ Log(LOG_ADMIN, source.u, this) << "and succesfully identified to " << OperServ->nick;
+ source.u->Extend("os_login_password_correct");
+ source.Reply(_("Password accepted."));
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand)
+ {
+ source.Reply(_("Syntax: \002LOGIN\002 \037password\037\n"
+ " \n"
+ "Logs you in to %s so you gain Services Operator privileges.\n"
+ "This command may be unnecessary if your oper block is\n"
+ "configured without a password."), OperServ->nick.c_str());
+ return true;
+ }
+
+ void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
+ {
+ SyntaxError(source, "LOGIN", _("LOGIN \037password\037"));
+ }
+};
+
+class OSLogin : public Module
+{
+ CommandOSLogin commandoslogin;
+
+ public:
+ OSLogin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetType(CORE);
+
+ this->AddCommand(OperServ, &commandoslogin);
+ }
+};
+
+MODULE_INIT(OSLogin)
diff --git a/modules/core/os_staff.cpp b/modules/core/os_staff.cpp
index 7e8a4f86d..f2dbc7613 100644
--- a/modules/core/os_staff.cpp
+++ b/modules/core/os_staff.cpp
@@ -25,11 +25,11 @@ class CommandOSStaff : public Command
{
source.Reply(_("On Level Nick"));
- for (std::list<std::pair<Anope::string, Anope::string> >::iterator it = Config->Opers.begin(), it_end = Config->Opers.end(); it != it_end; ++it)
+ for (unsigned i = 0; i < Config->Opers.size(); ++i)
{
- Anope::string nick = it->first, type = it->second;
+ Oper *o = Config->Opers[i];
- NickAlias *na = findnick(nick);
+ NickAlias *na = findnick(o->name);
if (na)
{
NickCore *nc = na->nc;
@@ -38,12 +38,12 @@ class CommandOSStaff : public Command
User *u2 = *uit;
if (na->nick.equals_ci(u2->nick))
- source.Reply(_(" %c %s %s"), '*', type.c_str(), u2->nick.c_str());
+ source.Reply(_(" %c %s %s"), '*', o->ot->GetName().c_str(), u2->nick.c_str());
else
- source.Reply(_(" %c %s %s [%s]"), '*', type.c_str(), na->nick.c_str(), u2->nick.c_str());
+ source.Reply(_(" %c %s %s [%s]"), '*', o->ot->GetName().c_str(), na->nick.c_str(), u2->nick.c_str());
}
if (nc->Users.empty())
- source.Reply(_(" %c %s %s"), ' ', type.c_str(), na->nick.c_str());
+ source.Reply(_(" %c %s %s"), ' ', o->ot->GetName().c_str(), na->nick.c_str());
}
}
diff --git a/modules/extra/cs_entrymsg.cpp b/modules/extra/cs_entrymsg.cpp
index df68b141f..649fd69f8 100644
--- a/modules/extra/cs_entrymsg.cpp
+++ b/modules/extra/cs_entrymsg.cpp
@@ -107,7 +107,7 @@ class CommandEntryMessage : public Command
User *u = source.u;
ChannelInfo *ci = source.ci;
- if (ci && (IsFounder(u, ci) || u->Account()->HasCommand("chanserv/entrymsg")))
+ if (ci && (IsFounder(u, ci) || u->HasCommand("chanserv/entrymsg")))
{
bool success = true;
if (params[1].equals_ci("LIST"))
diff --git a/modules/extra/db_mysql.cpp b/modules/extra/db_mysql.cpp
index 7b1addbdb..d8a6d934c 100644
--- a/modules/extra/db_mysql.cpp
+++ b/modules/extra/db_mysql.cpp
@@ -663,7 +663,7 @@ class DBMySQL : public Module
if (service == NickServ)
{
- if (u->Account() && ((command->name.equals_ci("SET") && !params.empty()) || (command->name.equals_ci("SASET") && u->Account()->HasCommand("nickserv/saset") && params.size() > 1)))
+ if (u->Account() && ((command->name.equals_ci("SET") && !params.empty()) || (command->name.equals_ci("SASET") && u->HasCommand("nickserv/saset") && params.size() > 1)))
{
Anope::string cmd = (command->name.equals_ci("SET") ? params[0] : params[1]);
NickCore *nc = (command->name.equals_ci("SET") ? u->Account() : findcore(params[0]));
@@ -697,7 +697,7 @@ class DBMySQL : public Module
{
if (!ci)
return;
- if (!u->Account()->HasPriv("chanserv/set") && check_access(u, ci, CA_SET))
+ if (!u->HasPriv("chanserv/set") && check_access(u, ci, CA_SET))
return;
if (params[1].equals_ci("FOUNDER") && ci->founder)
{
@@ -727,7 +727,7 @@ class DBMySQL : public Module
{
if (!ci)
return;
- if (!check_access(u, ci, CA_SET) && !u->Account()->HasPriv("botserv/administration"))
+ if (!check_access(u, ci, CA_SET) && !u->HasPriv("botserv/administration"))
return;
if (params[1].equals_ci("BADWORDS") || params[1].equals_ci("BOLDS") || params[1].equals_ci("CAPS") || params[1].equals_ci("COLORS") || params[1].equals_ci("FLOOD") || params[1].equals_ci("REPEAT") || params[1].equals_ci("REVERSES") || params[1].equals_ci("UNDERLINES"))
{
@@ -756,12 +756,12 @@ class DBMySQL : public Module
}
else if (command->name.equals_ci("SET") && params.size() > 2)
{
- if (ci && !check_access(u, ci, CA_SET) && !u->Account()->HasPriv("botserv/administration"))
+ if (ci && !check_access(u, ci, CA_SET) && !u->HasPriv("botserv/administration"))
return;
BotInfo *bi = NULL;
if (!ci)
bi = findbot(params[0]);
- if (bi && params[1].equals_ci("PRIVATE") && u->Account()->HasPriv("botserv/set/private"))
+ if (bi && params[1].equals_ci("PRIVATE") && u->HasPriv("botserv/set/private"))
{
this->RunQuery("UPDATE `anope_bs_core` SET `flags` = '" + ToString(bi->ToString()) + "' WHERE `nick` = '" + this->Escape(bi->nick) + "'");
}
diff --git a/modules/extra/hs_request.cpp b/modules/extra/hs_request.cpp
index 3b0a3c4cf..4978035d3 100644
--- a/modules/extra/hs_request.cpp
+++ b/modules/extra/hs_request.cpp
@@ -423,12 +423,17 @@ void req_send_memos(CommandSource &source, const Anope::string &vIdent, const An
host = vHost;
if (HSRequestMemoOper == 1)
- for (it = Config->Opers.begin(), it_end = Config->Opers.end(); it != it_end; ++it)
+ for (unsigned i = 0; i < Config->Opers.size(); ++i)
{
- Anope::string nick = it->first;
+ Oper *o = Config->Opers[i];
+
+ NickAlias *na = findnick(o->name);
+ if (!na)
+ continue;
+
char message[BUFSIZE];
snprintf(message, sizeof(message), _("[auto memo] vHost \002%s\002 has been requested."), host.c_str());
- memo_send(source, nick, message, 2);
+ memo_send(source, na->nick, message, 2);
}
}
diff --git a/modules/extra/m_async_commands.cpp b/modules/extra/m_async_commands.cpp
index e7aa37ff0..7e1b24f34 100644
--- a/modules/extra/m_async_commands.cpp
+++ b/modules/extra/m_async_commands.cpp
@@ -46,7 +46,7 @@ class AsynchCommandMutex : public CommandMutex
return;
}
- if (!command->permission.empty() && !u->Account()->HasCommand(command->permission))
+ if (!command->permission.empty() && !u->HasCommand(command->permission))
{
u->SendMessage(bi, _(ACCESS_DENIED));
Log(LOG_COMMAND, "denied", bi) << "Access denied for user " << u->GetMask() << " with command " << command;
diff --git a/modules/extra/m_ldap_oper.cpp b/modules/extra/m_ldap_oper.cpp
index 8a5f57116..b8a1d5f51 100644
--- a/modules/extra/m_ldap_oper.cpp
+++ b/modules/extra/m_ldap_oper.cpp
@@ -1,6 +1,7 @@
#include "module.h"
#include "ldap.h"
+static std::set<Oper *> my_opers;
static Anope::string opertype_attribute;
class IdentifyInterface : public LDAPInterface
@@ -36,22 +37,32 @@ class IdentifyInterface : public LDAPInterface
const Anope::string &opertype = attr.get(opertype_attribute);
- for (std::list<OperType *>::iterator oit = Config->MyOperTypes.begin(), oit_end = Config->MyOperTypes.end(); oit != oit_end; ++oit)
+ OperType *ot = OperType::Find(opertype);
+ if (ot != NULL && (u->Account()->o == NULL || ot != u->Account()->o->ot))
{
- OperType *ot = *oit;
- if (ot->GetName() == opertype && ot != u->Account()->ot)
+ Oper *o = u->Account()->o;
+ if (o != NULL && my_opers.count(o) > 0)
{
- u->Account()->ot = ot;
- Log() << "m_ldap_oper: Tied " << u->nick << " (" << u->Account()->display << ") to opertype " << ot->GetName();
- break;
+ my_opers.erase(o);
+ delete o;
}
+ o = new Oper(u->nick, "", "", ot);
+ my_opers.insert(o);
+ u->Account()->o = o;
+ Log() << "m_ldap_oper: Tied " << u->nick << " (" << u->Account()->display << ") to opertype " << ot->GetName();
}
}
catch (const LDAPException &ex)
{
- if (u->Account()->ot != NULL)
+ if (u->Account()->o != NULL)
{
- u->Account()->ot = NULL;
+ if (my_opers.count(u->Account()->o) > 0)
+ {
+ my_opers.erase(u->Account()->o);
+ delete u->Account()->o;
+ }
+ u->Account()->o = NULL;
+
Log() << "m_ldap_oper: Removed services operator from " << u->nick << " (" << u->Account()->display << ")";
}
}
@@ -79,8 +90,8 @@ class LDAPOper : public Module
this->SetAuthor("Anope");
this->SetType(SUPPORTED);
- Implementation i[] = { I_OnReload, I_OnNickIdentify };
- ModuleManager::Attach(i, this, 2);
+ Implementation i[] = { I_OnReload, I_OnNickIdentify, I_OnDelCore };
+ ModuleManager::Attach(i, this, 3);
OnReload(false);
}
@@ -94,6 +105,10 @@ class LDAPOper : public Module
this->basedn = config.ReadValue("m_ldap_oper", "basedn", "", 0);
this->filter = config.ReadValue("m_ldap_oper", "filter", "", 0);
opertype_attribute = config.ReadValue("m_ldap_oper", "opertype_attribute", "", 0);
+
+ for (std::set<Oper *>::iterator it = my_opers.begin(), it_end = my_opers.end(); it != it_end; ++it)
+ delete *it;
+ my_opers.clear();
}
void OnNickIdentify(User *u)
@@ -115,6 +130,16 @@ class LDAPOper : public Module
Log() << "m_ldapoper: " << ex.GetReason();
}
}
+
+ void OnDelCore(NickCore *nc)
+ {
+ if (nc->o != NULL && my_opers.count(nc->o) > 0)
+ {
+ my_opers.erase(nc->o);
+ delete nc->o;
+ nc->o = NULL;
+ }
+ }
};
MODULE_INIT(LDAPOper)
diff --git a/modules/extra/m_xmlrpc_main.cpp b/modules/extra/m_xmlrpc_main.cpp
index 39c4cca19..4efe230ad 100644
--- a/modules/extra/m_xmlrpc_main.cpp
+++ b/modules/extra/m_xmlrpc_main.cpp
@@ -248,8 +248,8 @@ class MyXMLRPCEvent : public XMLRPCEvent
if (u->Account())
{
request->reply("account", iface->Sanitize(u->Account()->display));
- if (u->Account()->ot)
- request->reply("opertype", iface->Sanitize(u->Account()->ot->GetName()));
+ if (u->Account()->o)
+ request->reply("opertype", iface->Sanitize(u->Account()->o->ot->GetName()));
}
Anope::string channels;
diff --git a/src/commands.cpp b/src/commands.cpp
index 00fe6574c..91b4787fd 100644
--- a/src/commands.cpp
+++ b/src/commands.cpp
@@ -156,7 +156,7 @@ void mod_run_cmd(BotInfo *bi, User *u, ChannelInfo *ci, Command *c, const Anope:
}
// If the command requires a permission, and they aren't registered or don't have the required perm, DENIED
- if (!c->permission.empty() && !u->Account()->HasCommand(c->permission))
+ if (!c->permission.empty() && !u->HasCommand(c->permission))
{
u->SendMessage(bi, _(ACCESS_DENIED));
Log(LOG_COMMAND, "denied", bi) << "Access denied for user " << u->GetMask() << " with command " << command;
@@ -201,7 +201,7 @@ void mod_help_cmd(BotInfo *bi, User *u, ChannelInfo *ci, const Anope::string &cm
source.service = ci ? ci->bi : bi;
source.fantasy = ci != NULL;
- if (!c || (Config->HidePrivilegedCommands && !c->permission.empty() && (!u->Account() || !u->Account()->HasCommand(c->permission))) || !c->OnHelp(source, subcommand))
+ if (!c || (Config->HidePrivilegedCommands && !c->permission.empty() && !u->HasCommand(c->permission)) || !c->OnHelp(source, subcommand))
source.Reply( _("No help available for \002%s\002."), cmd.c_str());
else
{
@@ -215,7 +215,7 @@ void mod_help_cmd(BotInfo *bi, User *u, ChannelInfo *ci, const Anope::string &cm
if (!c->HasFlag(CFLAG_ALLOW_UNREGISTERED) && !u->IsIdentified())
source.Reply( _("You need to be identified to use this command."));
/* User doesn't have the proper permission to use this command */
- else if (!c->permission.empty() && (!u->Account() || !u->Account()->HasCommand(c->permission)))
+ else if (!c->permission.empty() && !u->HasCommand(c->permission))
source.Reply(_("You cannot use this command."));
/* User can use this command */
else
diff --git a/src/config.cpp b/src/config.cpp
index 86ef446bc..e230a15b7 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -792,8 +792,10 @@ static bool DoneOperTypes(ServerConfig *, const Anope::string &)
static bool InitOpers(ServerConfig *config, const Anope::string &)
{
for (nickcore_map::const_iterator it = NickCoreList.begin(), it_end = NickCoreList.end(); it != it_end; ++it)
- it->second->ot = NULL;
+ it->second->o = NULL;
+ for (unsigned i = 0; i < config->Opers.size(); ++i)
+ delete config->Opers[i];
config->Opers.clear();
return true;
@@ -803,6 +805,8 @@ static bool DoOper(ServerConfig *config, const Anope::string &, const Anope::str
{
Anope::string name = values[0].GetValue();
Anope::string type = values[1].GetValue();
+ Anope::string password = values[2].GetValue();
+ Anope::string certfp = values[3].GetValue();
ValueItem vi(name);
if (!ValidateNotEmpty(config, "oper", "name", vi))
@@ -811,35 +815,35 @@ static bool DoOper(ServerConfig *config, const Anope::string &, const Anope::str
ValueItem vi2(type);
if (!ValidateNotEmpty(config, "oper", "type", vi2))
throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+
+ OperType *ot = NULL;
+ for (std::list<OperType *>::iterator it = config->MyOperTypes.begin(), it_end = config->MyOperTypes.end(); it != it_end; ++it)
+ if ((*it)->GetName() == type)
+ ot = *it;
+ if (ot == NULL)
+ throw ConfigException("Oper block for " + name + " has invalid oper type " + type);
+
+ Oper *o = new Oper(name, password, certfp, ot);
+ config->Opers.push_back(o);
- config->Opers.push_back(std::make_pair(name, type));
return true;
}
static bool DoneOpers(ServerConfig *config, const Anope::string &)
{
- for (std::list<std::pair<Anope::string, Anope::string> >::iterator it = config->Opers.begin(), it_end = config->Opers.end(); it != it_end; ++it)
+ for (unsigned i = 0; i < config->Opers.size(); ++i)
{
- Anope::string nick = it->first, type = it->second;
+ Oper *o = config->Opers[i];
- NickAlias *na = findnick(nick);
+ NickAlias *na = findnick(o->name);
if (!na)
// Nonexistant nick
continue;
- if (!na->nc)
- throw CoreException("Nick with no core?");
-
- for (std::list<OperType *>::iterator tit = config->MyOperTypes.begin(), tit_end = config->MyOperTypes.end(); tit != tit_end; ++tit)
- {
- OperType *ot = *tit;
- if (ot->GetName().equals_ci(type))
- {
- Log() << "Tied oper " << na->nc->display << " to type " << type;
- na->nc->ot = ot;
- }
- }
+ na->nc->o = o;
+ Log() << "Tied oper " << na->nc->display << " to type " << o->ot->GetName();
}
+
return true;
}
@@ -1295,9 +1299,9 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{DT_CHARPTR, DT_CHARPTR, DT_CHARPTR, DT_CHARPTR},
InitOperTypes, DoOperType, DoneOperTypes},
{"oper",
- {"name", "type", ""},
- {"", "", ""},
- {DT_CHARPTR, DT_CHARPTR},
+ {"name", "type", "password", "certfp", ""},
+ {"", "", "", "", ""},
+ {DT_CHARPTR, DT_CHARPTR, DT_CHARPTR, DT_CHARPTR},
InitOpers, DoOper, DoneOpers},
{"",
{""},
diff --git a/src/memoserv.cpp b/src/memoserv.cpp
index 128694557..9869e4264 100644
--- a/src/memoserv.cpp
+++ b/src/memoserv.cpp
@@ -167,7 +167,7 @@ void memo_send(CommandSource &source, const Anope::string &name, const Anope::st
bool ischan, isforbid;
MemoInfo *mi;
Anope::string sender = u && u->Account() ? u->Account()->display : "";
- int is_servoper = u && u->Account() && u->Account()->IsServicesOper();
+ bool is_servoper = u != NULL && u->IsServicesOper();
if (readonly)
u->SendMessage(MemoServ, _(MEMO_SEND_DISABLED));
@@ -217,7 +217,7 @@ void memo_send(CommandSource &source, const Anope::string &name, const Anope::st
{
if (!z || z == 3)
source.Reply(_("Memo sent to \002%s\002."), name.c_str());
- if ((!u->Account() || !u->Account()->IsServicesOper()) && mi->HasIgnore(u))
+ if (!u->IsServicesOper() && mi->HasIgnore(u))
return;
u->lastmemosend = Anope::CurTime;
diff --git a/src/messages.cpp b/src/messages.cpp
index c5ea2f039..192859e6f 100644
--- a/src/messages.cpp
+++ b/src/messages.cpp
@@ -37,15 +37,13 @@ bool OnStats(const Anope::string &source, const std::vector<Anope::string> &para
ircdproto->SendNumeric(Config->ServerName, 219, source, "%c :End of /STATS report.", params[0][0]);
else
{
- std::list<std::pair<Anope::string, Anope::string> >::iterator it, it_end;
-
- for (it = Config->Opers.begin(), it_end = Config->Opers.end(); it != it_end; ++it)
+ for (unsigned i = 0; i < Config->Opers.size(); ++i)
{
- Anope::string nick = it->first, type = it->second;
+ Oper *o = Config->Opers[i];
- NickCore *nc = findcore(nick);
- if (nc)
- ircdproto->SendNumeric(Config->ServerName, 243, source, "O * * %s %s 0", nick.c_str(), type.c_str());
+ NickAlias *na = findnick(o->name);
+ if (na)
+ ircdproto->SendNumeric(Config->ServerName, 243, source, "O * * %s %s 0", o->name.c_str(), o->ot->GetName().c_str());
}
ircdproto->SendNumeric(Config->ServerName, 219, source, "%c :End of /STATS report.", params[0][0]);
diff --git a/src/nickalias.cpp b/src/nickalias.cpp
index 3c8af1142..06e5f60dd 100644
--- a/src/nickalias.cpp
+++ b/src/nickalias.cpp
@@ -19,24 +19,12 @@ NickAlias::NickAlias(const Anope::string &nickname, NickCore *nickcore) : Flags<
NickAliasList[this->nick] = this;
- for (std::list<std::pair<Anope::string, Anope::string> >::iterator it = Config->Opers.begin(), it_end = Config->Opers.end(); it != it_end; ++it)
+ if (this->nc->o == NULL)
{
- if (this->nc->ot)
- break;
- if (!this->nick.equals_ci(it->first))
- continue;
-
- for (std::list<OperType *>::iterator tit = Config->MyOperTypes.begin(), tit_end = Config->MyOperTypes.end(); tit != tit_end; ++tit)
- {
- OperType *ot = *tit;
-
- if (ot->GetName().equals_ci(it->second))
- {
- Log() << "Tied oper " << this->nc->display << " to type " << ot->GetName();
- this->nc->ot = ot;
- break;
- }
- }
+ Oper *o = Oper::Find(this->nick);
+ if (o == NULL)
+ o = Oper::Find(this->nc->display);
+ this->nc->o = o;
}
}
diff --git a/src/nickcore.cpp b/src/nickcore.cpp
index e83d46c47..5fdf9c2dd 100644
--- a/src/nickcore.cpp
+++ b/src/nickcore.cpp
@@ -9,7 +9,7 @@ NickCore::NickCore(const Anope::string &coredisplay) : Flags<NickCoreFlag, NI_EN
if (coredisplay.empty())
throw CoreException("Empty display passed to NickCore constructor");
- this->ot = NULL;
+ this->o = NULL;
this->channelcount = 0;
this->lastmail = 0;
this->memos.memomax = Config->MSMaxMemos;
@@ -65,30 +65,9 @@ NickCore::~NickCore()
}
}
-bool NickCore::HasCommand(const Anope::string &cmdstr) const
-{
- if (!this->ot)
- // No opertype.
- return false;
-
- return this->ot->HasCommand(cmdstr);
-}
-
bool NickCore::IsServicesOper() const
{
- if (this->ot)
- return true;
-
- return false;
-}
-
-bool NickCore::HasPriv(const Anope::string &privstr) const
-{
- if (!this->ot)
- // No opertype.
- return false;
-
- return this->ot->HasPriv(privstr);
+ return this->o != NULL;
}
void NickCore::AddAccess(const Anope::string &entry)
diff --git a/src/nickserv.cpp b/src/nickserv.cpp
index fb1e52819..0c036f564 100644
--- a/src/nickserv.cpp
+++ b/src/nickserv.cpp
@@ -185,12 +185,14 @@ int validate_user(User *u)
u->Collide(na);
return 0;
}
+
if (!u->IsIdentified() && !u->fingerprint.empty() && na->nc->FindCert(u->fingerprint))
{
u->SendMessage(NickServ, _("SSL Fingerprint accepted, you are now identified"));
u->Identify(na);
return 1;
}
+
if (!na->nc->HasFlag(NI_SECURE) && u->IsRecognized())
{
na->last_seen = Anope::CurTime;
diff --git a/src/opertype.cpp b/src/opertype.cpp
index 19e0dd00f..9d6a4086f 100644
--- a/src/opertype.cpp
+++ b/src/opertype.cpp
@@ -7,6 +7,33 @@
#include "services.h"
+
+Oper *Oper::Find(const Anope::string &name)
+{
+ for (unsigned i = 0; i < Config->Opers.size(); ++i)
+ {
+ Oper *o = Config->Opers[i];
+
+ if (o->name.equals_ci(name))
+ return o;
+ }
+
+ return NULL;
+}
+
+OperType *OperType::Find(const Anope::string &name)
+{
+ for (std::list<OperType *>::iterator it = Config->MyOperTypes.begin(), it_end = Config->MyOperTypes.end(); it != it_end; ++it)
+ {
+ OperType *ot = *it;
+
+ if (ot->GetName() == name)
+ return ot;
+ }
+
+ return NULL;
+}
+
OperType::OperType(const Anope::string &nname) : name(nname)
{
}
diff --git a/src/users.cpp b/src/users.cpp
index 4b6e7368e..5e97fee5d 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -462,6 +462,46 @@ bool User::IsRecognized(bool CheckSecure)
return OnAccess;
}
+/** Check if the user is a services oper
+ * @return true if they are an oper
+ */
+bool User::IsServicesOper()
+{
+ if (!this->nc || !this->nc->o)
+ // No opertype.
+ return false;
+ else if (!this->nc->o->certfp.empty() && this->fingerprint != this->nc->o->certfp)
+ // Certfp mismatch
+ return false;
+ else if (!this->nc->o->password.empty() && !this->GetExt("os_login_password_correct"))
+ // Not identified
+ return false;
+
+ return true;
+}
+
+/** 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 User::HasCommand(const Anope::string &command)
+{
+ if (this->IsServicesOper())
+ return this->nc->o->ot->HasCommand(command);
+ return false;
+}
+
+/** 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 User::HasPriv(const Anope::string &priv)
+{
+ if (this->IsServicesOper())
+ return this->nc->o->ot->HasPriv(priv);
+ return false;
+}
+
/** Update the last usermask stored for a user, and check to see if they are recognized
*/
void User::UpdateHost()