diff --git a/extensions/m_remove.c b/extensions/m_remove.c index e9a3e6460..9321e37a0 100644 --- a/extensions/m_remove.c +++ b/extensions/m_remove.c @@ -114,7 +114,7 @@ m_remove(struct Client *client_p, struct Client *source_p, int parc, const char return 0; } - if(get_channel_access(source_p, msptr, MODE_ADD) < CHFL_CHANOP) + if(get_channel_access(source_p, msptr, MODE_ADD, NULL) < CHFL_CHANOP) { if(MyConnect(source_p)) { diff --git a/extensions/override.c b/extensions/override.c index 3bdf4bd39..36ed1dc8e 100644 --- a/extensions/override.c +++ b/extensions/override.c @@ -164,8 +164,10 @@ hack_channel_access(void *vdata) update_session_deadline(data->client, NULL); data->approved = CHFL_CHANOP; - sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s is using oper-override on %s (modehacking)", - get_oper_name(data->client), data->chptr->chname); + /* we only want to report modehacks, which are always non-NULL */ + if (data->modestr) + sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s is using oper-override on %s (modehacking: %s)", + get_oper_name(data->client), data->chptr->chname, data->modestr); } } diff --git a/include/channel.h b/include/channel.h index 2297bf360..9cf000238 100644 --- a/include/channel.h +++ b/include/channel.h @@ -275,7 +275,7 @@ extern int match_extban(const char *banstr, struct Client *client_p, struct Chan extern int valid_extban(const char *banstr, struct Client *client_p, struct Channel *chptr, long mode_type); const char * get_extban_string(void); -extern int get_channel_access(struct Client *source_p, struct membership *msptr, int dir); +extern int get_channel_access(struct Client *source_p, struct membership *msptr, int dir, const char *modestr); extern void send_channel_join(struct Channel *chptr, struct Client *client_p); diff --git a/include/hook.h b/include/hook.h index 70d1b5ad1..5d768c8d5 100644 --- a/include/hook.h +++ b/include/hook.h @@ -85,6 +85,7 @@ typedef struct struct Client *target; int approved; int dir; + const char *modestr; } hook_data_channel_approval; typedef struct diff --git a/ircd/chmode.c b/ircd/chmode.c index 4cf3cb5c6..f63e74e5f 100644 --- a/ircd/chmode.c +++ b/ircd/chmode.c @@ -43,6 +43,7 @@ #include "logger.h" #include "chmode.h" #include "s_assert.h" +#include "parse.h" /* bitmasks for error returns, so we send once per call */ #define SM_ERR_NOTS 0x00000001 /* No TS on channel */ @@ -179,7 +180,7 @@ cflag_orphan(char c_) } int -get_channel_access(struct Client *source_p, struct membership *msptr, int dir) +get_channel_access(struct Client *source_p, struct membership *msptr, int dir, const char *modestr) { hook_data_channel_approval moduledata; @@ -195,6 +196,7 @@ get_channel_access(struct Client *source_p, struct membership *msptr, int dir) moduledata.target = NULL; moduledata.approved = is_chanop(msptr) ? CHFL_CHANOP : CHFL_PEON; moduledata.dir = dir; + moduledata.modestr = modestr; call_hook(h_get_channel_access, &moduledata); @@ -519,7 +521,7 @@ check_forward(struct Client *source_p, struct Channel *chptr, if(MyClient(source_p) && !(targptr->mode.mode & MODE_FREETARGET)) { if((msptr = find_channel_membership(targptr, source_p)) == NULL || - get_channel_access(source_p, msptr, MODE_QUERY) != CHFL_CHANOP) + get_channel_access(source_p, msptr, MODE_QUERY, NULL) != CHFL_CHANOP) { sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), me.name, source_p->name, targptr->chname); @@ -1655,7 +1657,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p, else fakesource_p = source_p; - alevel = get_channel_access(source_p, msptr, dir); + alevel = get_channel_access(source_p, msptr, dir, reconstruct_parv(parc, parv)); for(; (c = *ml) != 0; ml++) { @@ -1665,7 +1667,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p, dir = MODE_ADD; if (!reauthorized) { - alevel = get_channel_access(source_p, msptr, dir); + alevel = get_channel_access(source_p, msptr, dir, reconstruct_parv(parc, parv)); reauthorized = 1; } break; @@ -1673,7 +1675,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p, dir = MODE_DEL; if (!reauthorized) { - alevel = get_channel_access(source_p, msptr, dir); + alevel = get_channel_access(source_p, msptr, dir, reconstruct_parv(parc, parv)); reauthorized = 1; } break; diff --git a/modules/core/m_kick.c b/modules/core/m_kick.c index 387534612..8473ae378 100644 --- a/modules/core/m_kick.c +++ b/modules/core/m_kick.c @@ -97,7 +97,7 @@ m_kick(struct Client *client_p, struct Client *source_p, int parc, const char *p return 0; } - if(get_channel_access(source_p, msptr, MODE_ADD) < CHFL_CHANOP) + if(get_channel_access(source_p, msptr, MODE_ADD, NULL) < CHFL_CHANOP) { if(MyConnect(source_p)) { diff --git a/modules/m_topic.c b/modules/m_topic.c index b59378a3e..c2c37f855 100644 --- a/modules/m_topic.c +++ b/modules/m_topic.c @@ -119,7 +119,7 @@ m_topic(struct Client *client_p, struct Client *source_p, int parc, const char * } if(((chptr->mode.mode & MODE_TOPICLIMIT) == 0 || - get_channel_access(source_p, msptr, MODE_ADD) >= CHFL_CHANOP) && + get_channel_access(source_p, msptr, MODE_ADD, NULL) >= CHFL_CHANOP) && (!MyClient(source_p) || can_send(chptr, source_p, msptr))) {