mirror of
https://github.com/unrealircd/unrealircd.git
synced 2026-06-12 17:14:46 +02:00
Make /INVITE bypass (nearly) all channel mode restrictions, as it used to be
and as it should be IMO. Both for invites by channel ops and for OperOverride. This also fixes a bug where an IRCOp with OperOverride could not bypass +l and other restrictions. Only +b and +i could be bypassed. Module coders: HOOKTYPE_OPER_INVITE_BAN is now gone and HOOKTYPE_INVITE_BYPASS is now new. The HOOKTYPE_INVITE_BYPASS is called when the user is joining a channel to which they were invited to. If you return HOOK_DENY there then the join is still blocked, otherwise it is allowed. Using this hook would be sortof unusual since usually you would want users to be able to bypass restrictions when they were invited by another user or when they invited themselves using OperOverride. The only example where we use it in UnrealIRCd is for +O channels so an IRCOp cannot use OperOverride to join +O channels when they would otherwise not be allowed to do so. Actually even that is a corner case that you could debate about, but.. whatever.
This commit is contained in:
+9
-7
@@ -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)) || \
|
||||
|
||||
@@ -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;
|
||||
|
||||
+17
-22
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user