summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAttila Molnar <attilamolnar@hush.com>2014-07-05 13:06:57 +0200
committerAttila Molnar <attilamolnar@hush.com>2014-07-05 13:06:57 +0200
commit1f74e543bda13e761e7fc6b161e8f736a3dd6042 (patch)
treedde0855157a3f3922031e2ff48341a8f0a1c820c /src
parent1d020d132ff6d05ffd865d025cf161d7637f10d8 (diff)
m_spanningtree Add optional expected nick TS parameter to SVSNICK
Drop SVSNICK if the expected nick TS is present and it does not match the user's nick timestamp
Diffstat (limited to 'src')
-rw-r--r--src/modules/m_spanningtree/svsnick.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/modules/m_spanningtree/svsnick.cpp b/src/modules/m_spanningtree/svsnick.cpp
index 8689f71ac..bb21fc54d 100644
--- a/src/modules/m_spanningtree/svsnick.cpp
+++ b/src/modules/m_spanningtree/svsnick.cpp
@@ -29,6 +29,29 @@ CmdResult CommandSVSNick::Handle(User* user, std::vector<std::string>& parameter
if (u && IS_LOCAL(u))
{
+ // The 4th parameter is optional and it is the expected nick TS of the target user. If this parameter is
+ // present and it doesn't match the user's nick TS, the SVSNICK is not acted upon.
+ // This makes it possible to detect the case when services wants to change the nick of a user, but the
+ // user changes their nick before the SVSNICK arrives, making the SVSNICK nick change (usually to a guest nick)
+ // unnecessary. Consider the following for example:
+ //
+ // 1. test changes nick to Attila which is protected by services
+ // 2. Services SVSNICKs the user to Guest12345
+ // 3. Attila changes nick to Attila_ which isn't protected by services
+ // 4. SVSNICK arrives
+ // 5. Attila_ gets his nick changed to Guest12345 unnecessarily
+ //
+ // In this case when the SVSNICK is processed the target has already changed his nick to something
+ // which isn't protected, so changing the nick again to a Guest nick is not desired.
+ // However, if the expected nick TS parameter is present in the SVSNICK then the nick change in step 5
+ // won't happen because the timestamps won't match.
+ if (parameters.size() > 3)
+ {
+ time_t ExpectedTS = ConvToInt(parameters[3]);
+ if (u->age != ExpectedTS)
+ return CMD_FAILURE; // Ignore SVSNICK
+ }
+
std::string nick = parameters[1];
if (isdigit(nick[0]))
nick = u->uuid;