X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fchannels.cpp;h=6c70259bcea4a78bbfc5379d27c81629edd87ae9;hb=1fb8a3f1b120db764375911be9ad8019a807a8ad;hp=b8195ee9f6c4475c8b64a6fae8c2310b8daedce3;hpb=f209cce90b394acd26e22eacef0bff61e8f5b4e1;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/channels.cpp b/src/channels.cpp index b8195ee9f..6c70259bc 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -3,7 +3,7 @@ * +------------------------------------+ * * InspIRCd: (C) 2002-2009 InspIRCd Development Team - * See: http://www.inspircd.org/wiki/index.php/Credits + * See: http://wiki.inspircd.org/Credits * * This program is free but copyrighted software; see * the file COPYING for details. @@ -34,27 +34,22 @@ Channel::Channel(InspIRCd* Instance, const std::string &cname, time_t ts) : Serv void Channel::SetMode(char mode,bool mode_on) { modes[mode-65] = mode_on; - if (!mode_on) - this->SetModeParam(mode,"",false); } - -void Channel::SetModeParam(char mode,const char* parameter,bool mode_on) +void Channel::SetModeParam(char mode, std::string parameter) { CustomModeList::iterator n = custom_mode_params.find(mode); - - if (mode_on) + // always erase, even if changing, so that the map gets the new value + if (n != custom_mode_params.end()) + custom_mode_params.erase(n); + if (parameter.empty()) { - if (n == custom_mode_params.end()) - custom_mode_params[mode] = strdup(parameter); + modes[mode-65] = false; } else { - if (n != custom_mode_params.end()) - { - free(n->second); - custom_mode_params.erase(n); - } + custom_mode_params[mode] = parameter; + modes[mode-65] = true; } } @@ -248,7 +243,8 @@ void Channel::SetDefaultModes() */ Channel* Channel::JoinUser(InspIRCd* Instance, User *user, const char* cn, bool override, const char* key, bool bursting, time_t TS) { - if (!user || !cn) + // Fix: unregistered users could be joined using /SAJOIN + if (!user || !cn || user->registered != REG_ALL) return NULL; char cname[MAXBUF]; @@ -265,15 +261,7 @@ Channel* Channel::JoinUser(InspIRCd* Instance, User *user, const char* cn, bool if (IS_LOCAL(user) && !override) { // Checking MyClass exists because we *may* get here with NULL, not 100% sure. - if (user->MyClass && user->MyClass->GetMaxChans()) - { - if (user->chans.size() >= user->MyClass->GetMaxChans()) - { - user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s %s :You are on too many channels",user->nick.c_str(), cn); - return NULL; - } - } - else + if (user->MyClass && user->MyClass->maxchans) { if (user->HasPrivPermission("channels/high-join-limit")) { @@ -285,7 +273,7 @@ Channel* Channel::JoinUser(InspIRCd* Instance, User *user, const char* cn, bool } else { - if (user->chans.size() >= Instance->Config->MaxChans) + if (user->chans.size() >= user->MyClass->maxchans) { user->WriteNumeric(ERR_TOOMANYCHANNELS, "%s %s :You are on too many channels",user->nick.c_str(), cn); return NULL; @@ -393,13 +381,10 @@ Channel* Channel::JoinUser(InspIRCd* Instance, User *user, const char* cn, bool } } - if (Ptr->bans.size()) + if (Ptr->IsBanned(user) && !can_bypass) { - if (Ptr->IsBanned(user) && !can_bypass) - { - user->WriteNumeric(ERR_BANNEDFROMCHAN, "%s %s :Cannot join channel (You're banned)",user->nick.c_str(), Ptr->name.c_str()); - return NULL; - } + user->WriteNumeric(ERR_BANNEDFROMCHAN, "%s %s :Cannot join channel (You're banned)",user->nick.c_str(), Ptr->name.c_str()); + return NULL; } /* @@ -481,6 +466,10 @@ Channel* Channel::ForceChan(InspIRCd* Instance, Channel* Ptr, User* user, const user->WriteNumeric(RPL_TOPIC, "%s %s :%s", user->nick.c_str(), Ptr->name.c_str(), Ptr->topic.c_str()); user->WriteNumeric(RPL_TOPICTIME, "%s %s %s %lu", user->nick.c_str(), Ptr->name.c_str(), Ptr->setby.c_str(), (unsigned long)Ptr->topicset); } + else + { + user->WriteNumeric(RPL_NOTOPICSET, "%s %s :No topic is set", user->nick.c_str(), Ptr->name.c_str()); + } Ptr->UserList(user); } FOREACH_MOD_I(Instance,I_OnPostJoin,OnPostJoin(user, Ptr)); @@ -489,78 +478,73 @@ Channel* Channel::ForceChan(InspIRCd* Instance, Channel* Ptr, User* user, const bool Channel::IsBanned(User* user) { - char mask[MAXBUF]; - int MOD_RESULT = 0; - FOREACH_RESULT(I_OnCheckBan,OnCheckBan(user, this)); + int result = 0; + FOREACH_RESULT_MAP(I_OnCheckBan, OnCheckBan(user, this), + result = banmatch_reduce(result, MOD_RESULT); + ); - if (MOD_RESULT == -1) - return true; - else if (MOD_RESULT == 0) + if (result) + return (result < 0); + + char mask[MAXBUF]; + snprintf(mask, MAXBUF, "%s!%s@%s", user->nick.c_str(), user->ident.c_str(), user->GetIPString()); + for (BanList::iterator i = this->bans.begin(); i != this->bans.end(); i++) { - snprintf(mask, MAXBUF, "%s!%s@%s", user->nick.c_str(), user->ident.c_str(), user->GetIPString()); - for (BanList::iterator i = this->bans.begin(); i != this->bans.end(); i++) + if ((InspIRCd::Match(user->GetFullHost(),i->data, NULL)) || // host + (InspIRCd::Match(user->GetFullRealHost(),i->data, NULL)) || // uncloaked host + (InspIRCd::MatchCIDR(mask, i->data, NULL))) // ip { - if ((InspIRCd::Match(user->GetFullHost(),i->data, NULL)) || // host - (InspIRCd::Match(user->GetFullRealHost(),i->data, NULL)) || // uncloaked host - (InspIRCd::MatchCIDR(mask, i->data, NULL))) // ip - { - return true; - } + return true; } } return false; } -bool Channel::IsExtBanned(const std::string &str, char type) +int Channel::GetExtBanStatus(const std::string &str, char type) { - int MOD_RESULT = 0; - FOREACH_RESULT(I_OnCheckStringExtBan, OnCheckStringExtBan(str, this, type)); + int result = 0; + FOREACH_RESULT_MAP(I_OnCheckStringExtBan, OnCheckStringExtBan(str, this, type), + result = banmatch_reduce(result, MOD_RESULT); + ); + + if (result) + return result; - if (MOD_RESULT == -1) - return true; - else if (MOD_RESULT == 0) + // nobody decided for us, check the ban list + for (BanList::iterator i = this->bans.begin(); i != this->bans.end(); i++) { - for (BanList::iterator i = this->bans.begin(); i != this->bans.end(); i++) - { - if (i->data[0] != type || i->data[1] != ':') - continue; + if (i->data[0] != type || i->data[1] != ':') + continue; - // Iterate past char and : to get to the mask without doing a data copy(!) - std::string maskptr = i->data.substr(2); - ServerInstance->Logs->Log("EXTBANS", DEBUG, "Checking %s against %s, type is %c", str.c_str(), maskptr.c_str(), type); + std::string maskptr = i->data.substr(2); + ServerInstance->Logs->Log("EXTBANS", DEBUG, "Checking %s against %s, type is %c", str.c_str(), maskptr.c_str(), type); - if (InspIRCd::Match(str, maskptr, NULL)) - return true; - } + if (InspIRCd::Match(str, maskptr, NULL)) + return -1; } - return false; + return 0; } -bool Channel::IsExtBanned(User *user, char type) +int Channel::GetExtBanStatus(User *user, char type) { - int MOD_RESULT = 0; - FOREACH_RESULT(I_OnCheckExtBan, OnCheckExtBan(user, this, type)); - - if (MOD_RESULT == -1) - return true; - else if (MOD_RESULT == 0) - { - char mask[MAXBUF]; - snprintf(mask, MAXBUF, "%s!%s@%s", user->nick.c_str(), user->ident.c_str(), user->GetIPString()); - - // XXX: we should probably hook cloaked hosts in here somehow too.. - if (this->IsExtBanned(mask, type)) - return true; + int result = 0; + FOREACH_RESULT_MAP(I_OnCheckExtBan, OnCheckExtBan(user, this, type), + result = banmatch_reduce(result, MOD_RESULT); + ); - if (this->IsExtBanned(user->GetFullHost(), type)) - return true; + if (result) + return result; - if (this->IsExtBanned(user->GetFullRealHost(), type)) - return true; - } - - return false; + char mask[MAXBUF]; + int rv = 0; + snprintf(mask, MAXBUF, "%s!%s@%s", user->nick.c_str(), user->ident.c_str(), user->GetIPString()); + + // XXX: we should probably hook cloaked hosts in here somehow too.. + rv = banmatch_reduce(rv, this->GetExtBanStatus(mask, type)); + rv = banmatch_reduce(rv, this->GetExtBanStatus(user->GetFullHost(), type)); + rv = banmatch_reduce(rv, this->GetExtBanStatus(user->GetFullRealHost(), type)); + return rv; } /* Channel::PartUser @@ -605,57 +589,13 @@ long Channel::PartUser(User *user, std::string &reason) return this->GetUserCounter(); } -long Channel::ServerKickUser(User* user, const char* reason, bool triggerevents, const char* servername) +long Channel::ServerKickUser(User* user, const char* reason, const char* servername) { - bool silent = false; - - if (!user || !reason) - return this->GetUserCounter(); - - if (IS_LOCAL(user)) - { - if (!this->HasUser(user)) - { - /* Not on channel */ - return this->GetUserCounter(); - } - } - if (servername == NULL || *ServerInstance->Config->HideWhoisServer) servername = ServerInstance->Config->ServerName; - if (triggerevents) - { - FOREACH_MOD(I_OnUserKick,OnUserKick(NULL, user, this, reason, silent)); - } - - UCListIter i = user->chans.find(this); - if (i != user->chans.end()) - { - if (!silent) - this->WriteChannelWithServ(servername, "KICK %s %s :%s", this->name.c_str(), user->nick.c_str(), reason); - - user->chans.erase(i); - this->RemoveAllPrefixes(user); - } - - if (!this->DelUser(user)) - { - chan_hash::iterator iter = ServerInstance->chanlist->find(this->name); - /* kill the record */ - if (iter != ServerInstance->chanlist->end()) - { - int MOD_RESULT = 0; - FOREACH_RESULT_I(ServerInstance,I_OnChannelPreDelete, OnChannelPreDelete(this)); - if (MOD_RESULT == 1) - return 1; // delete halted by module - FOREACH_MOD(I_OnChannelDelete, OnChannelDelete(this)); - ServerInstance->chanlist->erase(iter); - } - return 0; - } - - return this->GetUserCounter(); + ServerInstance->FakeClient->server = servername; + return this->KickUser(ServerInstance->FakeClient, user, reason); } long Channel::KickUser(User *src, User *user, const char* reason)