X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fusers.cpp;h=b3e6ef58f32b3efa082b4c8c0bc3f120b250e4b0;hb=36cb60f872712e8e5a59df74b5b36177addc4248;hp=2e4a49c3fe60db2821dd073a645005208e0d0eae;hpb=d8ee5433eab5c67e9094d9114e3696728f1cab2a;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/users.cpp b/src/users.cpp index 2e4a49c3f..b3e6ef58f 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -245,6 +245,8 @@ User::~User() { this->MyClass->RefCount--; ServerInstance->Logs->Log("USERS", DEBUG, "User destructor -- connect refcount now: %lu", this->MyClass->RefCount); + if (MyClass->RefCount == 0) + delete MyClass; } if (this->AllowedOperCommands) @@ -518,7 +520,6 @@ bool User::HasPermission(const std::string &command) bool User::HasPrivPermission(const std::string &privstr, bool noisy) { - ServerInstance->Logs->Log("PRIVS", DEBUG, "Checking if I have " + privstr); if (!IS_LOCAL(this)) { ServerInstance->Logs->Log("PRIVS", DEBUG, "Remote (yes)"); @@ -529,7 +530,6 @@ bool User::HasPrivPermission(const std::string &privstr, bool noisy) { if (noisy) this->WriteServ("NOTICE %s :You are not an oper", this->nick.c_str()); - ServerInstance->Logs->Log("PRIVS", DEBUG, "Not oper (no)"); return false; } @@ -537,7 +537,6 @@ bool User::HasPrivPermission(const std::string &privstr, bool noisy) { if (noisy) this->WriteServ("NOTICE %s :Privset empty(!?)", this->nick.c_str()); - ServerInstance->Logs->Log("PRIVS", DEBUG, "No privs(?) (no)"); return false; } @@ -747,13 +746,6 @@ void User::Oper(const std::string &opertype, const std::string &opername) if (this->IsModeSet('o')) this->UnOper(); - opertype_t::iterator iter_opertype = ServerInstance->Config->opertypes.find(this->oper.c_str()); - if (iter_opertype == ServerInstance->Config->opertypes.end()) - { - ServerInstance->Logs->Log("OPER", DEBUG, "%s!%s@%s opered as type: %s which didn't exist, failing", this->nick.c_str(), this->ident.c_str(), this->host.c_str(), opertype.c_str()); - return; - } - this->modes[UM_OPERATOR] = 1; this->WriteServ("MODE %s :+o", this->nick.c_str()); FOREACH_MOD(I_OnOper, OnOper(this, opertype)); @@ -765,61 +757,72 @@ 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 (AllowedOperCommands) - AllowedOperCommands->clear(); - else - AllowedOperCommands = new std::set; + /* + * This might look like it's in the wrong place. + * It is *not*! + * + * For multi-network servers, we may not have the opertypes of the remote server, but we still want to mark the user as an oper of that type. + * -- w00t + */ + opertype_t::iterator iter_opertype = ServerInstance->Config->opertypes.find(this->oper.c_str()); + if (iter_opertype != ServerInstance->Config->opertypes.end()) + { + if (AllowedOperCommands) + AllowedOperCommands->clear(); + else + AllowedOperCommands = new std::set; - if (AllowedPrivs) - AllowedPrivs->clear(); - else - AllowedPrivs = new std::set; + if (AllowedPrivs) + AllowedPrivs->clear(); + else + AllowedPrivs = new std::set; - AllowedUserModes.reset(); - AllowedChanModes.reset(); - this->AllowedUserModes['o' - 'A'] = true; // Call me paranoid if you want. + AllowedUserModes.reset(); + AllowedChanModes.reset(); + this->AllowedUserModes['o' - 'A'] = true; // Call me paranoid if you want. - std::string myclass, mycmd, mypriv; - irc::spacesepstream Classes(iter_opertype->second.c_str()); - while (Classes.GetToken(myclass)) - { - operclass_t::iterator iter_operclass = ServerInstance->Config->operclass.find(myclass.c_str()); - if (iter_operclass != ServerInstance->Config->operclass.end()) + std::string myclass, mycmd, mypriv; + irc::spacesepstream Classes(iter_opertype->second.c_str()); + while (Classes.GetToken(myclass)) { - /* Process commands */ - irc::spacesepstream CommandList(iter_operclass->second.commandlist); - while (CommandList.GetToken(mycmd)) + operclass_t::iterator iter_operclass = ServerInstance->Config->operclass.find(myclass.c_str()); + if (iter_operclass != ServerInstance->Config->operclass.end()) { - this->AllowedOperCommands->insert(mycmd); - } - - irc::spacesepstream PrivList(iter_operclass->second.privs); - while (PrivList.GetToken(mypriv)) - { - this->AllowedPrivs->insert(mypriv); - } - - for (unsigned char* c = (unsigned char*)iter_operclass->second.umodelist; *c; ++c) - { - if (*c == '*') + /* Process commands */ + irc::spacesepstream CommandList(iter_operclass->second.commandlist); + while (CommandList.GetToken(mycmd)) { - this->AllowedUserModes.set(); + this->AllowedOperCommands->insert(mycmd); } - else + + irc::spacesepstream PrivList(iter_operclass->second.privs); + while (PrivList.GetToken(mypriv)) { - this->AllowedUserModes[*c - 'A'] = true; + this->AllowedPrivs->insert(mypriv); } - } - for (unsigned char* c = (unsigned char*)iter_operclass->second.cmodelist; *c; ++c) - { - if (*c == '*') + for (unsigned char* c = (unsigned char*)iter_operclass->second.umodelist; *c; ++c) { - this->AllowedChanModes.set(); + if (*c == '*') + { + this->AllowedUserModes.set(); + } + else + { + this->AllowedUserModes[*c - 'A'] = true; + } } - else + + for (unsigned char* c = (unsigned char*)iter_operclass->second.cmodelist; *c; ++c) { - this->AllowedChanModes[*c - 'A'] = true; + if (*c == '*') + { + this->AllowedChanModes.set(); + } + else + { + this->AllowedChanModes[*c - 'A'] = true; + } } } } @@ -897,7 +900,7 @@ void User::CheckClass() { ConnectClass* a = this->MyClass; - if ((!a) || (a->GetType() == CC_DENY)) + if ((!a) || (a->type == CC_DENY)) { ServerInstance->Users->QuitUser(this, "Unauthorised connection"); return; @@ -1835,10 +1838,7 @@ ConnectClass* User::SetClass(const std::string &explicit_name) { ConnectClass* c = *i; - if (c->GetDisabled()) - continue; // can't possibly match, removed from conf - - if (explicit_name == c->GetName()) + if (explicit_name == c->name) { ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "Explicitly set to %s", explicit_name.c_str()); found = c; @@ -1851,22 +1851,15 @@ ConnectClass* User::SetClass(const std::string &explicit_name) { ConnectClass* c = *i; - if (c->GetType() == CC_ALLOW) + if (c->type == CC_ALLOW) { - ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "ALLOW %s %d %s", c->GetHost().c_str(), c->GetPort(), c->GetName().c_str()); + ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "ALLOW %s %d %s", c->host.c_str(), c->GetPort(), c->GetName().c_str()); } else { ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "DENY %s %d %s", c->GetHost().c_str(), c->GetPort(), c->GetName().c_str()); } - /* if it's disabled, we can't match this one. */ - if (c->GetDisabled()) - { - ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "Class disabled"); - continue; - } - /* check if host matches.. */ if (c->GetHost().length() && !InspIRCd::MatchCIDR(this->GetIPString(), c->GetHost(), NULL) && !InspIRCd::MatchCIDR(this->host, c->GetHost(), NULL)) @@ -1879,7 +1872,7 @@ ConnectClass* User::SetClass(const std::string &explicit_name) * deny change if change will take class over the limit check it HERE, not after we found a matching class, * because we should attempt to find another class if this one doesn't match us. -- w00t */ - if (c->limit && (c->RefCount + 1 >= c->limit)) + if (c->limit && (c->RefCount >= c->limit)) { ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "OOPS: Connect class limit (%lu) hit, denying", c->limit); continue; @@ -1916,6 +1909,8 @@ ConnectClass* User::SetClass(const std::string &explicit_name) return this->MyClass; this->MyClass->RefCount--; ServerInstance->Logs->Log("USERS", DEBUG, "Untying user from connect class -- refcount: %lu", this->MyClass->RefCount); + if (MyClass->RefCount == 0) + delete MyClass; } this->MyClass = found; @@ -2080,3 +2075,29 @@ bool VisData::VisibleTo(User* user) { return true; } + + +ConnectClass::ConnectClass(char t, const std::string& mask) + : type(t), name("unnamed"), registration_timeout(0), host(mask), pingtime(0), pass(""), hash(""), sendqmax(0), recvqmax(0), maxlocal(0), maxglobal(0), maxchans(0), port(0), limit(0), RefCount(1) +{ +} + +ConnectClass::ConnectClass(char t, const std::string& mask, const ConnectClass& parent) + : type(t), name("unnamed"), registration_timeout(parent.registration_timeout), host(mask), pingtime(parent.pingtime), pass(parent.pass), hash(parent.hash), sendqmax(parent.sendqmax), recvqmax(parent.recvqmax), maxlocal(parent.maxlocal), maxglobal(parent.maxglobal), maxchans(parent.maxchans), port(parent.port), limit(parent.limit), RefCount(1) +{ +} + +void ConnectClass::Update(const ConnectClass* src) +{ + name = src->name; + registration_timeout = src->registration_timeout; + host = src->host; + pingtime = src->pingtime; + pass = src->pass; + hash = src->hash; + sendqmax = src->sendqmax; + recvqmax = src->recvqmax; + maxlocal = src->maxlocal; + maxglobal = src->maxglobal; + limit = src->limit; +}