From c2ddecc2b1dbc9d055166bdf296da2e4536f74f6 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 27 Aug 2010 20:56:28 -0400 Subject: Added a new logging system --- data/example.conf | 112 ++++--- docs/Changes.conf | 2 + include/bots.h | 2 + include/channels.h | 4 +- include/config.h | 13 +- include/extern.h | 15 +- include/logger.h | 100 ++++++ include/modules.h | 4 +- include/services.h | 41 +-- include/users.h | 8 +- modules/core/bs_act.cpp | 6 +- modules/core/bs_assign.cpp | 3 + modules/core/bs_badwords.cpp | 19 +- modules/core/bs_bot.cpp | 6 + modules/core/bs_kick.cpp | 21 +- modules/core/bs_say.cpp | 6 +- modules/core/bs_set.cpp | 3 + modules/core/bs_unassign.cpp | 3 + modules/core/cs_access.cpp | 38 ++- modules/core/cs_akick.cpp | 32 +- modules/core/cs_ban.cpp | 5 +- modules/core/cs_clear.cpp | 6 +- modules/core/cs_drop.cpp | 13 +- modules/core/cs_forbid.cpp | 11 +- modules/core/cs_getkey.cpp | 3 + modules/core/cs_invite.cpp | 5 +- modules/core/cs_kick.cpp | 3 + modules/core/cs_modes.cpp | 38 +-- modules/core/cs_register.cpp | 10 +- modules/core/cs_saset.cpp | 4 +- modules/core/cs_set.cpp | 3 +- modules/core/cs_set_founder.cpp | 2 +- modules/core/cs_set_successor.cpp | 2 +- modules/core/cs_set_xop.cpp | 4 +- modules/core/cs_suspend.cpp | 11 +- modules/core/cs_topic.cpp | 14 +- modules/core/cs_xop.cpp | 22 +- modules/core/db_plain.cpp | 33 +- modules/core/enc_md5.cpp | 2 +- modules/core/enc_none.cpp | 2 +- modules/core/enc_old.cpp | 2 +- modules/core/enc_sha1.cpp | 2 +- modules/core/enc_sha256.cpp | 2 +- modules/core/hs_del.cpp | 2 +- modules/core/hs_delall.cpp | 2 +- modules/core/hs_off.cpp | 1 + modules/core/hs_on.cpp | 1 + modules/core/hs_set.cpp | 3 +- modules/core/hs_setall.cpp | 2 +- modules/core/ms_rsend.cpp | 2 +- modules/core/ns_drop.cpp | 4 +- modules/core/ns_forbid.cpp | 5 +- modules/core/ns_getemail.cpp | 2 +- modules/core/ns_getpass.cpp | 4 +- modules/core/ns_ghost.cpp | 4 +- modules/core/ns_group.cpp | 12 +- modules/core/ns_identify.cpp | 6 +- modules/core/ns_logout.cpp | 2 +- modules/core/ns_recover.cpp | 2 +- modules/core/ns_register.cpp | 18 +- modules/core/ns_release.cpp | 4 +- modules/core/ns_resetpass.cpp | 6 +- modules/core/ns_saset.cpp | 6 +- modules/core/ns_sendpass.cpp | 2 +- modules/core/ns_set.cpp | 4 +- modules/core/ns_set_email.cpp | 2 - modules/core/ns_suspend.cpp | 4 +- modules/core/os_defcon.cpp | 18 +- modules/core/os_ignore.cpp | 2 +- modules/core/os_modunload.cpp | 2 +- modules/core/os_news.cpp | 10 +- modules/core/os_reload.cpp | 2 +- modules/core/os_set.cpp | 76 +---- modules/core/ss_main.cpp | 4 +- modules/extra/cs_appendtopic.cpp | 2 +- modules/extra/cs_enforce.cpp | 6 - modules/extra/cs_set_misc.cpp | 2 +- modules/extra/db_mysql.cpp | 38 ++- modules/extra/hs_request.cpp | 16 +- modules/extra/m_mysql.cpp | 10 +- modules/extra/m_ssl.cpp | 8 +- modules/extra/ns_maxemail.cpp | 2 +- modules/extra/ns_set_misc.cpp | 2 +- modules/protocol/bahamut.cpp | 8 +- modules/protocol/inspircd11.cpp | 20 +- modules/protocol/inspircd12.cpp | 22 +- modules/protocol/inspircd20.cpp | 26 +- modules/protocol/ratbox.cpp | 12 +- modules/protocol/unreal32.cpp | 20 +- modules/socketengines/m_socketengine_epoll.cpp | 14 +- modules/socketengines/m_socketengine_select.cpp | 2 +- src/bots.cpp | 15 +- src/channels.cpp | 72 +++-- src/chanserv.cpp | 16 +- src/commands.cpp | 8 +- src/config.cpp | 127 ++++++-- src/encrypt.cpp | 4 +- src/init.cpp | 157 ++++------ src/language.cpp | 19 +- src/log.cpp | 264 ---------------- src/logger.cpp | 399 ++++++++++++++++++++++++ src/mail.cpp | 4 +- src/main.cpp | 268 ++++++++-------- src/memoserv.cpp | 2 +- src/messages.cpp | 10 +- src/misc.cpp | 4 +- src/modes.cpp | 40 ++- src/modulemanager.cpp | 26 +- src/modules.cpp | 22 +- src/nickalias.cpp | 2 +- src/nickcore.cpp | 2 +- src/nickserv.cpp | 8 +- src/process.cpp | 24 +- src/regchannel.cpp | 10 +- src/send.cpp | 8 +- src/servers.cpp | 30 +- src/sessions.cpp | 12 +- src/sockets.cpp | 2 +- src/users.cpp | 110 +++---- 119 files changed, 1510 insertions(+), 1216 deletions(-) create mode 100644 include/logger.h delete mode 100644 src/log.cpp create mode 100644 src/logger.cpp diff --git a/data/example.conf b/data/example.conf index 7dc9c1685..65d94ad5f 100644 --- a/data/example.conf +++ b/data/example.conf @@ -201,23 +201,6 @@ serverinfo */ networkinfo { - /* - * If set, Services will output log messages to the given channel. This - * directive is optional. - * - * IMPORTANT: This can be a security risk, so make certain this channel is - * sufficiently protected from normal access. - */ - #logchannel = "#services" - - /* - * If set, Services will output all BotServ chatter to the defined logchannel - * above. It shows all uses of BotServ ACT and SAY commands. Note that there - * is no logging to the log file. Only works if logchannel is also defined. - * This directive is optional. - */ - #logbot = yes - /* * This is the name of the network that Services will be running on. */ @@ -475,13 +458,6 @@ options */ #dumpcore = yes - /* - * If set, Anope will log user connections, disconnections, and nickname - * changes. You may have to do so in case you ever need to transmit user - * information to your local authorities. This directive is optional. - */ - #logusers = yes - /* * If set, Services will only show /stats o to IRC Operators. This directive * is optional. @@ -546,12 +522,6 @@ options */ ulineservers = "stats.your.network" - /* - * If set, Services will start logging to the log channel immediatly on startup. - * This directive is optional, and has no effect if logchannel is not defined. - */ - #enablelogchannel = yes - /* * Default modes for mode lock, these are set on newly registered channels. */ @@ -580,6 +550,80 @@ options hideprivilegedcommands = no } +/* + * [RECOMMENDED] Logging Configuration + * + * This section is used for configuring what is logged and where it is logged to. + * You may have multiple log blocks if you wish. Remember to properly secure any + * channels you choose to have Anope log to! + */ +log +{ + /* + * Target(s) to log to. If it starts with a # it is assumed to be a channel, otherwise + * it will log to a file. + */ + target = "services.log" + /* Log to both services.log and the channel #services */ + //target = "services.log #services" + + /* + * The source(s) to only accept log messages from. Leave commented to allow all sources. + * This can be a users name, a channel name, one of our clients (eg, OperServ), or a server name. + */ + //source = "" + + /* + * The number of days to keep logfiles, only useful if you are logging to a file. + * Set to 0 to never delete old logfiles. + * + * Note that Anope must run 24 hours a day for this feature to work correctly. + */ + logage = 7 + + /* + * What types of log messages should be logged by this block. There are nine general categories: + * + * admin - Execution of admin commands (OperServ, etc). + * override - A services operator using their powers to execute a command they couldn't normally. + * commands - Execution of general commands. + * servers - Server actions, linking, squitting, etc. + * channels - Actions in channels such as joins, parts, kicks, etc. + * users - User actions such as connecting, disconnecting, changing name, etc. + * normal - Miscelanious messages. + * rawio - Logs raw input and output from services + * debug - Debug messages (log files can become VERY large from this). + * + * These options determin what messages from the categories should be logged. Wildcards are accepted, and + * you can also negate values with a ~. For example, "operserv/* ~operserv/akill" would log all operserv + * messages except for operserv/akill. + * + * Valid admin, override, and command options are: + * pesudo-serv/commandname (eg, operserv/akill, chanserv/set) + * + * Valid server options are: + * connect, quit, sync + * + * Valid channel options are: + * create, destroy, join, part, kick, leave, mode + * + * Valid user options are: + * connect, disconnect, quit, nick, ident, host, mode, maxusers + * + * Normal and debug are simple yes/no answers, there are no types for them. + * + * Note that modules may add their own values to these options. + */ + admin = "operserv/*" + override = "chanserv/* nickserv/* memoserv/set botserv/* ~botserv/set" + commands = "~operserv/* *" + servers = "*" + //channels = "~mode *" + users = "connect disconnect nick" + normal = yes + rawio = no + debug = no +} /* * [RECOMMENDED] Oper Access Config @@ -594,7 +638,7 @@ options * * Available privileges: * botserv/administration - Can perform certain BotServ administrative tasks - * chanserv/access/modify - Can modify channel access lists + * chanserv/access/modify - Can modify channel access and akick lists * chanserv/auspex - Can see any information with /chanserv info * chanserv/no-register-limit - May register an unlimited number of channels and nicknames * chanserv/set - Can modify the settings of any channel (incl. changing of the owner and password!) @@ -1301,12 +1345,6 @@ operserv */ #superadmin = yes - /* - * If set, causes Services to write a message to the log every time a new user maximum is set. - * This directive is optional. - */ - logmaxusers = yes - /* * These define the default expiration times for, respectively, AKILLs, CHANKILLs, SNLINEs, * SQLINEs, and SZLINEs. diff --git a/docs/Changes.conf b/docs/Changes.conf index 404a06bc2..01227d8b2 100644 --- a/docs/Changes.conf +++ b/docs/Changes.conf @@ -11,6 +11,7 @@ opertype:commands added nickserv/saset/* and chanserv/saset/* options:socketengine added to choose what socket engine to use module:cs_set_misc and module:ns_set_misc added to replace the old set url/icq/email modules options:hideprivilegedcommands added to hide privileged commands from normal users +log block added to customize logging ** MODIFIED CONFIGURATION DIRECTIVES ** opertype:commands changed operserv/sgline to opserv/snline @@ -21,6 +22,7 @@ operserv:notifications ossgline changed ossnline ** DELETED CONFIGURATION DIRECTIVES ** serverinfo:helpchannel removed because it has been readded in m_helpchan +networkinfo:logchannel, logbot, logusers, logmaxusers, and logchannel removed because of the log block Anope Version 1.9.2 -------------------- diff --git a/include/bots.h b/include/bots.h index f6b8d2e14..0a84cce71 100644 --- a/include/bots.h +++ b/include/bots.h @@ -23,6 +23,8 @@ enum BotFlag { BI_BEGIN, + /* This bot is a core bot. NickServ, ChanServ, etc */ + BI_CORE, /* This bot can only be assigned by IRCops */ BI_PRIVATE, diff --git a/include/channels.h b/include/channels.h index 8c5d83c5d..7a02b3d6b 100644 --- a/include/channels.h +++ b/include/channels.h @@ -57,7 +57,9 @@ enum ChannelFlags /* Channel still exists when emptied */ CH_PERSIST, /* If set the channel is syncing users (channel was just created) and it should not be deleted */ - CH_SYNCING + CH_SYNCING, + /* Is a services log channel */ + CH_LOGCHAN }; class CoreExport Channel : public Extensible, public Flags diff --git a/include/config.h b/include/config.h index 8313f94d6..5d605aca5 100644 --- a/include/config.h +++ b/include/config.h @@ -465,8 +465,6 @@ class ServerConfig /* The hostname if services clients */ Anope::string ServiceHost; - /* Log channel */ - Anope::string LogChannel; /* Name of the network were on */ Anope::string NetworkName; /* The max legnth of nicks */ @@ -544,8 +542,6 @@ class ServerConfig bool UseStrictPrivMsg; /* Dump a core file if we crash */ bool DumpCore; - /* Log users connecting/existing/changing nicks */ - bool LogUsers; /* Number of seconds between consecutive uses of the REGISTER command * Not to be confused with NSRegDelay */ unsigned NickRegDelay; @@ -555,6 +551,8 @@ class ServerConfig Anope::string MLock; /* Default botmodes on channels, defaults to ao */ Anope::string BotModes; + /* THe actual modes */ + std::vector BotModeList; /* How many times to try and reconnect to the uplink before giving up */ unsigned MaxRetries; /* How long to wait between connection attempts */ @@ -562,6 +560,9 @@ class ServerConfig /* If services should hide unprivileged commands */ bool HidePrivilegedCommands; + /* A vector of our logfile options */ + std::vector LogInfos; + /* Services can use email */ bool UseMail; /* Path to the sendmail executable */ @@ -684,10 +685,6 @@ class ServerConfig Anope::string GlobalOnCycleUP; /* Super admin is allowed */ bool SuperAdmin; - /* Log things said through ACT/SAY */ - bool LogBot; - /* Log when new user max is reached */ - bool LogMaxUsers; /* Default expiry time for akills */ time_t AutokillExpiry; /* Default expiry time for chan kills */ diff --git a/include/extern.h b/include/extern.h index 4dc6cb4ba..dc4582478 100644 --- a/include/extern.h +++ b/include/extern.h @@ -153,8 +153,7 @@ E void hostserv_init(); E void introduce_user(const Anope::string &user); E bool GetCommandLineArgument(const Anope::string &name, char shortname = 0); E bool GetCommandLineArgument(const Anope::string &name, char shortname, Anope::string ¶m); -E int init_primary(int ac, char **av); -E int init_secondary(int ac, char **av); +E void Init(int ac, char **av); E Uplink *uplink_server; /**** ircd.c ****/ @@ -177,13 +176,8 @@ E const char *getstring(const NickCore *nc, int index); E const char *getstring(const User *nc, int index); E const char *getstring(int index); -/**** log.c ****/ - -E int open_log(); -E void close_log(); -E void log_perror(const char *fmt, ...) FORMAT(printf, 1, 2); -E void fatal(const char *fmt, ...) FORMAT(printf, 1, 2); -E void fatal_perror(const char *fmt, ...) FORMAT(printf, 1, 2); +/*** logger.cpp ***/ +E void InitLogChannels(ServerConfig *); /**** main.c ****/ @@ -193,7 +187,6 @@ E Anope::string services_dir; E Anope::string log_filename; E int debug; E bool readonly; -E bool LogChan; E bool nofork; E bool nothird; E bool noexpire; @@ -297,8 +290,6 @@ E unsigned GenericChannelModes, GenericUserModes; E Flags DefMLockOn; E Flags DefMLockOff; E std::map DefMLockParams; -/* Modes to set on bots when they join the channel */ -E std::list BotModes; E void SetDefaultMLock(ServerConfig *config); /**** nickserv.c ****/ diff --git a/include/logger.h b/include/logger.h new file mode 100644 index 000000000..79a582503 --- /dev/null +++ b/include/logger.h @@ -0,0 +1,100 @@ +#ifndef LOGGER_H +#define LOGGER_H + +enum LogType +{ + LOG_ADMIN, + LOG_OVERRIDE, + LOG_COMMAND, + LOG_SERVER, + LOG_CHANNEL, + LOG_USER, + LOG_NORMAL, + LOG_TERMINAL, + LOG_RAWIO, + LOG_DEBUG, + LOG_DEBUG_2, + LOG_DEBUG_3, + LOG_DEBUG_4 +}; + +struct LogFile +{ + Anope::string filename; + + public: + std::ofstream stream; + + LogFile(const Anope::string &name); + Anope::string GetName() const; +}; + +class CoreExport Log +{ + public: + BotInfo *bi; + LogType Type; + Anope::string Category; + std::list Sources; + + std::stringstream buf; + + Log(LogType type = LOG_NORMAL, const Anope::string &category = "", BotInfo *bi = Global); + + /* LOG_COMMAND/OVERRIDE/ADMIN */ + Log(LogType type, User *u, Command *c, ChannelInfo *ci = NULL); + + /* LOG_CHANNEL */ + Log(User *u, Channel *c, const Anope::string &category = ""); + + /* LOG_USER */ + explicit Log(User *u, const Anope::string &category = ""); + + /* LOG_SERVER */ + Log(Server *s, const Anope::string &category = ""); + + Log(BotInfo *b, const Anope::string &category = ""); + + ~Log(); + + template Log &operator<<(T val) + { + this->buf << val; + return *this; + } +}; + +class CoreExport LogInfo +{ + public: + std::list Targets; + std::map Logfiles; + std::list Sources; + int LogAge; + std::list Admin; + std::list Override; + std::list Commands; + std::list Servers; + std::list Users; + std::list Channels; + bool Normal; + bool RawIO; + bool Debug; + + LogInfo(int logage, bool normal, bool rawio, bool debug); + + ~LogInfo(); + + void AddType(std::list &list, const Anope::string &type); + + bool HasType(std::list &list, const Anope::string &type) const; + + std::list &GetList(LogType type); + + bool HasType(LogType Type); + + void ProcessMessage(const Log *l); +}; + +#endif // LOGGER_H + diff --git a/include/modules.h b/include/modules.h index 0d279c6c0..ebe56df48 100644 --- a/include/modules.h +++ b/include/modules.h @@ -66,7 +66,7 @@ if (true) \ } \ catch (const ModuleException &modexcept) \ { \ - Alog() << "Exception caught: " << modexcept.GetReason(); \ + Log() << "Exception caught: " << modexcept.GetReason(); \ } \ _i = safei; \ } \ @@ -98,7 +98,7 @@ if (true) \ } \ catch (const ModuleException &modexcept) \ { \ - Alog() << "Exception caught: " << modexcept.GetReason(); \ + Log() << "Exception caught: " << modexcept.GetReason(); \ } \ _i = safei; \ } \ diff --git a/include/services.h b/include/services.h index 2cda56a31..a0c701b95 100644 --- a/include/services.h +++ b/include/services.h @@ -181,6 +181,7 @@ extern "C" void __pfnBkCheck() {} /* Pull in the various bits of STL */ #include +#include #include #include #include @@ -253,6 +254,14 @@ class CoreException : public std::exception } }; +class FatalException : public CoreException +{ + public: + FatalException(const Anope::string &reason = "") : CoreException(reason) { } + + virtual ~FatalException() throw() { } +}; + class ModuleException : public CoreException { public: @@ -939,6 +948,7 @@ class ServerConfig; #include "operserv.h" #include "mail.h" #include "servers.h" +#include "logger.h" #include "config.h" class CoreExport IRCDProto @@ -1039,10 +1049,6 @@ class CoreExport IRCDProto virtual void SetAutoIdentificationToken(User *u) { } }; -class IRCDTS6Proto : public IRCDProto -{ -}; - /*************************************************************************/ struct Uplink @@ -1055,33 +1061,6 @@ struct Uplink Uplink(const Anope::string &_host, int _port, const Anope::string &_password, bool _ipv6) : host(_host), port(_port), password(_password), ipv6(_ipv6) { } }; -enum LogLevel -{ - LOG_NORMAL, - LOG_TERMINAL, - LOG_DEBUG, - LOG_DEBUG_2, - LOG_DEBUG_3, - LOG_DEBUG_4 -}; - -class CoreExport Alog -{ - private: - std::stringstream buf; - LogLevel Level; - public: - Alog(LogLevel val = LOG_NORMAL); - ~Alog(); - template Alog &operator<<(T val) - { - buf << val; - return *this; - } -}; - -/*************************************************************************/ - #include "timers.h" /** Timer for colliding nicks to force people off of nicknames diff --git a/include/users.h b/include/users.h index 40e98b114..e65068f33 100644 --- a/include/users.h +++ b/include/users.h @@ -76,10 +76,12 @@ class CoreExport User : public Extensible /** Create a new user object, initialising necessary fields and * adds it to the hash * - * @param nick The nickname of the user. - * @param uid The unique identifier of the user. + * @param snick The nickname of the user. + * @param sident The username of the user + * @param shost The hostname of the user + * @param suid The unique identifier of the user. */ - User(const Anope::string &nick, const Anope::string &uid); + User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &suid); /** Destroy a user. */ diff --git a/modules/core/bs_act.cpp b/modules/core/bs_act.cpp index 34251cbb2..d52dbdb78 100644 --- a/modules/core/bs_act.cpp +++ b/modules/core/bs_act.cpp @@ -49,8 +49,10 @@ class CommandBSAct : public Command ircdproto->SendAction(ci->bi, ci->name, "%s", message.c_str()); ci->bi->lastmsg = time(NULL); - if (Config->LogBot && !Config->LogChannel.empty() && LogChan && !debug && findchan(Config->LogChannel)) - ircdproto->SendPrivmsg(ci->bi, Config->LogChannel, "ACT %s %s %s", u->nick.c_str(), ci->name.c_str(), message.c_str()); + + // XXX Need to be able to find if someone is overriding this. + Log(LOG_COMMAND, u, this, ci) << message; + return MOD_CONT; } diff --git a/modules/core/bs_assign.cpp b/modules/core/bs_assign.cpp index b1242c857..97b23c0ef 100644 --- a/modules/core/bs_assign.cpp +++ b/modules/core/bs_assign.cpp @@ -59,6 +59,9 @@ class CommandBSAssign : public Command return MOD_CONT; } + bool override = !check_access(u, ci, CA_ASSIGN); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "for " << bi->nick; + bi->Assign(u, ci); notice_lang(Config->s_BotServ, u, BOT_ASSIGN_ASSIGNED, bi->nick.c_str(), ci->name.c_str()); return MOD_CONT; diff --git a/modules/core/bs_badwords.cpp b/modules/core/bs_badwords.cpp index 46b38bf1d..c02ff6570 100644 --- a/modules/core/bs_badwords.cpp +++ b/modules/core/bs_badwords.cpp @@ -53,10 +53,14 @@ class BadwordsDelCallback : public NumberList { User *u; ChannelInfo *ci; + Command *c; unsigned Deleted; + bool override; public: - BadwordsDelCallback(User *_u, ChannelInfo *_ci, const Anope::string &list) : NumberList(list, true), u(_u), ci(_ci), Deleted(0) + BadwordsDelCallback(User *_u, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), u(_u), ci(_ci), c(_c), Deleted(0), override(false) { + if (!check_access(u, ci, CA_BADWORDS) && u->Account()->HasPriv("botserv/administration")) + this->override = true; } ~BadwordsDelCallback() @@ -74,6 +78,7 @@ class BadwordsDelCallback : public NumberList if (Number > ci->GetBadWordCount()) return; + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, c, ci) << "DEL " << ci->GetBadWord(Number -1 )->word; ++Deleted; ci->EraseBadWord(Number - 1); } @@ -84,6 +89,9 @@ class CommandBSBadwords : public Command private: CommandReturn DoList(User *u, ChannelInfo *ci, const Anope::string &word) { + bool override = !check_access(u, ci, CA_BADWORDS); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "LIST"; + if (!ci->GetBadWordCount()) notice_lang(Config->s_BotServ, u, BOT_BADWORDS_LIST_EMPTY, ci->name.c_str()); else if (!word.empty() && word.find_first_not_of("1234567890,-") == Anope::string::npos) @@ -156,6 +164,8 @@ class CommandBSBadwords : public Command } } + bool override = !check_access(u, ci, CA_BADWORDS); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << realword; ci->AddBadWord(realword, type); notice_lang(Config->s_BotServ, u, BOT_BADWORDS_ADDED, realword.c_str(), ci->name.c_str()); @@ -168,7 +178,7 @@ class CommandBSBadwords : public Command /* Special case: is it a number/list? Only do search if it isn't. */ if (!word.empty() && isdigit(word[0]) && word.find_first_not_of("1234567890,-") == Anope::string::npos) { - BadwordsDelCallback list(u, ci, word); + BadwordsDelCallback list(u, ci, this, word); list.Process(); } else @@ -190,6 +200,8 @@ class CommandBSBadwords : public Command return MOD_CONT; } + bool override = !check_access(u, ci, CA_BADWORDS); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << badword->word; ci->EraseBadWord(i); notice_lang(Config->s_BotServ, u, BOT_BADWORDS_DELETED, badword->word.c_str(), ci->name.c_str()); @@ -200,6 +212,9 @@ class CommandBSBadwords : public Command CommandReturn DoClear(User *u, ChannelInfo *ci) { + bool override = !check_access(u, ci, CA_BADWORDS); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR"; + ci->ClearBadWords(); notice_lang(Config->s_BotServ, u, BOT_BADWORDS_CLEAR); return MOD_CONT; diff --git a/modules/core/bs_bot.cpp b/modules/core/bs_bot.cpp index f001c81a4..5c96ac70c 100644 --- a/modules/core/bs_bot.cpp +++ b/modules/core/bs_bot.cpp @@ -95,10 +95,13 @@ class CommandBSBot : public Command if (!(bi = new BotInfo(nick, user, host, real))) { + // XXX this cant happen? notice_lang(Config->s_BotServ, u, BOT_BOT_CREATION_FAILED); return MOD_CONT; } + Log(LOG_ADMIN, u, this) << "ADD " << bi->GetMask() << " " << bi->realname; + notice_lang(Config->s_BotServ, u, BOT_BOT_ADDED, bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str()); FOREACH_MOD(I_OnBotCreate, OnBotCreate(bi)); @@ -260,6 +263,7 @@ class CommandBSBot : public Command } notice_lang(Config->s_BotServ, u, BOT_BOT_CHANGED, oldnick.c_str(), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str()); + Log(LOG_ADMIN, u, this) << "CHANGE " << oldnick << " to " << bi->GetMask() << " " << bi->realname; FOREACH_MOD(I_OnBotChange, OnBotChange(bi)); return MOD_CONT; @@ -294,6 +298,8 @@ class CommandBSBot : public Command XLine x(bi->nick); ircdproto->SendSQLineDel(&x); + Log(LOG_ADMIN, u, this) << "DEL " << bi->nick; + delete bi; notice_lang(Config->s_BotServ, u, BOT_BOT_DELETED, nick.c_str()); return MOD_CONT; diff --git a/modules/core/bs_kick.cpp b/modules/core/bs_kick.cpp index 849efb7d0..2ed3c8639 100644 --- a/modules/core/bs_kick.cpp +++ b/modules/core/bs_kick.cpp @@ -42,6 +42,9 @@ class CommandBSKick : public Command notice_help(Config->s_BotServ, u, BOT_NOT_ASSIGNED); else { + bool override = !check_access(u, ci, CA_SET); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << option << " " << value; + if (option.equals_ci("BADWORDS")) { if (value.equals_ci("ON")) @@ -54,7 +57,7 @@ class CommandBSKick : public Command if (!error.empty() || ci->ttb[TTB_BADWORDS] < 0) { /* leaving the debug behind since we might want to know what these are */ - Alog(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_BADWORDS]; + Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_BADWORDS]; /* reset the value back to 0 - TSL */ ci->ttb[TTB_BADWORDS] = 0; notice_lang(Config->s_BotServ, u, BOT_KICK_BAD_TTB, ttb.c_str()); @@ -85,7 +88,7 @@ class CommandBSKick : public Command ci->ttb[TTB_BOLDS] = convertTo(ttb, error, false); if (!error.empty() || ci->ttb[TTB_BOLDS] < 0) { - Alog(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_BOLDS]; + Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_BOLDS]; ci->ttb[TTB_BOLDS] = 0; notice_lang(Config->s_BotServ, u, BOT_KICK_BAD_TTB, ttb.c_str()); return MOD_CONT; @@ -118,7 +121,7 @@ class CommandBSKick : public Command ci->ttb[TTB_CAPS] = convertTo(ttb, error, false); if (!error.empty() || ci->ttb[TTB_CAPS] < 0) { - Alog(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_CAPS]; + Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_CAPS]; ci->ttb[TTB_CAPS] = 0; notice_lang(Config->s_BotServ, u, BOT_KICK_BAD_TTB, ttb.c_str()); return MOD_CONT; @@ -163,7 +166,7 @@ class CommandBSKick : public Command ci->ttb[TTB_COLORS] = convertTo(ttb, error, false); if (!error.empty() || ci->ttb[TTB_COLORS] < 0) { - Alog(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_COLORS]; + Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_COLORS]; ci->ttb[TTB_COLORS] = 0; notice_lang(Config->s_BotServ, u, BOT_KICK_BAD_TTB, ttb.c_str()); return MOD_CONT; @@ -196,7 +199,7 @@ class CommandBSKick : public Command ci->ttb[TTB_FLOOD] = convertTo(ttb, error, false); if (!error.empty() || ci->ttb[TTB_FLOOD] < 0) { - Alog(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_FLOOD]; + Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_FLOOD]; ci->ttb[TTB_FLOOD] = 0; notice_lang(Config->s_BotServ, u, BOT_KICK_BAD_TTB, ttb.c_str()); return MOD_CONT; @@ -243,7 +246,7 @@ class CommandBSKick : public Command ci->ttb[TTB_REPEAT] = convertTo(ttb, error, false); if (!error.empty() || ci->ttb[TTB_REPEAT] < 0) { - Alog(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_REPEAT]; + Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_REPEAT]; ci->ttb[TTB_REPEAT] = 0; notice_lang(Config->s_BotServ, u, BOT_KICK_BAD_TTB, ttb.c_str()); return MOD_CONT; @@ -281,7 +284,7 @@ class CommandBSKick : public Command ci->ttb[TTB_REVERSES] = convertTo(ttb, error, false); if (!error.empty() || ci->ttb[TTB_REVERSES] < 0) { - Alog(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_REVERSES]; + Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_REVERSES]; ci->ttb[TTB_REVERSES] = 0; notice_lang(Config->s_BotServ, u, BOT_KICK_BAD_TTB, ttb.c_str()); return MOD_CONT; @@ -311,7 +314,7 @@ class CommandBSKick : public Command ci->ttb[TTB_UNDERLINES] = convertTo(ttb, error, false); if (!error.empty() || ci->ttb[TTB_UNDERLINES] < 0) { - Alog(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_UNDERLINES]; + Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_UNDERLINES]; ci->ttb[TTB_UNDERLINES] = 0; notice_lang(Config->s_BotServ, u, BOT_KICK_BAD_TTB, ttb.c_str()); return MOD_CONT; @@ -341,7 +344,7 @@ class CommandBSKick : public Command ci->ttb[TTB_ITALICS] = convertTo(ttb, error, false); if (!error.empty() || ci->ttb[TTB_ITALICS] < 0) { - Alog(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_ITALICS]; + Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_ITALICS]; ci->ttb[TTB_ITALICS] = 0; notice_lang(Config->s_BotServ, u, BOT_KICK_BAD_TTB, ttb.c_str()); return MOD_CONT; diff --git a/modules/core/bs_say.cpp b/modules/core/bs_say.cpp index 1b799c415..916cf8fca 100644 --- a/modules/core/bs_say.cpp +++ b/modules/core/bs_say.cpp @@ -55,8 +55,10 @@ class CommandBSSay : public Command ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", text.c_str()); ci->bi->lastmsg = time(NULL); - if (Config->LogBot && !Config->LogChannel.empty() && LogChan && !debug && findchan(Config->LogChannel)) - ircdproto->SendPrivmsg(ci->bi, Config->LogChannel, "SAY %s %s %s", u->nick.c_str(), ci->name.c_str(), text.c_str()); + + // XXX need a way to find if someone is overriding this + Log(LOG_COMMAND, u, this, ci) << text; + return MOD_CONT; } diff --git a/modules/core/bs_set.cpp b/modules/core/bs_set.cpp index 87a15cf66..0ee46a0d5 100644 --- a/modules/core/bs_set.cpp +++ b/modules/core/bs_set.cpp @@ -64,6 +64,9 @@ class CommandBSSet : public Command notice_lang(Config->s_BotServ, u, ACCESS_DENIED); else { + bool override = !check_access(u, ci, CA_SET); + Log(override ? LOG_ADMIN : LOG_COMMAND, u, this, ci) << option << value; + if (option.equals_ci("DONTKICKOPS")) { if (value.equals_ci("ON")) diff --git a/modules/core/bs_unassign.cpp b/modules/core/bs_unassign.cpp index bde37f78e..6b6b28fe9 100644 --- a/modules/core/bs_unassign.cpp +++ b/modules/core/bs_unassign.cpp @@ -36,6 +36,9 @@ class CommandBSUnassign : public Command notice_help(Config->s_BotServ, u, BOT_UNASSIGN_PERSISTANT_CHAN); else { + bool override = !check_access(u, ci, CA_ASSIGN); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "for " << ci->bi->nick; + ci->bi->UnAssign(u, ci); notice_lang(Config->s_BotServ, u, BOT_UNASSIGN_UNASSIGNED, ci->name.c_str()); } diff --git a/modules/core/cs_access.cpp b/modules/core/cs_access.cpp index 5fea57486..c6714cf05 100644 --- a/modules/core/cs_access.cpp +++ b/modules/core/cs_access.cpp @@ -108,12 +108,16 @@ class AccessDelCallback : public NumberList { User *u; ChannelInfo *ci; + Command *c; unsigned Deleted; Anope::string Nicks; bool Denied; + bool override; public: - AccessDelCallback(User *_u, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, true), u(_u), ci(_ci), Deleted(0), Denied(false) + AccessDelCallback(User *_u, ChannelInfo *_ci, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), u(_u), ci(_ci), c(_c), Deleted(0), Denied(false) { + if (!check_access(u, ci, CA_ACCESS_CHANGE) && u->Account()->HasPriv("chanserv/access/modify")) + this->override = true; } ~AccessDelCallback() @@ -124,7 +128,7 @@ class AccessDelCallback : public NumberList notice_lang(Config->s_ChanServ, u, CHAN_ACCESS_NO_MATCH, ci->name.c_str()); else { - Alog() << Config->s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) << ") deleted access of user" << (Deleted == 1 ? " " : "s ") << Nicks << " on " << ci->name; + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, c, ci) << "for user" << (Deleted == 1 ? " " : "s ") << Nicks; if (Deleted == 1) notice_lang(Config->s_ChanServ, u, CHAN_ACCESS_DELETED_ONE, ci->name.c_str()); @@ -183,6 +187,8 @@ class CommandCSAccess : public Command return MOD_CONT; } + bool override = !check_access(u, ci, CA_ACCESS_CHANGE) || level >= ulev; + NickAlias *na = findnick(nick); if (!na) { @@ -214,7 +220,7 @@ class CommandCSAccess : public Command FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na->nc, level)); - Alog() << Config->s_ChanServ << ": " << u->GetMask() << " (level " << ulev << ") set access level " << access->level << " to " << na->nick << " (group " << nc->display << ") on channel " << ci->name; + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << na->nick << "(group: " << nc->display << ") as level " << ulev; notice_lang(Config->s_ChanServ, u, CHAN_ACCESS_LEVEL_CHANGED, nc->display.c_str(), ci->name.c_str(), level); return MOD_CONT; } @@ -229,7 +235,7 @@ class CommandCSAccess : public Command FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, nc, level)); - Alog() << Config->s_ChanServ << ": " << u->GetMask() << " (level " << ulev << ") set access level " << level << " to " << na->nick << " (group " << nc->display << ") on channel " << ci->name; + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << na->nick << "(group: " << nc->display << ") as level " << ulev; notice_lang(Config->s_ChanServ, u, CHAN_ACCESS_ADDED, nc->display.c_str(), ci->name.c_str(), level); return MOD_CONT; @@ -243,7 +249,7 @@ class CommandCSAccess : public Command notice_lang(Config->s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, ci->name.c_str()); else if (isdigit(nick[0]) && nick.find_first_not_of("1234567890,-") == Anope::string::npos) { - AccessDelCallback list(u, ci, nick); + AccessDelCallback list(u, ci, this, nick); list.Process(); } else @@ -274,7 +280,9 @@ class CommandCSAccess : public Command else { notice_lang(Config->s_ChanServ, u, CHAN_ACCESS_DELETED, access->nc->display.c_str(), ci->name.c_str()); - Alog() << Config->s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) << ") deleted access of " << na->nick << " (group " << access->nc->display << ") on " << ci->name; + bool override = !check_access(u, ci, CA_ACCESS_CHANGE); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << na->nick << "(group: " << access->nc->display << ") from level " << access->level; + FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, na->nc)); ci->EraseAccess(i); @@ -375,7 +383,9 @@ class CommandCSAccess : public Command FOREACH_MOD(I_OnAccessClear, OnAccessClear(ci, u)); notice_lang(Config->s_ChanServ, u, CHAN_ACCESS_CLEAR, ci->name.c_str()); - Alog() << Config->s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) << " cleared access list on " << ci->name; + + bool override = !IsFounder(u, ci); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR"; } return MOD_CONT; @@ -471,7 +481,10 @@ class CommandCSLevels : public Command { ci->levels[levelinfo[i].what] = level; FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, level)); - Alog() << Config->s_ChanServ << ": " << u->GetMask() << " set level " << levelinfo[i].name << " on channel " << ci->name << " to " << level; + + bool override = !check_access(u, ci, CA_FOUNDER); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "SET " << levelinfo[i].name << " to " << level; + if (level == ACCESS_FOUNDER) notice_lang(Config->s_ChanServ, u, CHAN_LEVELS_CHANGED_FOUNDER, levelinfo[i].name.c_str(), ci->name.c_str()); else @@ -498,7 +511,9 @@ class CommandCSLevels : public Command ci->levels[levelinfo[i].what] = ACCESS_INVALID; FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, levelinfo[i].what)); - Alog() << Config->s_ChanServ << ": " << u->GetMask() << " disabled level " << levelinfo[i].name << " on channel " << ci->name; + bool override = !check_access(u, ci, CA_FOUNDER); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DISABLE " << levelinfo[i].name; + notice_lang(Config->s_ChanServ, u, CHAN_LEVELS_DISABLED, levelinfo[i].name.c_str(), ci->name.c_str()); return MOD_CONT; } @@ -547,7 +562,10 @@ class CommandCSLevels : public Command { reset_levels(ci); FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, -1, 0)); - Alog() << Config->s_ChanServ << ": " << u->GetMask() << " reset levels definitions on channel " << ci->name; + + bool override = !check_access(u, ci, CA_FOUNDER); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "RESET"; + notice_lang(Config->s_ChanServ, u, CHAN_LEVELS_RESET, ci->name.c_str()); return MOD_CONT; } diff --git a/modules/core/cs_akick.cpp b/modules/core/cs_akick.cpp index c3d3c77b5..5df1a9038 100644 --- a/modules/core/cs_akick.cpp +++ b/modules/core/cs_akick.cpp @@ -138,14 +138,18 @@ class AkickDelCallback : public NumberList { User *u; ChannelInfo *ci; + Command *c; unsigned Deleted; public: - AkickDelCallback(User *_u, ChannelInfo *_ci, const Anope::string &list) : NumberList(list, true), u(_u), ci(_ci), Deleted(0) + AkickDelCallback(User *_u, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), u(_u), ci(_ci), c(_c), Deleted(0) { } ~AkickDelCallback() { + bool override = !check_access(u, ci, CA_AKICK); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, c, ci) << "DEL on " << Deleted << " users"; + if (!Deleted) notice_lang(Config->s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str()); else if (Deleted == 1) @@ -266,6 +270,9 @@ class CommandCSAKick : public Command else akick = ci->AddAkick(u->nick, mask, reason); + bool override = !check_access(u, ci, CA_AKICK); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask << ": " << reason; + FOREACH_MOD(I_OnAkickAdd, OnAkickAdd(u, ci, akick)); notice_lang(Config->s_ChanServ, u, CHAN_AKICK_ADDED, mask.c_str(), ci->name.c_str()); @@ -306,6 +313,9 @@ class CommandCSAKick : public Command return; } + bool override = !check_access(u, ci, CA_AKICK); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "STICK " << akick->mask; + akick->SetFlag(AK_STUCK); notice_lang(Config->s_ChanServ, u, CHAN_AKICK_STUCK, akick->mask.c_str(), ci->name.c_str()); @@ -346,6 +356,9 @@ class CommandCSAKick : public Command return; } + bool override = !check_access(u, ci, CA_AKICK); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "UNSTICK " << akick->mask; + akick->UnsetFlag(AK_STUCK); notice_lang(Config->s_ChanServ, u, CHAN_AKICK_UNSTUCK, akick->mask.c_str(), ci->name.c_str()); } @@ -365,7 +378,7 @@ class CommandCSAKick : public Command /* Special case: is it a number/list? Only do search if it isn't. */ if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos) { - AkickDelCallback list(u, ci, mask); + AkickDelCallback list(u, ci, this, mask); list.Process(); } else @@ -387,6 +400,9 @@ class CommandCSAKick : public Command return; } + bool override = !check_access(u, ci, CA_AKICK); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << mask; + ci->EraseAkick(i); notice_lang(Config->s_ChanServ, u, CHAN_AKICK_DELETED, mask.c_str(), ci->name.c_str()); @@ -397,6 +413,9 @@ class CommandCSAKick : public Command { Anope::string mask = params.size() > 2 ? params[2] : ""; + bool override = !check_access(u, ci, CA_AKICK); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "LIST"; + if (!ci->GetAkickCount()) { notice_lang(Config->s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, ci->name.c_str()); @@ -442,6 +461,9 @@ class CommandCSAKick : public Command { Anope::string mask = params.size() > 2 ? params[2] : ""; + bool override = !check_access(u, ci, CA_AKICK); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "VIEW"; + if (!ci->GetAkickCount()) { notice_lang(Config->s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, ci->name.c_str()); @@ -502,11 +524,17 @@ class CommandCSAKick : public Command ++count; } + bool override = !check_access(u, ci, CA_AKICK); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ENFORCE, affects " << count << " users"; + notice_lang(Config->s_ChanServ, u, CHAN_AKICK_ENFORCE_DONE, ci->name.c_str(), count); } void DoClear(User *u, ChannelInfo *ci) { + bool override = !check_access(u, ci, CA_AKICK); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR"; + ci->ClearAkick(); notice_lang(Config->s_ChanServ, u, CHAN_AKICK_CLEAR, ci->name.c_str()); } diff --git a/modules/core/cs_ban.cpp b/modules/core/cs_ban.cpp index 500db20f5..fcc11d393 100644 --- a/modules/core/cs_ban.cpp +++ b/modules/core/cs_ban.cpp @@ -56,8 +56,11 @@ class CommandCSBan : public Command else { Anope::string mask; - get_idealban(ci, u2, mask); + + // XXX need a way to detect if someone is overriding + Log(LOG_COMMAND, u, this, ci) << "for " << mask; + c->SetMode(NULL, CMODE_BAN, mask); /* We still allow host banning while not allowing to kick */ diff --git a/modules/core/cs_clear.cpp b/modules/core/cs_clear.cpp index 42a9bd53a..1fa61fc56 100644 --- a/modules/core/cs_clear.cpp +++ b/modules/core/cs_clear.cpp @@ -34,9 +34,13 @@ class CommandCSClear : public Command ChannelMode *halfop = ModeManager::FindChannelModeByName(CMODE_HALFOP); ChannelMode *voice = ModeManager::FindChannelModeByName(CMODE_VOICE); + if (c) + // XXX + Log(LOG_COMMAND, u, this, ci) << what; + if (!c) notice_lang(Config->s_ChanServ, u, CHAN_X_NOT_IN_USE, chan.c_str()); - else if (!u || !check_access(u, ci, CA_CLEAR)) + else if (!check_access(u, ci, CA_CLEAR)) notice_lang(Config->s_ChanServ, u, ACCESS_DENIED); else if (what.equals_ci("bans")) { diff --git a/modules/core/cs_drop.cpp b/modules/core/cs_drop.cpp index 608fe3664..4ac066927 100644 --- a/modules/core/cs_drop.cpp +++ b/modules/core/cs_drop.cpp @@ -53,8 +53,6 @@ class CommandCSDrop : public Command return MOD_CONT; } - int level = get_access(u, ci); - if (ci->c && ModeManager::FindChannelModeByName(CMODE_REGISTERED)) ci->c->RemoveMode(NULL, CMODE_REGISTERED, "", false); @@ -64,16 +62,13 @@ class CommandCSDrop : public Command ircdproto->SendSQLineDel(&x); } - Alog() << Config->s_ChanServ << ": Channel " << ci->name << " dropped by " << u->GetMask() << " (founder: " << (ci->founder ? ci->founder->display : "(none)") << ")"; + bool override = (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "founder: " << (ci->founder ? ci->founder->display : "none"); + if (override) + ircdproto->SendGlobops(ChanServ, "\2%s\2 used DROP on channel \2%s\2", u->nick.c_str(), ci->name.c_str()); delete ci; - /* We must make sure that the Services admin has not normally the right to - * drop the channel before issuing the wallops. - */ - if (Config->WallDrop && (level < ACCESS_FOUNDER || (!IsFounder(u, ci) && ci->HasFlag(CI_SECUREFOUNDER)))) - ircdproto->SendGlobops(ChanServ, "\2%s\2 used DROP on channel \2%s\2", u->nick.c_str(), chan.c_str()); - notice_lang(Config->s_ChanServ, u, CHAN_DROPPED, chan.c_str()); FOREACH_MOD(I_OnChanDrop, OnChanDrop(chan)); diff --git a/modules/core/cs_forbid.cpp b/modules/core/cs_forbid.cpp index 09fddd091..706d5e4a8 100644 --- a/modules/core/cs_forbid.cpp +++ b/modules/core/cs_forbid.cpp @@ -53,7 +53,8 @@ class CommandCSForbid : public Command ci = new ChannelInfo(chan); if (!ci) { - Alog() << Config->s_ChanServ << ": Valid FORBID for " << ci->name << " by " << u->nick << " failed"; + // this cant happen? + //Alog() << Config->s_ChanServ << ": Valid FORBID for " << ci->name << " by " << u->nick << " failed"; notice_lang(Config->s_ChanServ, u, CHAN_FORBID_FAILED, chan.c_str()); return MOD_CONT; } @@ -80,16 +81,16 @@ class CommandCSForbid : public Command } } - if (Config->WallForbid) - ircdproto->SendGlobops(ChanServ, "\2%s\2 used FORBID on channel \2%s\2", u->nick.c_str(), ci->name.c_str()); - if (ircd->chansqline) { XLine x(chan, "Forbidden"); ircdproto->SendSQLine(&x); } - Alog() << Config->s_ChanServ << ": " << u->nick << " set FORBID for channel " << ci->name; + if (Config->WallForbid) + ircdproto->SendGlobops(ChanServ, "\2%s\2 used FORBID on channel \2%s\2", u->nick.c_str(), ci->name.c_str()); + Log(LOG_ADMIN, u, this, ci) << (!ci->forbidreason.empty() ? ci->forbidreason : "No reason"); + notice_lang(Config->s_ChanServ, u, CHAN_FORBID_SUCCEEDED, chan.c_str()); FOREACH_MOD(I_OnChanForbidden, OnChanForbidden(ci)); diff --git a/modules/core/cs_getkey.cpp b/modules/core/cs_getkey.cpp index c39000ea3..a3e80b424 100644 --- a/modules/core/cs_getkey.cpp +++ b/modules/core/cs_getkey.cpp @@ -40,6 +40,9 @@ class CommandCSGetKey : public Command return MOD_CONT; } + bool override = !check_access(u, ci, CA_GETKEY); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci); + notice_lang(Config->s_ChanServ, u, CHAN_GETKEY_KEY, chan.c_str(), key.c_str()); return MOD_CONT; } diff --git a/modules/core/cs_invite.cpp b/modules/core/cs_invite.cpp index 926375b3e..c841627a9 100644 --- a/modules/core/cs_invite.cpp +++ b/modules/core/cs_invite.cpp @@ -35,7 +35,7 @@ class CommandCSInvite : public Command ci = c->ci; - if (!u || !check_access(u, ci, CA_INVITE)) + if (!check_access(u, ci, CA_INVITE)) { notice_lang(Config->s_ChanServ, u, ACCESS_DENIED); return MOD_CONT; @@ -52,6 +52,9 @@ class CommandCSInvite : public Command } } + // XXX need a check for override... + Log(LOG_COMMAND, u, this, ci) << "for " << u2->nick; + if (c->FindUser(u2)) notice_lang(Config->s_ChanServ, u, CHAN_INVITE_ALREADY_IN, c->name.c_str()); else diff --git a/modules/core/cs_kick.cpp b/modules/core/cs_kick.cpp index 06f0004b8..4deb19b13 100644 --- a/modules/core/cs_kick.cpp +++ b/modules/core/cs_kick.cpp @@ -51,6 +51,9 @@ class CommandCSKick : public Command notice_lang(Config->s_ChanServ, u, NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str()); else { + // XXX + Log(LOG_COMMAND, u, this, ci) << "for " << u2->nick; + if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !check_access(u, ci, CA_SIGNKICK))) ci->c->Kick(whosends(ci), u2, "%s (%s)", reason.c_str(), u->nick.c_str()); else diff --git a/modules/core/cs_modes.cpp b/modules/core/cs_modes.cpp index 274c7e5af..54bc09d11 100644 --- a/modules/core/cs_modes.cpp +++ b/modules/core/cs_modes.cpp @@ -15,6 +15,7 @@ /** do_util: not a command, but does the job of others * @param u The user doing the command + * @param com The command calling this function * @param cm A channel mode class * @param chan The channel its being set on * @param nick The nick the modes being set on @@ -24,22 +25,14 @@ * @param name The name, eg "OP" or "HALFOP" * @param notice Flag required on a channel to send a notice */ -static CommandReturn do_util(User *u, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, int level, int levelself, const Anope::string &name, ChannelInfoFlag notice) +static CommandReturn do_util(User *u, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, int level, int levelself, const Anope::string &name, ChannelInfoFlag notice) { Channel *c = findchan(chan); - ChannelInfo *ci; + ChannelInfo *ci = c ? c->ci : NULL; User *u2; - Anope::string realnick = nick; - int is_same; - - if (realnick.empty()) - realnick = u->nick; - - is_same = u->nick.equals_cs(realnick) ? 1 : u->nick.equals_ci(realnick); - - if (c) - ci = c->ci; + Anope::string realnick = (!nick.empty() ? nick : u->nick); + bool is_same = u->nick.equals_ci(realnick); if (!c) notice_lang(Config->s_ChanServ, u, CHAN_X_NOT_IN_USE, chan.c_str()); @@ -60,6 +53,7 @@ static CommandReturn do_util(User *u, ChannelMode *cm, const Anope::string &chan else c->RemoveMode(NULL, cm, u2->nick); + Log(LOG_COMMAND, u, com, ci) << "for " << u2->nick; if (notice && ci->HasFlag(notice)) ircdproto->SendMessage(whosends(ci), c->name, "%s command used for %s by %s", name.c_str(), u2->nick.c_str(), u->nick.c_str()); } @@ -78,7 +72,7 @@ class CommandCSOp : public Command { ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP); - return do_util(u, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_OPDEOP, CA_OPDEOPME, "OP", CI_OPNOTICE); + return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", true, CA_OPDEOP, CA_OPDEOPME, "OP", CI_OPNOTICE); } bool OnHelp(User *u, const Anope::string &subcommand) @@ -109,7 +103,7 @@ class CommandCSDeOp : public Command { ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP); - return do_util(u, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_OPDEOP, CA_OPDEOPME, "DEOP", CI_OPNOTICE); + return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", false, CA_OPDEOP, CA_OPDEOPME, "DEOP", CI_OPNOTICE); } bool OnHelp(User *u, const Anope::string &subcommand) @@ -140,7 +134,7 @@ class CommandCSVoice : public Command { ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE); - return do_util(u, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_VOICE, CA_VOICEME, "VOICE", CI_BEGIN); + return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", true, CA_VOICE, CA_VOICEME, "VOICE", CI_BEGIN); } bool OnHelp(User *u, const Anope::string &subcommand) @@ -171,7 +165,7 @@ class CommandCSDeVoice : public Command { ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE); - return do_util(u, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_VOICE, CA_VOICEME, "DEVOICE", CI_BEGIN); + return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", false, CA_VOICE, CA_VOICEME, "DEVOICE", CI_BEGIN); } bool OnHelp(User *u, const Anope::string &subcommand) @@ -207,7 +201,7 @@ class CommandCSHalfOp : public Command return MOD_CONT; } - return do_util(u, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_HALFOP, CA_HALFOPME, "HALFOP", CI_BEGIN); + return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", true, CA_HALFOP, CA_HALFOPME, "HALFOP", CI_BEGIN); } bool OnHelp(User *u, const Anope::string &subcommand) @@ -241,7 +235,7 @@ class CommandCSDeHalfOp : public Command if (!cm) return MOD_CONT; - return do_util(u, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_HALFOP, CA_HALFOPME, "DEHALFOP", CI_BEGIN); + return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", false, CA_HALFOP, CA_HALFOPME, "DEHALFOP", CI_BEGIN); } bool OnHelp(User *u, const Anope::string &subcommand) @@ -275,7 +269,7 @@ class CommandCSProtect : public Command if (!cm) return MOD_CONT; - return do_util(u, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_PROTECT, CA_PROTECTME, "PROTECT", CI_BEGIN); + return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", true, CA_PROTECT, CA_PROTECTME, "PROTECT", CI_BEGIN); } bool OnHelp(User *u, const Anope::string &subcommand) @@ -309,7 +303,7 @@ class CommandCSDeProtect : public Command if (!cm) return MOD_CONT; - return do_util(u, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_PROTECT, CA_PROTECTME, "DEPROTECT", CI_BEGIN); + return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", false, CA_PROTECT, CA_PROTECTME, "DEPROTECT", CI_BEGIN); } bool OnHelp(User *u, const Anope::string &subcommand) @@ -343,7 +337,7 @@ class CommandCSOwner : public Command if (!cm) return MOD_CONT; - return do_util(u, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_OWNER, CA_OWNERME, "OWNER", CI_BEGIN); + return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", true, CA_OWNER, CA_OWNERME, "OWNER", CI_BEGIN); } bool OnHelp(User *u, const Anope::string &subcommand) @@ -377,7 +371,7 @@ class CommandCSDeOwner : public Command if (!cm) return MOD_CONT; - return do_util(u, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_OWNER, CA_OWNERME, "DEOWNER", CI_BEGIN); + return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", false, CA_OWNER, CA_OWNERME, "DEOWNER", CI_BEGIN); } bool OnHelp(User *u, const Anope::string &subcommand) diff --git a/modules/core/cs_register.cpp b/modules/core/cs_register.cpp index 70a436fa5..545f3f5a1 100644 --- a/modules/core/cs_register.cpp +++ b/modules/core/cs_register.cpp @@ -49,16 +49,12 @@ class CommandCSRegister : public Command notice_lang(Config->s_ChanServ, u, u->Account()->channelcount > Config->CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, Config->CSMaxReg); else if (!(ci = new ChannelInfo(chan))) { - Alog() << Config->s_ChanServ << ": makechan() failed for REGISTER " << chan; + // not possible ? + //Alog() << Config->s_ChanServ << ": makechan() failed for REGISTER " << chan; notice_lang(Config->s_ChanServ, u, CHAN_REGISTRATION_FAILED); } else { - if (c) - { - c->ci = ci; - ci->c = c; - } ci->founder = u->Account(); ci->desc = desc; @@ -73,7 +69,7 @@ class CommandCSRegister : public Command ci->bi = NULL; ++ci->founder->channelcount; - Alog() << Config->s_ChanServ << ": Channel '" << chan << "' registered by " << u->GetMask(); + Log(LOG_COMMAND, u, this, ci); notice_lang(Config->s_ChanServ, u, CHAN_REGISTERED, chan.c_str(), u->nick.c_str()); /* Implement new mode lock */ diff --git a/modules/core/cs_saset.cpp b/modules/core/cs_saset.cpp index 61ae2f299..923848e7a 100644 --- a/modules/core/cs_saset.cpp +++ b/modules/core/cs_saset.cpp @@ -40,9 +40,11 @@ class CommandCSSASet : public Command if (c) { - Anope::string cmdparams = cs_findchan(params[0])->name; + ChannelInfo *ci = cs_findchan(params[0]); + Anope::string cmdparams = ci->name; for (std::vector::const_iterator it = params.begin() + 2, it_end = params.end(); it != it_end; ++it) cmdparams += " " + *it; + Log(LOG_ADMIN, u, this, ci) << params[1] << " " << cmdparams; mod_run_cmd(ChanServ, u, c, params[1], cmdparams); } else diff --git a/modules/core/cs_set.cpp b/modules/core/cs_set.cpp index dd2063ffe..ede39c3c7 100644 --- a/modules/core/cs_set.cpp +++ b/modules/core/cs_set.cpp @@ -45,7 +45,8 @@ class CommandCSSet : public Command if (c) { - Anope::string cmdparams = cs_findchan(params[0])->name; + ChannelInfo *ci = cs_findchan(params[0]); + Anope::string cmdparams = ci->name; for (std::vector::const_iterator it = params.begin() + 2, it_end = params.end(); it != it_end; ++it) cmdparams += " " + *it; mod_run_cmd(ChanServ, u, c, params[1], cmdparams); diff --git a/modules/core/cs_set_founder.cpp b/modules/core/cs_set_founder.cpp index b6af6220a..ee955d590 100644 --- a/modules/core/cs_set_founder.cpp +++ b/modules/core/cs_set_founder.cpp @@ -53,7 +53,7 @@ class CommandCSSetFounder : public Command return MOD_CONT; } - Alog() << Config->s_ChanServ << ": Changing founder of " << ci->name << " from " << ci->founder->display << " to " << nc->display << " by " << u->GetMask(); + Log(!this->permission.empty() ? LOG_ADMIN : LOG_COMMAND, u, this, ci) << "to change the founder to " << nc->display; /* Founder and successor must not be the same group */ if (nc == ci->successor) diff --git a/modules/core/cs_set_successor.cpp b/modules/core/cs_set_successor.cpp index 7478651c4..b4e0972c6 100644 --- a/modules/core/cs_set_successor.cpp +++ b/modules/core/cs_set_successor.cpp @@ -58,7 +58,7 @@ class CommandCSSetSuccessor : public Command else nc = NULL; - Alog() << Config->s_ChanServ << ": Changing successor of " << ci->name << " from " << (ci->successor ? ci->successor->display : "none") << " to " << (nc ? nc->display : "none") << " by " << u->GetMask(); + Log(!this->permission.empty() ? LOG_ADMIN : LOG_COMMAND, u, this, ci) << "to change the successor from " << (ci->successor ? ci->successor->display : "none") << " to " << (nc ? nc->display : "none"); ci->successor = nc; diff --git a/modules/core/cs_set_xop.cpp b/modules/core/cs_set_xop.cpp index 18e4df76d..e08b014a1 100644 --- a/modules/core/cs_set_xop.cpp +++ b/modules/core/cs_set_xop.cpp @@ -64,14 +64,14 @@ class CommandCSSetXOP : public Command ci->SetFlag(CI_XOP); } - Alog() << Config->s_ChanServ << ": " << u->GetMask() << " enabled XOP for " << ci->name; + Log(LOG_COMMAND, u, this, ci) << "to enable XOP"; notice_lang(Config->s_ChanServ, u, CHAN_SET_XOP_ON, ci->name.c_str()); } else if (params[1].equals_ci("OFF")) { ci->UnsetFlag(CI_XOP); - Alog() << Config->s_ChanServ << ": " << u->GetMask() << " disabled XOP for " << ci->name; + Log(LOG_COMMAND, u, this, ci) << "to disable XOP"; notice_lang(Config->s_ChanServ, u, CHAN_SET_XOP_OFF, ci->name.c_str()); } else diff --git a/modules/core/cs_suspend.cpp b/modules/core/cs_suspend.cpp index 7af933a69..055b8b0e7 100644 --- a/modules/core/cs_suspend.cpp +++ b/modules/core/cs_suspend.cpp @@ -74,14 +74,15 @@ class CommandCSSuspend : public Command if (Config->WallForbid) ircdproto->SendGlobops(ChanServ, "\2%s\2 used SUSPEND on channel \2%s\2", u->nick.c_str(), ci->name.c_str()); - Alog() << Config->s_ChanServ << ": " << u->GetMask() << " set SUSPEND for channel " << ci->name; + Log(LOG_ADMIN, u, this, ci) << (!reason.empty() ? reason : "No reason"); notice_lang(Config->s_ChanServ, u, CHAN_SUSPEND_SUCCEEDED, chan.c_str()); FOREACH_MOD(I_OnChanSuspend, OnChanSuspend(ci)); } else { - Alog() << Config->s_ChanServ << ": Valid SUSPEND for " << ci->name << " by " << u->GetMask() << " failed"; + // cant happen? + //Alog() << Config->s_ChanServ << ": Valid SUSPEND for " << ci->name << " by " << u->GetMask() << " failed"; notice_lang(Config->s_ChanServ, u, CHAN_SUSPEND_FAILED, chan.c_str()); } return MOD_CONT; @@ -134,6 +135,8 @@ class CommandCSUnSuspend : public Command if (ci) { + Log(LOG_ADMIN, u, this, ci) << " was suspended for: " << (!ci->forbidreason.empty() ? ci->forbidreason : "No reason"); + ci->UnsetFlag(CI_SUSPENDED); ci->forbidreason.clear(); ci->forbidby.clear(); @@ -141,14 +144,14 @@ class CommandCSUnSuspend : public Command if (Config->WallForbid) ircdproto->SendGlobops(ChanServ, "\2%s\2 used UNSUSPEND on channel \2%s\2", u->nick.c_str(), ci->name.c_str()); - Alog() << Config->s_ChanServ << ": " << u->GetMask() << " set UNSUSPEND for channel " << ci->name; notice_lang(Config->s_ChanServ, u, CHAN_UNSUSPEND_SUCCEEDED, chan.c_str()); FOREACH_MOD(I_OnChanUnsuspend, OnChanUnsuspend(ci)); } else { - Alog() << Config->s_ChanServ << ": Valid UNSUSPEND for " << chan << " by " << u->nick << " failed"; + // cant happen ? + //Alog() << Config->s_ChanServ << ": Valid UNSUSPEND for " << chan << " by " << u->nick << " failed"; notice_lang(Config->s_ChanServ, u, CHAN_UNSUSPEND_FAILED, chan.c_str()); } return MOD_CONT; diff --git a/modules/core/cs_topic.cpp b/modules/core/cs_topic.cpp index 5a421e272..ebd09b385 100644 --- a/modules/core/cs_topic.cpp +++ b/modules/core/cs_topic.cpp @@ -25,11 +25,8 @@ class CommandCSTopic : public Command Anope::string chan = params[0]; Anope::string topic = params.size() > 1 ? params[1] : ""; - Channel *c; - ChannelInfo *ci; - - if ((c = findchan(chan))) - ci = c->ci; + ChannelInfo *ci = cs_findchan(params[0]); + Channel *c = ci->c; if (!c) notice_lang(Config->s_ChanServ, u, CHAN_X_NOT_IN_USE, chan.c_str()); @@ -48,9 +45,10 @@ class CommandCSTopic : public Command else c->topic_time = ci->last_topic_time; - if (!check_access(u, ci, CA_TOPIC)) - Alog() << Confi