1
0
mirror of https://github.com/anope/anope.git synced 2026-06-30 13:26:38 +02:00

Rewrote some of the opertype system, added os_login

This commit is contained in:
Adam
2011-03-14 13:52:26 -04:00
parent 4fe49af840
commit ed73d76751
65 changed files with 393 additions and 201 deletions
+7 -1
View File
@@ -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
+2
View File
@@ -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
+2 -2
View File
@@ -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
+1 -13
View File
@@ -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
+1 -1
View File
@@ -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.
+25
View File
@@ -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".
*/
+17
View File
@@ -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();
+2 -2
View File
@@ -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;
+2 -2
View File
@@ -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;
+3 -3
View File
@@ -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;
+1 -1
View File
@@ -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:"));
+1 -1
View File
@@ -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"
+2 -2
View File
@@ -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;
+1 -1
View File
@@ -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));
+4 -4
View File
@@ -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"
+1 -1
View File
@@ -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));
+7 -7
View File
@@ -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);
+1 -1
View File
@@ -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."));
+1 -1
View File
@@ -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;
+4 -4
View File
@@ -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"
+1 -1
View File
@@ -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;
+2 -2
View File
@@ -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"
+1 -1
View File
@@ -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))
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -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
{
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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
{
+6 -6
View File
@@ -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;
+1 -1
View File
@@ -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);
}
};
+1 -1
View File
@@ -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"
+4 -4
View File
@@ -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"
+1 -1
View File
@@ -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));
+2 -2
View File
@@ -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"
+1 -1
View File
@@ -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)
+2 -2
View File
@@ -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"
+1 -1
View File
@@ -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))
+2 -2
View File
@@ -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"
+8 -4
View File
@@ -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"
+2 -2
View File
@@ -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"
+2 -2
View File
@@ -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)
{
+3 -3
View File
@@ -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));
+3 -3
View File
@@ -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"
+6 -6
View File
@@ -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, "");
+1 -1
View File
@@ -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());
+1 -1
View File
@@ -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());
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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());
}
+82
View File
@@ -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)
+6 -6
View File
@@ -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());
}
}
+1 -1
View File
@@ -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"))
+5 -5
View File
@@ -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) + "'");
}
+8 -3
View File
@@ -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);
}
}
+1 -1
View File
@@ -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;
+35 -10
View File
@@ -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)
+2 -2
View File
@@ -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;
+3 -3
View File
@@ -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
+24 -20
View File
@@ -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},
{"",
{""},
+2 -2
View File
@@ -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;
+5 -7
View File
@@ -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]);
+5 -17
View File
@@ -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;
}
}
+2 -23
View File
@@ -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)
+2
View File
@@ -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;
+27
View File
@@ -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)
{
}
+40
View File
@@ -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()