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:
parent
c7708a0994
commit
202d496644
8 changed files with 32 additions and 9 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ typedef struct
|
|||
struct membership *msptr;
|
||||
struct Client *target;
|
||||
int approved;
|
||||
int dir;
|
||||
} hook_data_channel_approval;
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)))
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
22
src/chmode.c
22
src/chmode.c
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue