From 01413dd3cc5e9984b5278b613bc2ef8abc1267d7 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 Feb 2013 21:44:37 -0500 Subject: [PATCH] Use channel mode +r to determine if a channel has either been newly created or created while we were offline (eg, during the inital burst to the uplink). Fixes not knowing whether or not channels ops in non-secureop non-persistent channels obtained op while we were offline by creating the channel or legitimately by being set op by another channel op. --- src/channels.cpp | 11 ++++++++--- src/messages.cpp | 5 ++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/channels.cpp b/src/channels.cpp index d9075282c..9265fdacf 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -928,7 +928,8 @@ void Channel::SetCorrectModes(User *user, bool give_modes, bool check_noop) *admin = ModeManager::FindChannelModeByName("PROTECT"), *op = ModeManager::FindChannelModeByName("OP"), *halfop = ModeManager::FindChannelModeByName("HALFOP"), - *voice = ModeManager::FindChannelModeByName("VOICE"); + *voice = ModeManager::FindChannelModeByName("VOICE"), + *registered = ModeManager::FindChannelModeByName("REGISTERED"); if (user == NULL) return; @@ -954,8 +955,12 @@ void Channel::SetCorrectModes(User *user, bool give_modes, bool check_noop) else if (voice && u_access.HasPriv("AUTOVOICE")) this->SetMode(NULL, "VOICE", user->GetUID()); } - /* If this channel has secureops or the channel is syncing and they are not ulined, check to remove modes */ - if ((ci->HasExt("SECUREOPS") || (this->HasExt("SYNCING") && user->server->IsSynced())) && !user->server->IsULined()) + /* If this channel has secureops, or the registered channel mode exists and the channel does not have +r set (aka the channel + * was created just now or while we were off), or the registered channel mode does not exist and channel is syncing (aka just + * created *to us*) and the user's server is synced (aka this isn't us doing our initial uplink - without this we would be deopping all + * users with no access on a non-secureops channel on startup), and the user's server isn't ulined, then set negative modes. + */ + if ((ci->HasExt("SECUREOPS") || (registered && !this->HasMode("REGISTERED")) || (!registered && this->HasExt("SYNCING") && user->server->IsSynced())) && !user->server->IsULined()) { if (owner && !u_access.HasPriv("AUTOOWNER") && !u_access.HasPriv("OWNERME")) this->RemoveMode(NULL, "OWNER", user->GetUID()); diff --git a/src/messages.cpp b/src/messages.cpp index 6a60d9cd9..dc11b99b4 100644 --- a/src/messages.cpp +++ b/src/messages.cpp @@ -107,7 +107,10 @@ void Join::SJoin(MessageSource &source, const Anope::string &chan, time_t ts, co /* Update the modes for the channel */ if (keep_their_modes && !modes.empty()) - c->SetModesInternal(source, modes); + /* If we are syncing, mlock is checked later in Channel::Sync. It is important to not check it here + * so that Channel::SetCorrectModes can correctly detect the presence of channel mode +r. + */ + c->SetModesInternal(source, modes, ts, !c->HasExt("SYNCING")); for (std::list::const_iterator it = users.begin(), it_end = users.end(); it != it_end; ++it) {