X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fusers.cpp;h=43ebfe0a3a2df1d6ac71b648d6afb0d498f7537f;hb=20680f9c4964a5e10e3649a1e479078ff85c5c85;hp=f1c3a3fef01577472921287d85dfb34cdf1b1e7c;hpb=da074814501f23680b579feb1ad649c86e8a1348;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/users.cpp b/src/users.cpp index f1c3a3fef..43ebfe0a3 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -73,6 +73,9 @@ std::string User::ProcessNoticeMasks(const char *sm) output += *c; } } + else + this->WriteNumeric(501, "%s %c :is unknown snomask char to me", this->nick, *c); + oldadding = adding; break; } @@ -190,7 +193,11 @@ User::User(InspIRCd* Instance, const std::string &uid) : ServerInstance(Instance Visibility = NULL; ip = NULL; MyClass = NULL; + AllowedUserModes = NULL; + AllowedChanModes = NULL; AllowedOperCommands = NULL; + memset(AllowedUserModes, 0, sizeof(AllowedUserModes)); + memset(AllowedChanModes, 0, sizeof(AllowedChanModes)); chans.clear(); invites.clear(); memset(modes,0,sizeof(modes)); @@ -226,6 +233,18 @@ User::~User() AllowedOperCommands = NULL; } + if (this->AllowedUserModes) + { + delete AllowedUserModes; + AllowedUserModes = NULL; + } + + if (this->AllowedChanModes) + { + delete AllowedChanModes; + AllowedChanModes = NULL; + } + this->InvalidateCache(); this->DecrementModes(); @@ -434,6 +453,21 @@ void User::RemoveInvite(const irc::string &channel) } } +bool User::HasModePermission(unsigned char mode, ModeType type) +{ + if (!IS_LOCAL(this)) + return true; + + if (!IS_OPER(this)) + return false; + + if (!AllowedUserModes || !AllowedChanModes) + return false; + + return ((type == MODETYPE_USER ? AllowedUserModes : AllowedChanModes))[(mode - 'A')]; + +} + bool User::HasPermission(const std::string &command) { /* @@ -666,6 +700,15 @@ void User::Oper(const std::string &opertype, const std::string &opername) else AllowedOperCommands = new std::map; + if (!AllowedChanModes) + AllowedChanModes = new bool[64]; + + if (!AllowedUserModes) + AllowedUserModes = new bool[64]; + + memset(AllowedUserModes, 0, 64); + memset(AllowedChanModes, 0, 64); + char* Classes = strdup(iter_opertype->second); char* myclass = strtok_r(Classes," ",&savept); while (myclass) @@ -673,7 +716,7 @@ void User::Oper(const std::string &opertype, const std::string &opername) operclass_t::iterator iter_operclass = ServerInstance->Config->operclass.find(myclass); if (iter_operclass != ServerInstance->Config->operclass.end()) { - char* CommandList = strdup(iter_operclass->second); + char* CommandList = strdup(iter_operclass->second.commandlist); mycmd = strtok_r(CommandList," ",&savept2); while (mycmd) { @@ -681,6 +724,29 @@ void User::Oper(const std::string &opertype, const std::string &opername) mycmd = strtok_r(NULL," ",&savept2); } free(CommandList); + this->AllowedUserModes['o' - 'A'] = true; // Call me paranoid if you want. + for (unsigned char* c = (unsigned char*)iter_operclass->second.umodelist; *c; ++c) + { + if (*c == '*') + { + memset(this->AllowedUserModes, (int)(true), sizeof(this->AllowedUserModes)); + } + else + { + this->AllowedUserModes[*c - 'A'] = true; + } + } + for (unsigned char* c = (unsigned char*)iter_operclass->second.cmodelist; *c; ++c) + { + if (*c == '*') + { + memset(this->AllowedChanModes, (int)(true), sizeof(this->AllowedChanModes)); + } + else + { + this->AllowedChanModes[*c - 'A'] = true; + } + } } myclass = strtok_r(NULL," ",&savept); } @@ -700,11 +766,27 @@ void User::UnOper() { if (IS_OPER(this)) { - // unset their oper type (what IS_OPER checks), and remove +o + /* Remove all oper only modes from the user when the deoper - Bug #466*/ + std::string moderemove("-"); + + for (unsigned char letter = 'A'; letter <= 'z'; letter++) + { + if (letter != 'o') + { + ModeHandler* mh = ServerInstance->Modes->FindMode(letter, MODETYPE_USER); + if (mh && mh->NeedsOper()) + moderemove += letter; + } + } + + const char* parameters[] = { this->nick, moderemove.c_str() }; + ServerInstance->Parser->CallHandler("MODE", parameters, 2, this); + + /* unset their oper type (what IS_OPER checks), and remove +o */ *this->oper = 0; this->modes[UM_OPERATOR] = 0; - // remove the user from the oper list. Will remove multiple entries as a safeguard against bug #404 + /* remove the user from the oper list. Will remove multiple entries as a safeguard against bug #404 */ ServerInstance->Users->all_opers.remove(this); if (AllowedOperCommands) @@ -814,14 +896,14 @@ void User::FullConnect() } this->WriteServ("NOTICE Auth :Welcome to \002%s\002!",ServerInstance->Config->Network); - this->WriteServ("001 %s :Welcome to the %s IRC Network %s!%s@%s",this->nick, ServerInstance->Config->Network, this->nick, this->ident, this->host); - this->WriteServ("002 %s :Your host is %s, running version %s",this->nick,ServerInstance->Config->ServerName,VERSION); - this->WriteServ("003 %s :This server was created %s %s", this->nick, __TIME__, __DATE__); - this->WriteServ("004 %s %s %s %s %s %s", this->nick, ServerInstance->Config->ServerName, VERSION, ServerInstance->Modes->UserModeList().c_str(), ServerInstance->Modes->ChannelModeList().c_str(), ServerInstance->Modes->ParaModeList().c_str()); + this->WriteNumeric(001, "%s :Welcome to the %s IRC Network %s!%s@%s",this->nick, ServerInstance->Config->Network, this->nick, this->ident, this->host); + this->WriteNumeric(002, "%s :Your host is %s, running version %s",this->nick,ServerInstance->Config->ServerName,VERSION); + this->WriteNumeric(003, "%s :This server was created %s %s", this->nick, __TIME__, __DATE__); + this->WriteNumeric(004, "%s %s %s %s %s %s", this->nick, ServerInstance->Config->ServerName, VERSION, ServerInstance->Modes->UserModeList().c_str(), ServerInstance->Modes->ChannelModeList().c_str(), ServerInstance->Modes->ParaModeList().c_str()); ServerInstance->Config->Send005(this); - this->WriteServ("042 %s %s :your unique ID", this->nick, this->uuid); + this->WriteNumeric(42, "%s %s :your unique ID", this->nick, this->uuid); this->ShowMOTD(); @@ -1134,6 +1216,32 @@ void User::WriteServ(const char* text, ...) } +void User::WriteNumeric(unsigned int numeric, const char* text, ...) +{ + va_list argsPtr; + char textbuffer[MAXBUF]; + + va_start(argsPtr, text); + vsnprintf(textbuffer, MAXBUF, text, argsPtr); + va_end(argsPtr); + + this->WriteNumeric(numeric, std::string(textbuffer)); +} + +void User::WriteNumeric(unsigned int numeric, const std::string &text) +{ + char textbuffer[MAXBUF]; + int MOD_RESULT = 0; + + FOREACH_RESULT(I_OnNumeric, OnNumeric(this, numeric, text)); + + if (MOD_RESULT) + return; + + snprintf(textbuffer,MAXBUF,":%s %03u %s",ServerInstance->Config->ServerName, numeric, text.c_str()); + this->Write(std::string(textbuffer)); +} + void User::WriteFrom(User *user, const std::string &text) { char tb[MAXBUF]; @@ -1419,7 +1527,7 @@ bool User::ChangeDisplayedHost(const char* shost) } if (IS_LOCAL(this)) - this->WriteServ("396 %s %s :is now your displayed host",this->nick,this->dhost); + this->WriteNumeric(396, "%s %s :is now your displayed host",this->nick,this->dhost); return true; } @@ -1663,31 +1771,31 @@ void User::ShowMOTD() { if (!ServerInstance->Config->MOTD.size()) { - this->WriteServ("422 %s :Message of the day file is missing.",this->nick); + this->WriteNumeric(422, "%s :Message of the day file is missing.",this->nick); return; } - this->WriteServ("375 %s :%s message of the day", this->nick, ServerInstance->Config->ServerName); + this->WriteNumeric(375, "%s :%s message of the day", this->nick, ServerInstance->Config->ServerName); for (file_cache::iterator i = ServerInstance->Config->MOTD.begin(); i != ServerInstance->Config->MOTD.end(); i++) - this->WriteServ("372 %s :- %s",this->nick,i->c_str()); + this->WriteNumeric(372, "%s :- %s",this->nick,i->c_str()); - this->WriteServ("376 %s :End of message of the day.", this->nick); + this->WriteNumeric(376, "%s :End of message of the day.", this->nick); } void User::ShowRULES() { if (!ServerInstance->Config->RULES.size()) { - this->WriteServ("434 %s :RULES File is missing",this->nick); + this->WriteNumeric(434, "%s :RULES File is missing",this->nick); return; } - this->WriteServ("308 %s :- %s Server Rules -",this->nick,ServerInstance->Config->ServerName); + this->WriteNumeric(308, "%s :- %s Server Rules -",this->nick,ServerInstance->Config->ServerName); for (file_cache::iterator i = ServerInstance->Config->RULES.begin(); i != ServerInstance->Config->RULES.end(); i++) - this->WriteServ("232 %s :- %s",this->nick,i->c_str()); + this->WriteNumeric(232, "%s :- %s",this->nick,i->c_str()); - this->WriteServ("309 %s :End of RULES command.",this->nick); + this->WriteNumeric(309, "%s :End of RULES command.",this->nick); } void User::HandleEvent(EventType et, int errornum)