diff --git a/include/modules.h b/include/modules.h index d8dddf0b4..a56b75266 100644 --- a/include/modules.h +++ b/include/modules.h @@ -1146,8 +1146,8 @@ extern void SavePersistentLongX(ModuleInfo *modinfo, const char *varshortname, l #define HOOKTYPE_SEE_CHANNEL_IN_WHOIS 77 /** See hooktype_join_data() */ #define HOOKTYPE_JOIN_DATA 78 -/** See hooktype_oper_invite_ban() */ -#define HOOKTYPE_OPER_INVITE_BAN 79 +/** See hooktype_invite_bypass() */ +#define HOOKTYPE_INVITE_BYPASS 79 /** See hooktype_view_topic_outside_channel() */ #define HOOKTYPE_VIEW_TOPIC_OUTSIDE_CHANNEL 80 /** See hooktype_chan_permit_nick_change() */ @@ -1931,14 +1931,16 @@ int hooktype_see_channel_in_whois(Client *client, Client *target, Channel *chann */ int hooktype_join_data(Client *who, Channel *channel); -/** Should the user be able to bypass bans? (function prototype for HOOKTYPE_OPER_INVITE_BAN). +/** Should the user be able to bypass channel restrictions because they are invited? (function prototype for HOOKTYPE_INVITE_BYPASS). * @param client The client * @param channel The channel - * @note The actual meaning of this hook is more complex, you are unlikely to use it, anyway. - * @retval HOOK_DENY Deny the join if the user is also banned + * @retval HOOK_DENY Don't allow the user to bypass channel restrictions when they are invited * @retval HOOK_CONTINUE Obey the normal rules + * @note Usually you want a user to be able to bypass channel restrictions such as +l or +b when they are /INVITEd by another user + * or have invited themselves (OperOverride). But, there may be special cases where you don't want this. + * For example, this hook is used by +O to still not allow ircops to join +O channels even if they have OperOverride capability. */ -int hooktype_oper_invite_ban(Client *client, Channel *channel); +int hooktype_invite_bypass(Client *client, Channel *channel); /** Should a user be able to view the topic when not in the channel? (function prototype for HOOKTYPE_VIEW_TOPIC_OUTSIDE_CHANNEL). * @param client The client requesting the topic @@ -2336,7 +2338,7 @@ _UNREAL_ERROR(_hook_error_incompatible, "Incompatible hook function. Check argum ((hooktype == HOOKTYPE_JOIN_DATA) && !ValidateHook(hooktype_join_data, func)) || \ ((hooktype == HOOKTYPE_PRE_KNOCK) && !ValidateHook(hooktype_pre_knock, func)) || \ ((hooktype == HOOKTYPE_PRE_INVITE) && !ValidateHook(hooktype_pre_invite, func)) || \ - ((hooktype == HOOKTYPE_OPER_INVITE_BAN) && !ValidateHook(hooktype_oper_invite_ban, func)) || \ + ((hooktype == HOOKTYPE_INVITE_BYPASS) && !ValidateHook(hooktype_invite_bypass, func)) || \ ((hooktype == HOOKTYPE_VIEW_TOPIC_OUTSIDE_CHANNEL) && !ValidateHook(hooktype_view_topic_outside_channel, func)) || \ ((hooktype == HOOKTYPE_CHAN_PERMIT_NICK_CHANGE) && !ValidateHook(hooktype_chan_permit_nick_change, func)) || \ ((hooktype == HOOKTYPE_IS_CHANNEL_SECURE) && !ValidateHook(hooktype_is_channel_secure, func)) || \ diff --git a/src/modules/chanmodes/operonly.c b/src/modules/chanmodes/operonly.c index 3c4b4f7c1..a140a8573 100644 --- a/src/modules/chanmodes/operonly.c +++ b/src/modules/chanmodes/operonly.c @@ -35,7 +35,7 @@ Cmode_t EXTCMODE_OPERONLY; int operonly_require_oper(Client *client, Channel *channel, char mode, const char *para, int checkt, int what); int operonly_can_join(Client *client, Channel *channel, const char *key, char **errmsg); int operonly_view_topic_outside_channel(Client *client, Channel *channel); -int operonly_oper_invite_ban(Client *client, Channel *channel); +int operonly_invite_bypass(Client *client, Channel *channel); MOD_TEST() { @@ -53,7 +53,7 @@ CmodeInfo req; CmodeAdd(modinfo->handle, req, &EXTCMODE_OPERONLY); HookAdd(modinfo->handle, HOOKTYPE_CAN_JOIN, 0, operonly_can_join); - HookAdd(modinfo->handle, HOOKTYPE_OPER_INVITE_BAN, 0, operonly_oper_invite_ban); + HookAdd(modinfo->handle, HOOKTYPE_INVITE_BYPASS, 0, operonly_invite_bypass); HookAdd(modinfo->handle, HOOKTYPE_VIEW_TOPIC_OUTSIDE_CHANNEL, 0, operonly_view_topic_outside_channel); @@ -81,10 +81,9 @@ int operonly_can_join(Client *client, Channel *channel, const char *key, char ** return 0; } -int operonly_oper_invite_ban(Client *client, Channel *channel) +int operonly_invite_bypass(Client *client, Channel *channel) { - if ((channel->mode.mode & EXTCMODE_OPERONLY) && - !ValidatePermissionsForPath("channel:operonly:ban",client,NULL,NULL,NULL)) + if ((channel->mode.mode & EXTCMODE_OPERONLY) && !ValidatePermissionsForPath("channel:operonly:ban",client,NULL,NULL,NULL)) return HOOK_DENY; return HOOK_CONTINUE; diff --git a/src/modules/join.c b/src/modules/join.c index 9d585cafb..724931fc3 100644 --- a/src/modules/join.c +++ b/src/modules/join.c @@ -94,37 +94,32 @@ MOD_UNLOAD() */ int _can_join(Client *client, Channel *channel, const char *key, char **errmsg) { - Link *lp; - Ban *banned; Hook *h; - int i=0, j=0; + + /* An /INVITE lets you bypass all restrictions */ + if (is_invited(client, channel)) + { + int j = 0; + for (h = Hooks[HOOKTYPE_INVITE_BYPASS]; h; h = h->next) + { + j = (*(h->func.intfunc))(client,channel); + if (j != 0) + break; + } + /* Bypass is OK, unless a HOOKTYPE_INVITE_BYPASS hook returns HOOK_DENY */ + if (j != HOOK_DENY) + return 0; + } for (h = Hooks[HOOKTYPE_CAN_JOIN]; h; h = h->next) { - i = (*(h->func.intfunc))(client,channel,key, errmsg); + int i = (*(h->func.intfunc))(client,channel,key, errmsg); if (i != 0) return i; } - for (h = Hooks[HOOKTYPE_OPER_INVITE_BAN]; h; h = h->next) - { - j = (*(h->func.intfunc))(client,channel); - if (j != 0) - break; - } - /* See if we can evade this ban */ - banned = is_banned(client, channel, BANCHK_JOIN, NULL, NULL); - if (banned && j == HOOK_DENY) - { - *errmsg = STR_ERR_BANNEDFROMCHAN; - return ERR_BANNEDFROMCHAN; - } - - if (is_invited(client, channel)) - return 0; /* allowed to walk through all the other modes */ - - if (banned) + if (is_banned(client, channel, BANCHK_JOIN, NULL, NULL)) { *errmsg = STR_ERR_BANNEDFROMCHAN; return ERR_BANNEDFROMCHAN;