override: only engage override code if we're needing to authorize a WRITE to a channel's state (closes #65)

This commit is contained in:
William Pitcock 2015-12-10 01:00:32 -06:00
parent c7708a0994
commit 202d496644
8 changed files with 32 additions and 9 deletions

View File

@ -108,7 +108,7 @@ m_remove(struct Client *client_p, struct Client *source_p, int parc, const char
return 0;
}
if(get_channel_access(source_p, msptr) < CHFL_CHANOP)
if(get_channel_access(source_p, msptr, MODE_ADD) < CHFL_CHANOP)
{
if(MyConnect(source_p))
{
@ -178,6 +178,7 @@ m_remove(struct Client *client_p, struct Client *source_p, int parc, const char
hookdata.msptr = msptr;
hookdata.target = who;
hookdata.approved = 1;
hookdata.dir = MODE_ADD; /* ensure modules like override speak up */
call_hook(h_can_kick, &hookdata);

View File

@ -153,6 +153,9 @@ hack_channel_access(void *vdata)
{
hook_data_channel_approval *data = (hook_data_channel_approval *) vdata;
if (data->dir == MODE_QUERY)
return;
if (data->approved == CHFL_CHANOP)
return;
@ -189,6 +192,9 @@ hack_can_send(void *vdata)
{
hook_data_channel_approval *data = (hook_data_channel_approval *) vdata;
if (data->dir == MODE_QUERY)
return;
if (data->approved == CAN_SEND_NONOP || data->approved == CAN_SEND_OPV)
return;

View File

@ -270,7 +270,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);
extern int get_channel_access(struct Client *source_p, struct membership *msptr, int dir);
extern void send_channel_join(struct Channel *chptr, struct Client *client_p);

View File

@ -82,6 +82,7 @@ typedef struct
struct membership *msptr;
struct Client *target;
int approved;
int dir;
} hook_data_channel_approval;
typedef struct

View File

@ -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) < CHFL_CHANOP)
if(get_channel_access(source_p, msptr, MODE_ADD) < CHFL_CHANOP)
{
if(MyConnect(source_p))
{
@ -167,6 +167,7 @@ m_kick(struct Client *client_p, struct Client *source_p, int parc, const char *p
hookdata.msptr = msptr;
hookdata.target = who;
hookdata.approved = 1;
hookdata.dir = MODE_ADD; /* ensure modules like override speak up */
call_hook(h_can_kick, &hookdata);

View File

@ -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) >= CHFL_CHANOP) &&
get_channel_access(source_p, msptr, MODE_ADD) >= CHFL_CHANOP) &&
(!MyClient(source_p) ||
can_send(chptr, source_p, msptr)))
{

View File

@ -821,6 +821,7 @@ can_send(struct Channel *chptr, struct Client *source_p, struct membership *mspt
hook_data_channel_approval moduledata;
moduledata.approved = CAN_SEND_NONOP;
moduledata.dir = MODE_QUERY;
if(IsServer(source_p) || IsService(source_p))
return CAN_SEND_OPV;
@ -871,6 +872,7 @@ can_send(struct Channel *chptr, struct Client *source_p, struct membership *mspt
moduledata.chptr = msptr->chptr;
moduledata.msptr = msptr;
moduledata.target = NULL;
moduledata.dir = (moduledata.approved == CAN_SEND_NO) ? MODE_ADD : MODE_QUERY;
call_hook(h_can_send, &moduledata);

View File

@ -179,7 +179,7 @@ cflag_orphan(char c_)
}
int
get_channel_access(struct Client *source_p, struct membership *msptr)
get_channel_access(struct Client *source_p, struct membership *msptr, int dir)
{
hook_data_channel_approval moduledata;
@ -194,6 +194,7 @@ get_channel_access(struct Client *source_p, struct membership *msptr)
moduledata.msptr = msptr;
moduledata.target = NULL;
moduledata.approved = is_chanop(msptr) ? CHFL_CHANOP : CHFL_PEON;
moduledata.dir = dir;
call_hook(h_get_channel_access, &moduledata);
@ -518,7 +519,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) != CHFL_CHANOP)
get_channel_access(source_p, msptr, MODE_QUERY) != CHFL_CHANOP)
{
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
me.name, source_p->name, targptr->chname);
@ -1632,13 +1633,14 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
char *pbuf;
int cur_len, mlen, paralen, paracount, arglen, len;
int i, j, flags;
int dir = MODE_ADD;
int dir = MODE_QUERY;
int parn = 1;
int errors = 0;
int alevel;
const char *ml = parv[0];
char c;
struct Client *fakesource_p;
int reauthorized = 0; /* if we change from MODE_QUERY to MODE_ADD/MODE_DEL, then reauth once, ugly but it works */
mask_pos = 0;
removed_mask_pos = 0;
@ -1646,23 +1648,33 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
mode_limit = 0;
mode_limit_simple = 0;
alevel = get_channel_access(source_p, msptr);
/* Hide connecting server on netburst -- jilles */
if (ConfigServerHide.flatten_links && IsServer(source_p) && !has_id(source_p) && !HasSentEob(source_p))
fakesource_p = &me;
else
fakesource_p = source_p;
alevel = get_channel_access(source_p, msptr, dir);
for(; (c = *ml) != 0; ml++)
{
switch (c)
{
case '+':
dir = MODE_ADD;
if (!reauthorized)
{
alevel = get_channel_access(source_p, msptr, dir);
reauthorized = 1;
}
break;
case '-':
dir = MODE_DEL;
if (!reauthorized)
{
alevel = get_channel_access(source_p, msptr, dir);
reauthorized = 1;
}
break;
case '=':
dir = MODE_QUERY;