mirror of
https://github.com/unrealircd/unrealircd.git
synced 2026-07-10 23:23:12 +02:00
- Add support for server-enforced mode locks (MLOCK).
This allows the IRCd to enforce MLOCKs that are set by services, which eliminates clashes between users setting modes and services enforcing it's mlock on channels. (#3055)
This commit is contained in:
@@ -2434,3 +2434,7 @@
|
||||
queued data on the receive queue (eg: due to fake lag) was not processed
|
||||
unless we got new data from the client.
|
||||
Now, better document this. Also, avoid calling dbuf_put with 0 length.
|
||||
- Add support for server-enforced mode locks (MLOCK).
|
||||
This allows the IRCd to enforce MLOCKs that are set by services, which
|
||||
eliminates clashes between users setting modes and services enforcing
|
||||
it's mlock on channels. (#3055)
|
||||
|
||||
@@ -274,6 +274,7 @@ extern void start_auth(aClient *);
|
||||
extern void read_authports(aClient *);
|
||||
extern void send_authports(aClient *);
|
||||
|
||||
extern void set_channel_mlock(aClient *, aClient *, aChannel *, const char *, int);
|
||||
|
||||
extern void restart(char *);
|
||||
extern void server_reboot(char *);
|
||||
|
||||
@@ -297,6 +297,9 @@
|
||||
#define MSG_EOS "EOS"
|
||||
#define TOK_EOS "ES"
|
||||
|
||||
#define MSG_MLOCK "MLOCK"
|
||||
#define TOK_MLOCK "ML"
|
||||
|
||||
#define MAXPARA 15
|
||||
|
||||
extern int m_error();
|
||||
|
||||
@@ -370,6 +370,8 @@
|
||||
|
||||
#define RPL_WHOISSECURE 671
|
||||
|
||||
#define ERR_MLOCKRESTRICTED 742
|
||||
|
||||
#define ERR_CANNOTDOCOMMAND 972
|
||||
#define ERR_CANNOTCHANGECHANMODE 974
|
||||
|
||||
|
||||
@@ -372,6 +372,7 @@ typedef unsigned int u_int32_t; /* XXX Hope this works! */
|
||||
#define PROTO_SASL 0x80000 /* client is doing SASL */
|
||||
#define PROTO_AWAY_NOTIFY 0x100000 /* client supports away-notify */
|
||||
#define PROTO_ACCOUNT_NOTIFY 0x200000 /* client supports account-notify */
|
||||
#define PROTO_MLOCK 0x400000 /* server supports MLOCK */
|
||||
|
||||
/*
|
||||
* flags macros.
|
||||
@@ -1627,6 +1628,7 @@ struct Channel {
|
||||
#ifdef JOINTHROTTLE
|
||||
aJFlood *jflood;
|
||||
#endif
|
||||
char *mode_lock;
|
||||
char chname[1];
|
||||
};
|
||||
|
||||
|
||||
@@ -1416,6 +1416,8 @@ void sub1_from_channel(aChannel *chptr)
|
||||
#ifdef JOINTHROTTLE
|
||||
cmodej_delchannelentries(chptr);
|
||||
#endif
|
||||
if (chptr->mode_lock)
|
||||
MyFree(chptr->mode_lock);
|
||||
if (chptr->topic)
|
||||
MyFree(chptr->topic);
|
||||
if (chptr->topic_nick)
|
||||
@@ -1863,3 +1865,24 @@ char m;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set_channel_mlock()
|
||||
*
|
||||
* inputs - client, source, channel, params
|
||||
* output -
|
||||
* side effects - channel mlock is changed / MLOCK is propagated
|
||||
*/
|
||||
void
|
||||
set_channel_mlock(aClient *cptr, aClient *sptr, aChannel *chptr, const char *newmlock, int propagate)
|
||||
{
|
||||
if (chptr->mode_lock)
|
||||
MyFree(chptr->mode_lock);
|
||||
chptr->mode_lock = newmlock != NULL ? strdup(newmlock) : NULL;
|
||||
|
||||
if (propagate)
|
||||
{
|
||||
sendto_serv_butone_token(cptr, cptr->name, MSG_MLOCK, TOK_MLOCK, "%B %s :%s",
|
||||
chptr->creationtime, chptr->chname,
|
||||
BadPtr(chptr->mode_lock) ? "" : chptr->mode_lock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
|
||||
/* Forward declarations */
|
||||
DLLFUNC CMD_FUNC(m_mode);
|
||||
DLLFUNC CMD_FUNC(m_mlock);
|
||||
DLLFUNC void _do_mode(aChannel *chptr, aClient *cptr, aClient *sptr, int parc, char *parv[], time_t sendts, int samode);
|
||||
DLLFUNC void _set_mode(aChannel *chptr, aClient *cptr, int parc, char *parv[], u_int *pcount,
|
||||
char pvar[MAXMODEPARAMS][MODEBUFLEN + 3], int bounce);
|
||||
@@ -96,6 +97,7 @@ DLLFUNC int MOD_TEST(m_mode)(ModuleInfo *modinfo)
|
||||
DLLFUNC int MOD_INIT(m_mode)(ModuleInfo *modinfo)
|
||||
{
|
||||
CommandAdd(modinfo->handle, MSG_MODE, TOK_MODE, m_mode, MAXPARA, M_USER|M_SERVER);
|
||||
CommandAdd(modinfo->handle, MSG_MLOCK, TOK_MLOCK, m_mlock, MAXPARA, M_SERVER);
|
||||
MARK_AS_OFFICIAL_MODULE(modinfo);
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
@@ -1935,6 +1937,7 @@ DLLFUNC void _set_mode(aChannel *chptr, aClient *cptr, int parc, char *parv[], u
|
||||
aCtab *tab = &cFlagTab[0];
|
||||
aCtab foundat;
|
||||
int found = 0;
|
||||
int sent_mlock_warning = 0;
|
||||
unsigned int htrig = 0;
|
||||
long oldm, oldl;
|
||||
int checkrestr = 0, warnrestr = 1;
|
||||
@@ -1978,6 +1981,15 @@ DLLFUNC void _set_mode(aChannel *chptr, aClient *cptr, int parc, char *parv[], u
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if (MyClient(cptr) && chptr->mode_lock && strchr(chptr->mode_lock, *curchr) != NULL)
|
||||
{
|
||||
if (!sent_mlock_warning)
|
||||
{
|
||||
sendto_one(cptr, err_str(ERR_MLOCKRESTRICTED), me.name, cptr->name, chptr->chname, *curchr, chptr->mode_lock);
|
||||
sent_mlock_warning++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
found = 0;
|
||||
tab = &cFlagTab[0];
|
||||
while ((tab->mode != 0x0) && found == 0)
|
||||
@@ -2490,3 +2502,28 @@ DLLFUNC CMD_FUNC(_m_umode)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CMD_FUNC(m_mlock)
|
||||
{
|
||||
aChannel *chptr = NULL;
|
||||
TS chants;
|
||||
|
||||
if (*parv[1] == '!')
|
||||
chants = (TS) base64dec(parv[1] + 1);
|
||||
else
|
||||
chants = (TS) atol(parv[1]);
|
||||
|
||||
/* Now, try to find the channel in question */
|
||||
chptr = find_channel(parv[2], NullChn);
|
||||
if(chptr == NULL)
|
||||
return 0;
|
||||
|
||||
/* TS is higher, drop it. */
|
||||
if(chants > chptr->creationtime)
|
||||
return 0;
|
||||
|
||||
if(IsServer(sptr))
|
||||
set_channel_mlock(cptr, sptr, chptr, parv[3], TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -432,6 +432,18 @@ CMD_FUNC(m_protoctl)
|
||||
if (s[8] != '*')
|
||||
send_protoctl_servers(sptr, 1);
|
||||
}
|
||||
else if ((strcmp(s, "MLOCK")) == 0)
|
||||
{
|
||||
#ifdef PROTOCTL_MADNESS
|
||||
if (remove)
|
||||
{
|
||||
cptr->proto &= ~PROTO_MLOCK;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
Debug((DEBUG_ERROR, "Chose protocol %s for link %s", proto, cptr->name));
|
||||
cptr->proto |= PROTO_MLOCK;
|
||||
}
|
||||
/*
|
||||
* Add other protocol extensions here, with proto
|
||||
* containing the base option, and options containing
|
||||
|
||||
@@ -1204,6 +1204,14 @@ void send_channel_modes(aClient *cptr, aChannel *chptr)
|
||||
if (modebuf[1] || *parabuf)
|
||||
sendmodeto_one(cptr, me.name, chptr->chname, modebuf,
|
||||
parabuf, chptr->creationtime);
|
||||
|
||||
/* send MLOCK here too... --nenolod */
|
||||
if (CHECKPROTO(cptr, PROTO_MLOCK))
|
||||
{
|
||||
sendto_one(cptr, (CHECKPROTO(cptr, PROTO_SJB64) ? "%s %B %s :%s" : "%s %lu %s :%s"),
|
||||
(IsToken(cptr) ? TOK_MLOCK : MSG_MLOCK), chptr->creationtime, chptr->chname,
|
||||
BadPtr(chptr->mode_lock) ? "" : chptr->mode_lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -375,6 +375,9 @@ CMD_FUNC(m_sjoin)
|
||||
sptr->name, chptr->chname, modebuf, parabuf);
|
||||
|
||||
}
|
||||
|
||||
/* since we're dropping our modes, we want to clear the mlock as well. --nenolod */
|
||||
set_channel_mlock(cptr, sptr, chptr, NULL, FALSE);
|
||||
}
|
||||
/* Mode setting done :), now for our beloved clients */
|
||||
parabuf[0] = 0;
|
||||
|
||||
+1
-1
@@ -798,7 +798,7 @@ static char *replies[] = {
|
||||
/* 739 */ NULL,
|
||||
/* 740 */ NULL,
|
||||
/* 741 */ NULL,
|
||||
/* 742 */ NULL,
|
||||
/* 742 ERR_MLOCKRESTRICTED */ ":%s 742 %s %s %c %s :MODE cannot be set due to channel having an active MLOCK restriction policy",
|
||||
/* 743 */ NULL,
|
||||
/* 744 */ NULL,
|
||||
/* 745 */ NULL,
|
||||
|
||||
Reference in New Issue
Block a user