diff options
Diffstat (limited to 'src/users.cpp')
-rw-r--r-- | src/users.cpp | 198 |
1 files changed, 107 insertions, 91 deletions
diff --git a/src/users.cpp b/src/users.cpp index dfb386871..bcf50a1ff 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -225,11 +225,9 @@ User::User(const std::string &uid) { server = ServerInstance->Config->ServerName; age = ServerInstance->Time(); - Penalty = 0; - lastping = signon = idle_lastmsg = nping = registered = 0; + signon = idle_lastmsg = registered = 0; quietquit = quitting = exempt = dns_done = false; fd = -1; - AllowedPrivs = AllowedOperCommands = NULL; uuid = uid; client_sa.sa.sa_family = AF_UNSPEC; @@ -244,8 +242,11 @@ User::User(const std::string &uid) LocalUser::LocalUser() : User(ServerInstance->GetUID()) { + AllowedPrivs = AllowedOperCommands = NULL; bytes_in = bytes_out = cmds_in = cmds_out = 0; server_sa.sa.sa_family = AF_UNSPEC; + Penalty = 0; + lastping = nping = 0; } User::~User() @@ -350,7 +351,7 @@ const std::string User::GetFullRealHost() return this->cached_fullrealhost; } -bool User::IsInvited(const irc::string &channel) +bool LocalUser::IsInvited(const irc::string &channel) { time_t now = ServerInstance->Time(); InvitedList::iterator safei; @@ -372,7 +373,7 @@ bool User::IsInvited(const irc::string &channel) return false; } -InvitedList* User::GetInviteList() +InvitedList* LocalUser::GetInviteList() { time_t now = ServerInstance->Time(); /* Weed out expired invites here. */ @@ -390,7 +391,7 @@ InvitedList* User::GetInviteList() return &invites; } -void User::InviteTo(const irc::string &channel, time_t invtimeout) +void LocalUser::InviteTo(const irc::string &channel, time_t invtimeout) { time_t now = ServerInstance->Time(); if (invtimeout != 0 && now > invtimeout) return; /* Don't add invites that are expired from the get-go. */ @@ -409,7 +410,7 @@ void User::InviteTo(const irc::string &channel, time_t invtimeout) invites.push_back(std::make_pair(channel, invtimeout)); } -void User::RemoveInvite(const irc::string &channel) +void LocalUser::RemoveInvite(const irc::string &channel) { for (InvitedList::iterator i = invites.begin(); i != invites.end(); i++) { @@ -421,11 +422,13 @@ void User::RemoveInvite(const irc::string &channel) } } -bool User::HasModePermission(unsigned char mode, ModeType type) +bool User::HasModePermission(unsigned char, ModeType) { - if (!IS_LOCAL(this)) - return true; + return true; +} +bool LocalUser::HasModePermission(unsigned char mode, ModeType type) +{ if (!IS_OPER(this)) return false; @@ -434,19 +437,20 @@ bool User::HasModePermission(unsigned char mode, ModeType type) return ((type == MODETYPE_USER ? AllowedUserModes : AllowedChanModes))[(mode - 'A')]; } - -bool User::HasPermission(const std::string &command) +/* + * users on remote servers can completely bypass all permissions based checks. + * This prevents desyncs when one server has different type/class tags to another. + * That having been said, this does open things up to the possibility of source changes + * allowing remote kills, etc - but if they have access to the src, they most likely have + * access to the conf - so it's an end to a means either way. + */ +bool User::HasPermission(const std::string&) { - /* - * users on remote servers can completely bypass all permissions based checks. - * This prevents desyncs when one server has different type/class tags to another. - * That having been said, this does open things up to the possibility of source changes - * allowing remote kills, etc - but if they have access to the src, they most likely have - * access to the conf - so it's an end to a means either way. - */ - if (!IS_LOCAL(this)) - return true; + return true; +} +bool LocalUser::HasPermission(const std::string &command) +{ // are they even an oper at all? if (!IS_OPER(this)) { @@ -464,15 +468,13 @@ bool User::HasPermission(const std::string &command) return false; } - bool User::HasPrivPermission(const std::string &privstr, bool noisy) { - if (!IS_LOCAL(this)) - { - ServerInstance->Logs->Log("PRIVS", DEBUG, "Remote (yes)"); - return true; - } + return true; +} +bool LocalUser::HasPrivPermission(const std::string &privstr, bool noisy) +{ if (!IS_OPER(this)) { if (noisy) @@ -510,14 +512,14 @@ void LocalUser::OnDataReady() if (quitting) return; - if (MyClass && recvq.length() > MyClass->GetRecvqMax() && !HasPrivPermission("users/flood/increased-buffers")) + if (recvq.length() > MyClass->GetRecvqMax() && !HasPrivPermission("users/flood/increased-buffers")) { ServerInstance->Users->QuitUser(this, "RecvQ exceeded"); ServerInstance->SNO->WriteToSnoMask('a', "User %s RecvQ of %lu exceeds connect class maximum of %lu", nick.c_str(), (unsigned long)recvq.length(), MyClass->GetRecvqMax()); } unsigned long sendqmax = ULONG_MAX; - if (MyClass && !HasPrivPermission("users/flood/increased-buffers")) + if (!HasPrivPermission("users/flood/increased-buffers")) sendqmax = MyClass->GetSendqSoftMax(); int penaltymax = MyClass->GetPenaltyThreshold(); if (penaltymax == 0 || HasPrivPermission("users/flood/no-fakelag")) @@ -566,7 +568,7 @@ eol_found: void LocalUser::AddWriteBuf(const std::string &data) { - if (!quitting && MyClass && getSendQSize() + data.length() > MyClass->GetSendqHardMax() && !HasPrivPermission("users/flood/increased-buffers")) + if (!quitting && getSendQSize() + data.length() > MyClass->GetSendqHardMax() && !HasPrivPermission("users/flood/increased-buffers")) { /* * Quit the user FIRST, because otherwise we could recurse @@ -602,18 +604,6 @@ CullResult User::cull() if (IS_LOCAL(this) && fd != INT_MAX) Close(); - if (this->AllowedOperCommands) - { - delete AllowedOperCommands; - AllowedOperCommands = NULL; - } - - if (this->AllowedPrivs) - { - delete AllowedPrivs; - AllowedPrivs = NULL; - } - this->InvalidateCache(); this->DecrementModes(); @@ -630,6 +620,18 @@ CullResult LocalUser::cull() else ServerInstance->Logs->Log("USERS", DEBUG, "Failed to remove user from vector"); + if (this->AllowedOperCommands) + { + delete AllowedOperCommands; + AllowedOperCommands = NULL; + } + + if (this->AllowedPrivs) + { + delete AllowedPrivs; + AllowedPrivs = NULL; + } + if (client_sa.sa.sa_family != AF_UNSPEC) ServerInstance->Users->RemoveCloneCounts(this); return User::cull(); @@ -651,6 +653,14 @@ void User::Oper(const std::string &opertype, const std::string &opername) this->oper.assign(opertype, 0, 512); ServerInstance->Users->all_opers.push_back(this); + if (IS_LOCAL(this)) + IS_LOCAL(this)->OperInternal(); + + FOREACH_MOD(I_OnPostOper,OnPostOper(this, opertype, opername)); +} + +void LocalUser::OperInternal() +{ /* * This might look like it's in the wrong place. * It is *not*! @@ -721,60 +731,64 @@ void User::Oper(const std::string &opertype, const std::string &opername) } } } - - FOREACH_MOD(I_OnPostOper,OnPostOper(this, opertype, opername)); } void User::UnOper() { - if (IS_OPER(this)) - { - /* - * unset their oper type (what IS_OPER checks). - * note, order is important - this must come before modes as -o attempts - * to call UnOper. -- w00t - */ - this->oper.clear(); + if (!IS_OPER(this)) + return; + /* + * unset their oper type (what IS_OPER checks). + * note, order is important - this must come before modes as -o attempts + * to call UnOper. -- w00t + */ + this->oper.clear(); - /* Remove all oper only modes from the user when the deoper - Bug #466*/ - std::string moderemove("-"); - for (unsigned char letter = 'A'; letter <= 'z'; letter++) - { - ModeHandler* mh = ServerInstance->Modes->FindMode(letter, MODETYPE_USER); - if (mh && mh->NeedsOper()) - moderemove += letter; - } + /* Remove all oper only modes from the user when the deoper - Bug #466*/ + std::string moderemove("-"); + for (unsigned char letter = 'A'; letter <= 'z'; letter++) + { + ModeHandler* mh = ServerInstance->Modes->FindMode(letter, MODETYPE_USER); + if (mh && mh->NeedsOper()) + moderemove += letter; + } - std::vector<std::string> parameters; - parameters.push_back(this->nick); - parameters.push_back(moderemove); - ServerInstance->Parser->CallHandler("MODE", parameters, this); + std::vector<std::string> parameters; + parameters.push_back(this->nick); + parameters.push_back(moderemove); - /* remove the user from the oper list. Will remove multiple entries as a safeguard against bug #404 */ - ServerInstance->Users->all_opers.remove(this); + ServerInstance->Parser->CallHandler("MODE", parameters, this); - if (AllowedOperCommands) - { - delete AllowedOperCommands; - AllowedOperCommands = NULL; - } + /* remove the user from the oper list. Will remove multiple entries as a safeguard against bug #404 */ + ServerInstance->Users->all_opers.remove(this); - if (AllowedPrivs) - { - delete AllowedPrivs; - AllowedPrivs = NULL; - } + if (IS_LOCAL(this)) + IS_LOCAL(this)->UnOperInternal(); + this->modes[UM_OPERATOR] = 0; +} - AllowedUserModes.reset(); - AllowedChanModes.reset(); - this->modes[UM_OPERATOR] = 0; +void LocalUser::UnOperInternal() +{ + if (AllowedOperCommands) + { + delete AllowedOperCommands; + AllowedOperCommands = NULL; + } + + if (AllowedPrivs) + { + delete AllowedPrivs; + AllowedPrivs = NULL; } + AllowedUserModes.reset(); + AllowedChanModes.reset(); } + /* adds or updates an entry in the whowas list */ void User::AddToWhoWas() { @@ -790,11 +804,15 @@ void User::AddToWhoWas() /* * Check class restrictions */ -void User::CheckClass() +void LocalUser::CheckClass() { ConnectClass* a = this->MyClass; - if ((!a) || (a->type == CC_DENY)) + if (!a) + { + ServerInstance->Users->QuitUser(this, "Access denied by configuration"); + } + else if (a->type == CC_DENY) { ServerInstance->Users->QuitUser(this, "Unauthorised connection"); return; @@ -852,7 +870,7 @@ void LocalUser::FullConnect() /* Check the password, if one is required by the user's connect class. * This CANNOT be in CheckClass(), because that is called prior to PASS as well! */ - if (MyClass && !MyClass->pass.empty()) + if (!MyClass->pass.empty()) { if (ServerInstance->PassCompare(this, MyClass->pass.c_str(), password.c_str(), MyClass->hash.c_str())) { @@ -1641,7 +1659,7 @@ void User::SplitChanList(User* dest, const std::string &cl) * then their ip will be taken as 'priority' anyway, so for example, * <connect allow="127.0.0.1"> will match joe!bloggs@localhost */ -ConnectClass* LocalUser::SetClass(const std::string &explicit_name) +void LocalUser::SetClass(const std::string &explicit_name) { ConnectClass *found = NULL; @@ -1719,8 +1737,6 @@ ConnectClass* LocalUser::SetClass(const std::string &explicit_name) { MyClass = found; } - - return this->MyClass; } /* looks up a users password for their connection class (<ALLOW>/<DENY> tags) @@ -1728,9 +1744,14 @@ ConnectClass* LocalUser::SetClass(const std::string &explicit_name) * then their ip will be taken as 'priority' anyway, so for example, * <connect allow="127.0.0.1"> will match joe!bloggs@localhost */ +ConnectClass* LocalUser::GetClass() +{ + return MyClass; +} + ConnectClass* User::GetClass() { - return this->MyClass; + return NULL; } void User::PurgeEmptyChannels() @@ -1776,11 +1797,6 @@ void User::ShowRULES() this->WriteNumeric(RPL_RULESEND, "%s :End of RULES command.",this->nick.c_str()); } -void User::IncreasePenalty(int increase) -{ - this->Penalty += increase; -} - void FakeUser::SetFakeServer(std::string name) { this->nick = name; |