Rework ircd-side MLOCK enforcement: instead of trying to track modes locked on or off, instead keep a simple list of mode letters that are locked, and reject any change to those modes.
This commit is contained in:
parent
0a01ecfa85
commit
78e6b731e4
4 changed files with 13 additions and 40 deletions
|
@ -39,7 +39,6 @@ struct Client;
|
||||||
struct Mode
|
struct Mode
|
||||||
{
|
{
|
||||||
unsigned int mode;
|
unsigned int mode;
|
||||||
unsigned int off_mode;
|
|
||||||
int limit;
|
int limit;
|
||||||
char key[KEYLEN];
|
char key[KEYLEN];
|
||||||
unsigned int join_num;
|
unsigned int join_num;
|
||||||
|
@ -52,7 +51,7 @@ struct Channel
|
||||||
{
|
{
|
||||||
rb_dlink_node node;
|
rb_dlink_node node;
|
||||||
struct Mode mode;
|
struct Mode mode;
|
||||||
struct Mode mode_lock;
|
char *mode_lock;
|
||||||
char *topic;
|
char *topic;
|
||||||
char *topic_info;
|
char *topic_info;
|
||||||
time_t topic_time;
|
time_t topic_time;
|
||||||
|
@ -264,7 +263,7 @@ void resv_chan_forcepart(const char *name, const char *reason, int temp_time);
|
||||||
extern void set_channel_mode(struct Client *client_p, struct Client *source_p,
|
extern void set_channel_mode(struct Client *client_p, struct Client *source_p,
|
||||||
struct Channel *chptr, struct membership *msptr, int parc, const char *parv[]);
|
struct Channel *chptr, struct membership *msptr, int parc, const char *parv[]);
|
||||||
extern void set_channel_mlock(struct Client *client_p, struct Client *source_p,
|
extern void set_channel_mlock(struct Client *client_p, struct Client *source_p,
|
||||||
struct Channel *chptr, int parc, const char *parv[]);
|
struct Channel *chptr, const char *newmlock);
|
||||||
|
|
||||||
extern struct ChannelMode chmode_table[256];
|
extern struct ChannelMode chmode_table[256];
|
||||||
|
|
||||||
|
|
|
@ -235,7 +235,7 @@ ms_mlock(struct Client *client_p, struct Client *source_p, int parc, const char
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(IsServer(source_p))
|
if(IsServer(source_p))
|
||||||
set_channel_mlock(client_p, source_p, chptr, parc - 3, parv + 3);
|
set_channel_mlock(client_p, source_p, chptr, parv[3]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,7 @@ void
|
||||||
free_channel(struct Channel *chptr)
|
free_channel(struct Channel *chptr)
|
||||||
{
|
{
|
||||||
rb_free(chptr->chname);
|
rb_free(chptr->chname);
|
||||||
|
rb_free(chptr->mode_lock);
|
||||||
rb_bh_free(channel_heap, chptr);
|
rb_bh_free(channel_heap, chptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
45
src/chmode.c
45
src/chmode.c
|
@ -516,7 +516,7 @@ chm_simple(struct Client *source_p, struct Channel *chptr,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* setting + */
|
/* setting + */
|
||||||
if((dir == MODE_ADD) && !(chptr->mode.mode & mode_type) && !(chptr->mode_lock.off_mode & mode_type))
|
if((dir == MODE_ADD) && !(chptr->mode.mode & mode_type))
|
||||||
{
|
{
|
||||||
/* if +f is disabled, ignore an attempt to set +QF locally */
|
/* if +f is disabled, ignore an attempt to set +QF locally */
|
||||||
if(!ConfigChannel.use_forward && MyClient(source_p) &&
|
if(!ConfigChannel.use_forward && MyClient(source_p) &&
|
||||||
|
@ -533,7 +533,7 @@ chm_simple(struct Client *source_p, struct Channel *chptr,
|
||||||
mode_changes[mode_count].mems = ALL_MEMBERS;
|
mode_changes[mode_count].mems = ALL_MEMBERS;
|
||||||
mode_changes[mode_count++].arg = NULL;
|
mode_changes[mode_count++].arg = NULL;
|
||||||
}
|
}
|
||||||
else if((dir == MODE_DEL) && (chptr->mode.mode & mode_type) && !(chptr->mode_lock.mode & mode_type))
|
else if((dir == MODE_DEL) && (chptr->mode.mode & mode_type))
|
||||||
{
|
{
|
||||||
chptr->mode.mode &= ~mode_type;
|
chptr->mode.mode &= ~mode_type;
|
||||||
|
|
||||||
|
@ -1662,6 +1662,9 @@ 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))
|
||||||
|
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,
|
||||||
|
@ -1768,41 +1771,11 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
set_channel_mlock(struct Client *client_p, struct Client *source_p,
|
set_channel_mlock(struct Client *client_p, struct Client *source_p,
|
||||||
struct Channel *chptr, int parc, const char *parv[])
|
struct Channel *chptr, const char *newmlock)
|
||||||
{
|
{
|
||||||
int dir = MODE_ADD;
|
rb_free(chptr->mode_lock);
|
||||||
const char *ml = parv[0];
|
chptr->mode_lock = rb_strdup(newmlock);
|
||||||
char c;
|
|
||||||
|
|
||||||
memset(&chptr->mode_lock, '\0', sizeof(struct Mode));
|
|
||||||
|
|
||||||
for(; (c = *ml) != 0; ml++)
|
|
||||||
{
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case '+':
|
|
||||||
dir = MODE_ADD;
|
|
||||||
break;
|
|
||||||
case '-':
|
|
||||||
dir = MODE_DEL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (chmode_table[(unsigned char) c].set_func == chm_simple)
|
|
||||||
switch(dir)
|
|
||||||
{
|
|
||||||
case MODE_ADD:
|
|
||||||
chptr->mode_lock.mode |= chmode_table[(unsigned char) c].mode_type;
|
|
||||||
chptr->mode_lock.off_mode &= ~chmode_table[(unsigned char) c].mode_type;
|
|
||||||
break;
|
|
||||||
case MODE_DEL:
|
|
||||||
chptr->mode_lock.off_mode |= chmode_table[(unsigned char) c].mode_type;
|
|
||||||
chptr->mode_lock.mode &= ~chmode_table[(unsigned char) c].mode_type;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sendto_server(client_p, NULL, CAP_TS6 | CAP_MLOCK, NOCAPS, ":%s MLOCK %ld %s %s",
|
sendto_server(client_p, NULL, CAP_TS6 | CAP_MLOCK, NOCAPS, ":%s MLOCK %ld %s %s",
|
||||||
source_p->id, (long) chptr->channelts, chptr->chname, channel_mlock(chptr, &me));
|
source_p->id, (long) chptr->channelts, chptr->chname, chptr->mode_lock);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue