
I like being able to stop someone from changing TO a nick. I have some users that annoyingly change to "away" nicks or some other nick change when they disconnect from a bnc. I can let the user use the channel, but stop them from using the annoying away/disconnected nick by banning it. Aaron Wiebe wrote:
I like. Will apply this.
One question, for future thought - since we're flushing banserial now on nick changes, does it really make sense to limit nick changes based on is_banned status? It might make sense to just let users change their nicks, and let them be quiet if they want to change to a banned nickname...
-Aaron
On Mon, May 4, 2009 at 6:00 PM, Ned T. Crigler <crigler@gmail.com> wrote:
After services does a SVSNICK on a user, if the new nickname is banned in a channel, they are still allowed to talk and change their nick if they were not banned previously.
For example:
*** Mode change "+b testing!*@*" on #test by RuneB *** Mode change "-o RuneB" on #test by RuneB <RuneB> I can talk. Now I'll force a SVSNICK on me to testing. *** RuneB is now known as testing <testing> can I still talk? <testing> yep.
This is because is_banned doesn't recheck the ban list if the banserial has not changed for the user (instead it returns immediately). SVSNICK forces a nick change, but doesn't change the banserial in any of the channels the user is in. This causes is_banned to think the ban status has not changed. --- include/h.h | 1 + src/channel.c | 20 ++++++++++++++++++++ src/m_nick.c | 7 +++++++ src/m_services.c | 1 + 4 files changed, 29 insertions(+), 0 deletions(-)
diff --git a/include/h.h b/include/h.h index 26465cd..1d4cce7 100644 --- a/include/h.h +++ b/include/h.h @@ -91,6 +91,7 @@ extern int bootopt; extern char *canonize(char *); extern void check_fdlists(); extern aChannel *find_channel(char *, aChannel *); +extern void flush_user_banserial(aClient *); extern aBan *nick_is_banned(aChannel *, char *, aClient *); extern void remove_matching_bans(aChannel *, aClient *, aClient *); #ifdef EXEMPT_LISTS diff --git a/src/channel.c b/src/channel.c index 642d7f1..1662f33 100644 --- a/src/channel.c +++ b/src/channel.c @@ -537,6 +537,26 @@ static int is_banned(aClient *cptr, aChannel *chptr, chanMember *cm) return 0; }
+/* + * Forces the cached banned status for a user to be flushed in all the channels + * they are in. + */ +void flush_user_banserial(aClient *cptr) +{ + Link *ptr; + + if (!IsPerson(cptr)) + return; + for (ptr = cptr->user->channel; ptr; ptr = ptr->next) + { + aChannel *chptr = ptr->value.chptr; + chanMember *cm = find_user_member(chptr->members, cptr); + + if (cm) + cm->banserial = chptr->banserial - 1; + } +} + aBan *nick_is_banned(aChannel *chptr, char *nick, aClient *cptr) { aBan *ban; diff --git a/src/m_nick.c b/src/m_nick.c index 79eab36..6eee775 100644 --- a/src/m_nick.c +++ b/src/m_nick.c @@ -575,6 +575,13 @@ int m_nick(aClient *cptr, aClient *sptr, int parc, char *parv[]) /* If it changed nicks, -r it */ if (mycmp(parv[0], nick)) sptr->umode &= ~UMODE_r; + + /* + * Flush the banserial for the channels the user is in, since this + * could be a SVSNICK induced nick change, which overrides any ban + * checking on the originating server. + */ + flush_user_banserial(sptr); } } else diff --git a/src/m_services.c b/src/m_services.c index 50e0b87..bc97958 100644 --- a/src/m_services.c +++ b/src/m_services.c @@ -230,6 +230,7 @@ int m_svsnick(aClient *cptr, aClient *sptr, int parc, char *parv[]) strcpy(acptr->name, newnick); add_to_client_hash_table(acptr->name, acptr); hash_check_watch(acptr, RPL_LOGON); + flush_user_banserial(acptr);
return 0; } -- 1.6.2.4
-- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.