chmode: Allow mode queries on mlocked modes.
Check mlock at the same point where chanops are checked (except for querying a +e/+I list) and abstract this check into a function. In particular, /mode #channel f is now again allowed if +f is mlocked.
This commit is contained in:
parent
e4ce3b5409
commit
f3b3ad0b07
1 changed files with 46 additions and 69 deletions
115
src/chmode.c
115
src/chmode.c
|
@ -199,6 +199,42 @@ get_channel_access(struct Client *source_p, struct membership *msptr)
|
||||||
return moduledata.approved;
|
return moduledata.approved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* allow_mode_change()
|
||||||
|
*
|
||||||
|
* Checks if mlock and chanops permit a mode change.
|
||||||
|
*
|
||||||
|
* inputs - client, channel, access level, errors pointer, mode char
|
||||||
|
* outputs - 0 on failure, 1 on success
|
||||||
|
* side effects - error message sent on failure
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
allow_mode_change(struct Client *source_p, struct Channel *chptr, int alevel,
|
||||||
|
int *errors, char c)
|
||||||
|
{
|
||||||
|
/* If this mode char is locked, don't allow local users to change it. */
|
||||||
|
if (MyClient(source_p) && chptr->mode_lock && strchr(chptr->mode_lock, c))
|
||||||
|
{
|
||||||
|
if (!(*errors & SM_ERR_MLOCK))
|
||||||
|
sendto_one_numeric(source_p,
|
||||||
|
ERR_MLOCKRESTRICTED,
|
||||||
|
form_str(ERR_MLOCKRESTRICTED),
|
||||||
|
chptr->chname,
|
||||||
|
c,
|
||||||
|
chptr->mode_lock);
|
||||||
|
*errors |= SM_ERR_MLOCK;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(alevel != CHFL_CHANOP)
|
||||||
|
{
|
||||||
|
if(!(*errors & SM_ERR_NOOPS))
|
||||||
|
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
||||||
|
me.name, source_p->name, chptr->chname);
|
||||||
|
*errors |= SM_ERR_NOOPS;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* add_id()
|
/* add_id()
|
||||||
*
|
*
|
||||||
* inputs - client, channel, id to add, type, forward
|
* inputs - client, channel, id to add, type, forward
|
||||||
|
@ -576,14 +612,8 @@ chm_simple(struct Client *source_p, struct Channel *chptr,
|
||||||
int alevel, int parc, int *parn,
|
int alevel, int parc, int *parn,
|
||||||
const char **parv, int *errors, int dir, char c, long mode_type)
|
const char **parv, int *errors, int dir, char c, long mode_type)
|
||||||
{
|
{
|
||||||
if(alevel != CHFL_CHANOP)
|
if(!allow_mode_change(source_p, chptr, alevel, errors, c))
|
||||||
{
|
|
||||||
if(!(*errors & SM_ERR_NOOPS))
|
|
||||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
|
||||||
me.name, source_p->name, chptr->chname);
|
|
||||||
*errors |= SM_ERR_NOOPS;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if(MyClient(source_p) && (++mode_limit_simple > MAXMODES_SIMPLE))
|
if(MyClient(source_p) && (++mode_limit_simple > MAXMODES_SIMPLE))
|
||||||
return;
|
return;
|
||||||
|
@ -789,6 +819,7 @@ chm_ban(struct Client *source_p, struct Channel *chptr,
|
||||||
*errors |= errorval;
|
*errors |= errorval;
|
||||||
|
|
||||||
/* non-ops cant see +eI lists.. */
|
/* non-ops cant see +eI lists.. */
|
||||||
|
/* note that this is still permitted if +e/+I are mlocked. */
|
||||||
if(alevel != CHFL_CHANOP && mode_type != CHFL_BAN &&
|
if(alevel != CHFL_CHANOP && mode_type != CHFL_BAN &&
|
||||||
mode_type != CHFL_QUIET)
|
mode_type != CHFL_QUIET)
|
||||||
{
|
{
|
||||||
|
@ -816,14 +847,9 @@ chm_ban(struct Client *source_p, struct Channel *chptr,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(alevel != CHFL_CHANOP)
|
if(!allow_mode_change(source_p, chptr, alevel, errors, c))
|
||||||
{
|
|
||||||
if(!(*errors & SM_ERR_NOOPS))
|
|
||||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
|
||||||
me.name, source_p->name, chptr->chname);
|
|
||||||
*errors |= SM_ERR_NOOPS;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if(MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
|
if(MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
|
||||||
return;
|
return;
|
||||||
|
@ -969,14 +995,8 @@ chm_op(struct Client *source_p, struct Channel *chptr,
|
||||||
const char *opnick;
|
const char *opnick;
|
||||||
struct Client *targ_p;
|
struct Client *targ_p;
|
||||||
|
|
||||||
if(alevel != CHFL_CHANOP)
|
if(!allow_mode_change(source_p, chptr, alevel, errors, c))
|
||||||
{
|
|
||||||
if(!(*errors & SM_ERR_NOOPS))
|
|
||||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
|
||||||
me.name, source_p->name, chptr->chname);
|
|
||||||
*errors |= SM_ERR_NOOPS;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if((dir == MODE_QUERY) || (parc <= *parn))
|
if((dir == MODE_QUERY) || (parc <= *parn))
|
||||||
return;
|
return;
|
||||||
|
@ -1057,14 +1077,8 @@ chm_voice(struct Client *source_p, struct Channel *chptr,
|
||||||
const char *opnick;
|
const char *opnick;
|
||||||
struct Client *targ_p;
|
struct Client *targ_p;
|
||||||
|
|
||||||
if(alevel != CHFL_CHANOP)
|
if(!allow_mode_change(source_p, chptr, alevel, errors, c))
|
||||||
{
|
|
||||||
if(!(*errors & SM_ERR_NOOPS))
|
|
||||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
|
||||||
me.name, source_p->name, chptr->chname);
|
|
||||||
*errors |= SM_ERR_NOOPS;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if((dir == MODE_QUERY) || parc <= *parn)
|
if((dir == MODE_QUERY) || parc <= *parn)
|
||||||
return;
|
return;
|
||||||
|
@ -1135,14 +1149,8 @@ chm_limit(struct Client *source_p, struct Channel *chptr,
|
||||||
static char limitstr[30];
|
static char limitstr[30];
|
||||||
int limit;
|
int limit;
|
||||||
|
|
||||||
if(alevel != CHFL_CHANOP)
|
if(!allow_mode_change(source_p, chptr, alevel, errors, c))
|
||||||
{
|
|
||||||
if(!(*errors & SM_ERR_NOOPS))
|
|
||||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
|
||||||
me.name, source_p->name, chptr->chname);
|
|
||||||
*errors |= SM_ERR_NOOPS;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if(dir == MODE_QUERY)
|
if(dir == MODE_QUERY)
|
||||||
return;
|
return;
|
||||||
|
@ -1194,14 +1202,8 @@ chm_throttle(struct Client *source_p, struct Channel *chptr,
|
||||||
{
|
{
|
||||||
int joins = 0, timeslice = 0;
|
int joins = 0, timeslice = 0;
|
||||||
|
|
||||||
if(alevel != CHFL_CHANOP)
|
if(!allow_mode_change(source_p, chptr, alevel, errors, c))
|
||||||
{
|
|
||||||
if(!(*errors & SM_ERR_NOOPS))
|
|
||||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
|
||||||
me.name, source_p->name, chptr->chname);
|
|
||||||
*errors |= SM_ERR_NOOPS;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if(dir == MODE_QUERY)
|
if(dir == MODE_QUERY)
|
||||||
return;
|
return;
|
||||||
|
@ -1275,14 +1277,8 @@ chm_forward(struct Client *source_p, struct Channel *chptr,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef FORWARD_OPERONLY
|
#ifndef FORWARD_OPERONLY
|
||||||
if(alevel != CHFL_CHANOP)
|
if(!allow_mode_change(source_p, chptr, alevel, errors, c))
|
||||||
{
|
|
||||||
if(!(*errors & SM_ERR_NOOPS))
|
|
||||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
|
||||||
me.name, source_p->name, chptr->chname);
|
|
||||||
*errors |= SM_ERR_NOOPS;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
if(!IsOper(source_p) && !IsServer(source_p))
|
if(!IsOper(source_p) && !IsServer(source_p))
|
||||||
{
|
{
|
||||||
|
@ -1342,14 +1338,8 @@ chm_key(struct Client *source_p, struct Channel *chptr,
|
||||||
{
|
{
|
||||||
char *key;
|
char *key;
|
||||||
|
|
||||||
if(alevel != CHFL_CHANOP)
|
if(!allow_mode_change(source_p, chptr, alevel, errors, c))
|
||||||
{
|
|
||||||
if(!(*errors & SM_ERR_NOOPS))
|
|
||||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
|
||||||
me.name, source_p->name, chptr->chname);
|
|
||||||
*errors |= SM_ERR_NOOPS;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if(dir == MODE_QUERY)
|
if(dir == MODE_QUERY)
|
||||||
return;
|
return;
|
||||||
|
@ -1741,19 +1731,6 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
|
||||||
dir = MODE_QUERY;
|
dir = MODE_QUERY;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* If this mode char is locked, don't allow local users to change it. */
|
|
||||||
if (MyClient(source_p) && chptr->mode_lock && strchr(chptr->mode_lock, c))
|
|
||||||
{
|
|
||||||
if (!(errors & SM_ERR_MLOCK))
|
|
||||||
sendto_one_numeric(source_p,
|
|
||||||
ERR_MLOCKRESTRICTED,
|
|
||||||
form_str(ERR_MLOCKRESTRICTED),
|
|
||||||
chptr->chname,
|
|
||||||
c,
|
|
||||||
chptr->mode_lock);
|
|
||||||
errors |= SM_ERR_MLOCK;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
chmode_table[(unsigned char) c].set_func(fakesource_p, chptr, alevel,
|
chmode_table[(unsigned char) c].set_func(fakesource_p, chptr, alevel,
|
||||||
parc, &parn, parv,
|
parc, &parn, parv,
|
||||||
&errors, dir, c,
|
&errors, dir, c,
|
||||||
|
|
Loading…
Reference in a new issue