X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fconfigreader.cpp;h=05171ea60d605de4b093ccf0df8ec2d6d57f236f;hb=26cd5393c9308fabe73c41870f06f73a5b001cd7;hp=a6d6e3c85e256d8f211ce3b1bdf210655c4313e1;hpb=6cfd6ad816d597a88abcbe6c6dc9d3e507aa539c;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/configreader.cpp b/src/configreader.cpp index a6d6e3c85..05171ea60 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -32,12 +32,8 @@ #include "commands/cmd_whowas.h" #include "modes/cmode_h.h" -ServerConfig::ServerConfig(InspIRCd* Instance) : ServerInstance(Instance) +ServerConfig::ServerConfig() { - *sid = *ServerName = *Network = *ServerDesc = *AdminName = '\0'; - *HideWhoisServer = *AdminEmail = *AdminNick = *diepass = *restartpass = *FixedQuit = *HideKillsServer = '\0'; - *DefaultModes = *CustomVersion = *motd = *rules = *PrefixQuit = *DieValue = *DNSServer = '\0'; - *UserStats = *DisabledCommands = *SuffixQuit = '\0'; WhoWasGroupSize = WhoWasMaxGroups = WhoWasMaxKeep = 0; log_file = NULL; NoUserDns = forcedebug = OperSpyWhois = nofork = HideBans = HideSplits = UndernetMsgPrefix = false; @@ -45,7 +41,7 @@ ServerConfig::ServerConfig(InspIRCd* Instance) : ServerInstance(Instance) dns_timeout = DieDelay = 5; MaxTargets = 20; NetBufferSize = 10240; - SoftLimit = Instance->SE->GetMaxFds(); + SoftLimit = ServerInstance->SE->GetMaxFds(); MaxConn = SOMAXCONN; MaxWhoResults = 0; debugging = 0; @@ -199,7 +195,7 @@ static bool ValidateMaxTargets(ServerConfig* conf, const char*, const char*, Val { if ((data.GetInteger() < 1) || (data.GetInteger() > 31)) { - conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"WARNING: value is greater than 31 or less than 1, set to 20."); + ServerInstance->Logs->Log("CONFIG",DEFAULT,"WARNING: value is greater than 31 or less than 1, set to 20."); data.Set(20); } return true; @@ -207,10 +203,10 @@ static bool ValidateMaxTargets(ServerConfig* conf, const char*, const char*, Val static bool ValidateSoftLimit(ServerConfig* conf, const char*, const char*, ValueItem &data) { - if ((data.GetInteger() < 1) || (data.GetInteger() > conf->GetInstance()->SE->GetMaxFds())) + if ((data.GetInteger() < 1) || (data.GetInteger() > ServerInstance->SE->GetMaxFds())) { - conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"WARNING: value is greater than %d or less than 0, set to %d.",conf->GetInstance()->SE->GetMaxFds(),conf->GetInstance()->SE->GetMaxFds()); - data.Set(conf->GetInstance()->SE->GetMaxFds()); + ServerInstance->Logs->Log("CONFIG",DEFAULT,"WARNING: value is greater than %d or less than 0, set to %d.",ServerInstance->SE->GetMaxFds(),ServerInstance->SE->GetMaxFds()); + data.Set(ServerInstance->SE->GetMaxFds()); } return true; } @@ -218,11 +214,11 @@ static bool ValidateSoftLimit(ServerConfig* conf, const char*, const char*, Valu static bool ValidateMaxConn(ServerConfig* conf, const char*, const char*, ValueItem &data) { if (data.GetInteger() > SOMAXCONN) - conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"WARNING: value may be higher than the system-defined SOMAXCONN value!"); + ServerInstance->Logs->Log("CONFIG",DEFAULT,"WARNING: value may be higher than the system-defined SOMAXCONN value!"); return true; } -bool ServerConfig::ApplyDisabledCommands(const char* data) +bool ServerConfig::ApplyDisabledCommands(const std::string& data) { std::stringstream dcmds(data); std::string thiscmd; @@ -275,7 +271,7 @@ static bool ValidateDnsServer(ServerConfig* conf, const char*, const char*, Valu { std::string nameserver; // attempt to look up their nameserver from /etc/resolv.conf - conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"WARNING: not defined, attempting to find working server in /etc/resolv.conf..."); + ServerInstance->Logs->Log("CONFIG",DEFAULT,"WARNING: not defined, attempting to find working server in /etc/resolv.conf..."); std::ifstream resolv("/etc/resolv.conf"); bool found_server = false; @@ -288,19 +284,19 @@ static bool ValidateDnsServer(ServerConfig* conf, const char*, const char*, Valu resolv >> nameserver; data.Set(nameserver.c_str()); found_server = true; - conf->GetInstance()->Logs->Log("CONFIG",DEFAULT," set to '%s' as first resolver in /etc/resolv.conf.",nameserver.c_str()); + ServerInstance->Logs->Log("CONFIG",DEFAULT," set to '%s' as first resolver in /etc/resolv.conf.",nameserver.c_str()); } } if (!found_server) { - conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"/etc/resolv.conf contains no viable nameserver entries! Defaulting to nameserver '127.0.0.1'!"); + ServerInstance->Logs->Log("CONFIG",DEFAULT,"/etc/resolv.conf contains no viable nameserver entries! Defaulting to nameserver '127.0.0.1'!"); data.Set("127.0.0.1"); } } else { - conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"/etc/resolv.conf can't be opened! Defaulting to nameserver '127.0.0.1'!"); + ServerInstance->Logs->Log("CONFIG",DEFAULT,"/etc/resolv.conf can't be opened! Defaulting to nameserver '127.0.0.1'!"); data.Set("127.0.0.1"); } } @@ -310,11 +306,11 @@ static bool ValidateDnsServer(ServerConfig* conf, const char*, const char*, Valu static bool ValidateServerName(ServerConfig* conf, const char*, const char*, ValueItem &data) { - conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"Validating server name"); + ServerInstance->Logs->Log("CONFIG",DEFAULT,"Validating server name"); /* If we already have a servername, and they changed it, we should throw an exception. */ if (!strchr(data.GetString(), '.')) { - conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"WARNING: '%s' is not a fully-qualified domain name. Changed to '%s.'", + ServerInstance->Logs->Log("CONFIG",DEFAULT,"WARNING: '%s' is not a fully-qualified domain name. Changed to '%s.'", data.GetString(),data.GetString()); std::string moo = data.GetValue(); data.Set(moo.append(".")); @@ -328,7 +324,7 @@ static bool ValidateNetBufferSize(ServerConfig* conf, const char*, const char*, // 65534 not 65535 because of null terminator if ((!data.GetInteger()) || (data.GetInteger() > 65534) || (data.GetInteger() < 1024)) { - conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"No NetBufferSize specified or size out of range, setting to default of 10240."); + ServerInstance->Logs->Log("CONFIG",DEFAULT,"No NetBufferSize specified or size out of range, setting to default of 10240."); data.Set(10240); } return true; @@ -338,22 +334,22 @@ static bool ValidateMaxWho(ServerConfig* conf, const char*, const char*, ValueIt { if ((data.GetInteger() > 65535) || (data.GetInteger() < 1)) { - conf->GetInstance()->Logs->Log("CONFIG",DEFAULT," size out of range, setting to default of 128."); - data.Set(128); + ServerInstance->Logs->Log("CONFIG",DEFAULT," size out of range, setting to default of 1024."); + data.Set(1024); } return true; } static bool ValidateHalfOp(ServerConfig* conf, const char*, const char*, ValueItem &data) { - ModeHandler* mh = conf->GetInstance()->Modes->FindMode('h', MODETYPE_CHANNEL); + ModeHandler* mh = ServerInstance->Modes->FindMode('h', MODETYPE_CHANNEL); if (data.GetBool() && !mh) { - conf->GetInstance()->Logs->Log("CONFIG", DEFAULT, "Enabling halfop mode."); - mh = new ModeChannelHalfOp(conf->GetInstance()); - conf->GetInstance()->Modes->AddMode(mh); + ServerInstance->Logs->Log("CONFIG", DEFAULT, "Enabling halfop mode."); + mh = new ModeChannelHalfOp; + ServerInstance->Modes->AddMode(mh); } else if (!data.GetBool() && mh) { - conf->GetInstance()->Logs->Log("CONFIG", DEFAULT, "Disabling halfop mode."); - conf->GetInstance()->Modes->DelMode(mh); + ServerInstance->Logs->Log("CONFIG", DEFAULT, "Disabling halfop mode."); + ServerInstance->Modes->DelMode(mh); delete mh; } return true; @@ -412,23 +408,23 @@ static bool ValidateInvite(ServerConfig* conf, const char*, const char*, ValueIt static bool ValidateSID(ServerConfig* conf, const char*, const char*, ValueItem &data) { - conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"Validating server id"); + ServerInstance->Logs->Log("CONFIG",DEFAULT,"Validating server id"); const char *sid = data.GetString(); - if (*sid && !conf->GetInstance()->IsSID(sid)) + if (*sid && !ServerInstance->IsSID(sid)) { throw CoreException(std::string(sid) + " is not a valid server ID. A server ID must be 3 characters long, with the first character a digit and the next two characters a digit or letter."); } - strlcpy(conf->sid, sid, 5); + conf->sid = sid; return true; } static bool ValidateWhoWas(ServerConfig* conf, const char*, const char*, ValueItem &data) { - conf->WhoWasMaxKeep = conf->GetInstance()->Duration(data.GetString()); + conf->WhoWasMaxKeep = ServerInstance->Duration(data.GetString()); if (conf->WhoWasGroupSize < 0) conf->WhoWasGroupSize = 0; @@ -439,14 +435,13 @@ static bool ValidateWhoWas(ServerConfig* conf, const char*, const char*, ValueIt if (conf->WhoWasMaxKeep < 3600) { conf->WhoWasMaxKeep = 3600; - conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"WARNING: value less than 3600, setting to default 3600"); + ServerInstance->Logs->Log("CONFIG",DEFAULT,"WARNING: value less than 3600, setting to default 3600"); } - Command* whowas_command = conf->GetInstance()->Parser->GetHandler("WHOWAS"); - if (whowas_command) + Module* whowas = ServerInstance->Modules->Find("cmd_whowas.so"); + if (whowas) { - std::deque params; - whowas_command->HandleInternal(WHOWAS_PRUNE, params); + WhowasRequest(NULL, whowas, WhowasRequest::WHOWAS_PRUNE).Send(); } return true; @@ -477,8 +472,8 @@ static bool DoZLine(ServerConfig* conf, const char* tag, const char** entries, V const char* reason = values[0].GetString(); const char* ipmask = values[1].GetString(); - ZLine* zl = new ZLine(conf->GetInstance(), conf->GetInstance()->Time(), 0, "", reason, ipmask); - if (!conf->GetInstance()->XLines->AddLine(zl, NULL)) + ZLine* zl = new ZLine(ServerInstance->Time(), 0, "", reason, ipmask); + if (!ServerInstance->XLines->AddLine(zl, NULL)) delete zl; return true; @@ -489,8 +484,8 @@ static bool DoQLine(ServerConfig* conf, const char* tag, const char** entries, V const char* reason = values[0].GetString(); const char* nick = values[1].GetString(); - QLine* ql = new QLine(conf->GetInstance(), conf->GetInstance()->Time(), 0, "", reason, nick); - if (!conf->GetInstance()->XLines->AddLine(ql, NULL)) + QLine* ql = new QLine(ServerInstance->Time(), 0, "", reason, nick); + if (!ServerInstance->XLines->AddLine(ql, NULL)) delete ql; return true; @@ -501,11 +496,11 @@ static bool DoKLine(ServerConfig* conf, const char* tag, const char** entries, V const char* reason = values[0].GetString(); const char* host = values[1].GetString(); - XLineManager* xlm = conf->GetInstance()->XLines; + XLineManager* xlm = ServerInstance->XLines; IdentHostPair ih = xlm->IdentSplit(host); - KLine* kl = new KLine(conf->GetInstance(), conf->GetInstance()->Time(), 0, "", reason, ih.first.c_str(), ih.second.c_str()); + KLine* kl = new KLine(ServerInstance->Time(), 0, "", reason, ih.first.c_str(), ih.second.c_str()); if (!xlm->AddLine(kl, NULL)) delete kl; return true; @@ -516,11 +511,11 @@ static bool DoELine(ServerConfig* conf, const char* tag, const char** entries, V const char* reason = values[0].GetString(); const char* host = values[1].GetString(); - XLineManager* xlm = conf->GetInstance()->XLines; + XLineManager* xlm = ServerInstance->XLines; IdentHostPair ih = xlm->IdentSplit(host); - ELine* el = new ELine(conf->GetInstance(), conf->GetInstance()->Time(), 0, "", reason, ih.first.c_str(), ih.second.c_str()); + ELine* el = new ELine(ServerInstance->Time(), 0, "", reason, ih.first.c_str(), ih.second.c_str()); if (!xlm->AddLine(el, NULL)) delete el; return true; @@ -558,10 +553,10 @@ static bool DoClass(ServerConfig* conf, const char* tag, const char**, ValueList } } - conf->operclass[ClassName].commandlist = strnewdup(CommandList); - conf->operclass[ClassName].umodelist = strnewdup(UModeList); - conf->operclass[ClassName].cmodelist = strnewdup(CModeList); - conf->operclass[ClassName].privs = strnewdup(PrivsList); + conf->operclass[ClassName].commandlist = CommandList; + conf->operclass[ClassName].umodelist = UModeList; + conf->operclass[ClassName].cmodelist = CModeList; + conf->operclass[ClassName].privs = PrivsList; return true; } @@ -689,7 +684,19 @@ void ServerConfig::CrossCheckConnectBlocks(ServerConfig* current) if (ConfValue("connect", "pingfreq", i, tmpv, false)) me->pingtime = atol(tmpv.c_str()); if (ConfValue("connect", "sendq", i, tmpv, false)) - me->sendqmax = atol(tmpv.c_str()); + { + // attempt to guess a good hard/soft sendq from a single value + long value = atol(tmpv.c_str()); + if (value > 16384) + me->softsendqmax = value / 16; + else + me->softsendqmax = value; + me->hardsendqmax = value * 8; + } + if (ConfValue("connect", "softsendq", i, tmpv, false)) + me->softsendqmax = atol(tmpv.c_str()); + if (ConfValue("connect", "hardsendq", i, tmpv, false)) + me->hardsendqmax = atol(tmpv.c_str()); if (ConfValue("connect", "recvq", i, tmpv, false)) me->recvqmax = atol(tmpv.c_str()); if (ConfValue("connect", "localmax", i, tmpv, false)) @@ -706,8 +713,8 @@ void ServerConfig::CrossCheckConnectBlocks(ServerConfig* current) ClassMap::iterator oldMask = oldBlocksByMask.find(typeMask); if (oldMask != oldBlocksByMask.end()) { - oldBlocksByMask.erase(oldMask); ConnectClass* old = oldMask->second; + oldBlocksByMask.erase(oldMask); old->Update(me); delete me; me = old; @@ -716,11 +723,6 @@ void ServerConfig::CrossCheckConnectBlocks(ServerConfig* current) Classes[i] = me; } } - - for(ClassMap::iterator toRemove = oldBlocksByMask.begin(); toRemove != oldBlocksByMask.end(); toRemove++) - { - removed_classes.push_back(toRemove->second); - } } @@ -750,45 +752,45 @@ static const Deprecated ChangedConfig[] = { static const InitialConfig Values[] = { {"performance", "softlimit", "0", new ValueContainerUInt (&ServerConfig::SoftLimit), DT_INTEGER, ValidateSoftLimit}, {"performance", "somaxconn", SOMAXCONN_S, new ValueContainerInt (&ServerConfig::MaxConn), DT_INTEGER, ValidateMaxConn}, - {"options", "moronbanner", "You're banned!", new ValueContainerChar (&ServerConfig::MoronBanner), DT_CHARPTR, NULL}, - {"server", "name", "", new ValueContainerChar (&ServerConfig::ServerName), DT_HOSTNAME, ValidateServerName}, - {"server", "description", "Configure Me", new ValueContainerChar (&ServerConfig::ServerDesc), DT_CHARPTR, NULL}, - {"server", "network", "Network", new ValueContainerChar (&ServerConfig::Network), DT_NOSPACES, NULL}, - {"server", "id", "", new ValueContainerChar (&ServerConfig::sid), DT_CHARPTR, ValidateSID}, - {"admin", "name", "", new ValueContainerChar (&ServerConfig::AdminName), DT_CHARPTR, NULL}, - {"admin", "email", "Mis@configu.red", new ValueContainerChar (&ServerConfig::AdminEmail), DT_CHARPTR, NULL}, - {"admin", "nick", "Misconfigured", new ValueContainerChar (&ServerConfig::AdminNick), DT_CHARPTR, NULL}, - {"files", "motd", "", new ValueContainerChar (&ServerConfig::motd), DT_CHARPTR, ValidateMotd}, - {"files", "rules", "", new ValueContainerChar (&ServerConfig::rules), DT_CHARPTR, ValidateRules}, - {"power", "diepass", "", new ValueContainerChar (&ServerConfig::diepass), DT_CHARPTR, ValidateNotEmpty}, + {"options", "moronbanner", "You're banned!", new ValueContainerString (&ServerConfig::MoronBanner), DT_CHARPTR, NULL}, + {"server", "name", "", new ValueContainerString (&ServerConfig::ServerName), DT_HOSTNAME, ValidateServerName}, + {"server", "description", "Configure Me", new ValueContainerString (&ServerConfig::ServerDesc), DT_CHARPTR, NULL}, + {"server", "network", "Network", new ValueContainerString (&ServerConfig::Network), DT_NOSPACES, NULL}, + {"server", "id", "", new ValueContainerString (&ServerConfig::sid), DT_CHARPTR, ValidateSID}, + {"admin", "name", "", new ValueContainerString (&ServerConfig::AdminName), DT_CHARPTR, NULL}, + {"admin", "email", "Mis@configu.red", new ValueContainerString (&ServerConfig::AdminEmail), DT_CHARPTR, NULL}, + {"admin", "nick", "Misconfigured", new ValueContainerString (&ServerConfig::AdminNick), DT_CHARPTR, NULL}, + {"files", "motd", "", new ValueContainerString (&ServerConfig::motd), DT_CHARPTR, ValidateMotd}, + {"files", "rules", "", new ValueContainerString (&ServerConfig::rules), DT_CHARPTR, ValidateRules}, + {"power", "diepass", "", new ValueContainerString (&ServerConfig::diepass), DT_CHARPTR, ValidateNotEmpty}, {"power", "pause", "", new ValueContainerInt (&ServerConfig::DieDelay), DT_INTEGER, NULL}, - {"power", "hash", "", new ValueContainerChar (&ServerConfig::powerhash), DT_CHARPTR, NULL}, - {"power", "restartpass", "", new ValueContainerChar (&ServerConfig::restartpass), DT_CHARPTR, ValidateNotEmpty}, - {"options", "prefixquit", "", new ValueContainerChar (&ServerConfig::PrefixQuit), DT_CHARPTR, NULL}, - {"options", "suffixquit", "", new ValueContainerChar (&ServerConfig::SuffixQuit), DT_CHARPTR, NULL}, - {"options", "fixedquit", "", new ValueContainerChar (&ServerConfig::FixedQuit), DT_CHARPTR, NULL}, - {"options", "prefixpart", "", new ValueContainerChar (&ServerConfig::PrefixPart), DT_CHARPTR, NULL}, - {"options", "suffixpart", "", new ValueContainerChar (&ServerConfig::SuffixPart), DT_CHARPTR, NULL}, - {"options", "fixedpart", "", new ValueContainerChar (&ServerConfig::FixedPart), DT_CHARPTR, NULL}, + {"power", "hash", "", new ValueContainerString (&ServerConfig::powerhash), DT_CHARPTR, NULL}, + {"power", "restartpass", "", new ValueContainerString (&ServerConfig::restartpass), DT_CHARPTR, ValidateNotEmpty}, + {"options", "prefixquit", "", new ValueContainerString (&ServerConfig::PrefixQuit), DT_CHARPTR, NULL}, + {"options", "suffixquit", "", new ValueContainerString (&ServerConfig::SuffixQuit), DT_CHARPTR, NULL}, + {"options", "fixedquit", "", new ValueContainerString (&ServerConfig::FixedQuit), DT_CHARPTR, NULL}, + {"options", "prefixpart", "", new ValueContainerString (&ServerConfig::PrefixPart), DT_CHARPTR, NULL}, + {"options", "suffixpart", "", new ValueContainerString (&ServerConfig::SuffixPart), DT_CHARPTR, NULL}, + {"options", "fixedpart", "", new ValueContainerString (&ServerConfig::FixedPart), DT_CHARPTR, NULL}, {"performance", "netbuffersize","10240", new ValueContainerInt (&ServerConfig::NetBufferSize), DT_INTEGER, ValidateNetBufferSize}, - {"performance", "maxwho", "128", new ValueContainerInt (&ServerConfig::MaxWhoResults), DT_INTEGER, ValidateMaxWho}, + {"performance", "maxwho", "1024", new ValueContainerInt (&ServerConfig::MaxWhoResults), DT_INTEGER, ValidateMaxWho}, {"options", "allowhalfop", "0", new ValueContainerBool (&ServerConfig::AllowHalfop), DT_BOOLEAN, ValidateHalfOp}, - {"dns", "server", "", new ValueContainerChar (&ServerConfig::DNSServer), DT_IPADDRESS,ValidateDnsServer}, + {"dns", "server", "", new ValueContainerString (&ServerConfig::DNSServer), DT_IPADDRESS,ValidateDnsServer}, {"dns", "timeout", "5", new ValueContainerInt (&ServerConfig::dns_timeout), DT_INTEGER, NULL}, {"options", "moduledir", MOD_PATH, new ValueContainerString (&ServerConfig::ModPath), DT_CHARPTR, NULL}, - {"disabled", "commands", "", new ValueContainerChar (&ServerConfig::DisabledCommands), DT_CHARPTR, NULL}, + {"disabled", "commands", "", new ValueContainerString (&ServerConfig::DisabledCommands), DT_CHARPTR, NULL}, {"disabled", "usermodes", "", NULL, DT_NOTHING, ValidateDisabledUModes}, {"disabled", "chanmodes", "", NULL, DT_NOTHING, ValidateDisabledCModes}, {"disabled", "fakenonexistant", "0", new ValueContainerBool (&ServerConfig::DisabledDontExist), DT_BOOLEAN, NULL}, - {"security", "runasuser", "", new ValueContainerChar(&ServerConfig::SetUser), DT_CHARPTR, NULL}, - {"security", "runasgroup", "", new ValueContainerChar(&ServerConfig::SetGroup), DT_CHARPTR, NULL}, - {"security", "userstats", "", new ValueContainerChar (&ServerConfig::UserStats), DT_CHARPTR, NULL}, - {"security", "customversion","", new ValueContainerChar (&ServerConfig::CustomVersion), DT_CHARPTR, NULL}, + {"security", "runasuser", "", new ValueContainerString(&ServerConfig::SetUser), DT_CHARPTR, NULL}, + {"security", "runasgroup", "", new ValueContainerString(&ServerConfig::SetGroup), DT_CHARPTR, NULL}, + {"security", "userstats", "", new ValueContainerString (&ServerConfig::UserStats), DT_CHARPTR, NULL}, + {"security", "customversion","", new ValueContainerString (&ServerConfig::CustomVersion), DT_CHARPTR, NULL}, {"security", "hidesplits", "0", new ValueContainerBool (&ServerConfig::HideSplits), DT_BOOLEAN, NULL}, {"security", "hidebans", "0", new ValueContainerBool (&ServerConfig::HideBans), DT_BOOLEAN, NULL}, - {"security", "hidewhois", "", new ValueContainerChar (&ServerConfig::HideWhoisServer), DT_NOSPACES, NULL}, - {"security", "hidekills", "", new ValueContainerChar (&ServerConfig::HideKillsServer), DT_NOSPACES, NULL}, + {"security", "hidewhois", "", new ValueContainerString (&ServerConfig::HideWhoisServer), DT_NOSPACES, NULL}, + {"security", "hidekills", "", new ValueContainerString (&ServerConfig::HideKillsServer), DT_NOSPACES, NULL}, {"security", "operspywhois", "0", new ValueContainerBool (&ServerConfig::OperSpyWhois), DT_BOOLEAN, NULL}, {"security", "restrictbannedusers", "1", new ValueContainerBool (&ServerConfig::RestrictBannedUsers), DT_BOOLEAN, NULL}, {"security", "genericoper", "0", new ValueContainerBool (&ServerConfig::GenericOper), DT_BOOLEAN, NULL}, @@ -801,12 +803,12 @@ static const InitialConfig Values[] = { {"security", "hidemodes", "", NULL, DT_NOTHING, ValidateModeLists}, {"options", "exemptchanops","", NULL, DT_NOTHING, ValidateExemptChanOps}, {"security", "maxtargets", "20", new ValueContainerUInt (&ServerConfig::MaxTargets), DT_INTEGER, ValidateMaxTargets}, - {"options", "defaultmodes", "nt", new ValueContainerChar (&ServerConfig::DefaultModes), DT_CHARPTR, NULL}, + {"options", "defaultmodes", "nt", new ValueContainerString (&ServerConfig::DefaultModes), DT_CHARPTR, NULL}, {"pid", "file", "", new ValueContainerString (&ServerConfig::PID), DT_CHARPTR, NULL}, {"whowas", "groupsize", "10", new ValueContainerInt (&ServerConfig::WhoWasGroupSize), DT_INTEGER, NULL}, {"whowas", "maxgroups", "10240", new ValueContainerInt (&ServerConfig::WhoWasMaxGroups), DT_INTEGER, NULL}, {"whowas", "maxkeep", "3600", NULL, DT_NOTHING, ValidateWhoWas}, - {"die", "value", "", new ValueContainerChar (&ServerConfig::DieValue), DT_CHARPTR, NULL}, + {"die", "value", "", new ValueContainerString (&ServerConfig::DieValue), DT_CHARPTR, NULL}, {"channels", "users", "20", new ValueContainerUInt (&ServerConfig::MaxChans), DT_INTEGER, NULL}, {"channels", "opers", "60", new ValueContainerUInt (&ServerConfig::OperMaxChans), DT_INTEGER, NULL}, {"cidr", "ipv4clone", "32", new ValueContainerInt (&ServerConfig::c_ipv4_range), DT_INTEGER, NULL}, @@ -906,7 +908,7 @@ void ServerConfig::Read() { /* Load and parse the config file, if there are any errors then explode */ - if (!this->DoInclude(ServerInstance->ConfigFileName)) + if (!this->DoInclude(ServerInstance->ConfigFileName, true)) { valid = false; return; @@ -958,40 +960,37 @@ void ServerConfig::Apply(ServerConfig* old, const std::string &useruid) { case DT_NOSPACES: { - ValueContainerChar* vcc = (ValueContainerChar*)Values[Index].val; + ValueContainerString* vcc = (ValueContainerString*)Values[Index].val; ValidateNoSpaces(vi.GetString(), Values[Index].tag, Values[Index].value); - vcc->Set(this, vi); + vcc->Set(this, vi.GetValue()); } break; case DT_HOSTNAME: { - ValueContainerChar* vcc = (ValueContainerChar*)Values[Index].val; + ValueContainerString* vcc = (ValueContainerString*)Values[Index].val; ValidateHostname(vi.GetString(), Values[Index].tag, Values[Index].value); - vcc->Set(this, vi); + vcc->Set(this, vi.GetValue()); } break; case DT_IPADDRESS: { - ValueContainerChar* vcc = (ValueContainerChar*)Values[Index].val; + ValueContainerString* vcc = (ValueContainerString*)Values[Index].val; ValidateIP(vi.GetString(), Values[Index].tag, Values[Index].value, allow_wild); - vcc->Set(this, vi); + vcc->Set(this, vi.GetValue()); } break; case DT_CHANNEL: { - ValueContainerChar* vcc = (ValueContainerChar*)Values[Index].val; + ValueContainerString* vcc = (ValueContainerString*)Values[Index].val; if (*(vi.GetString()) && !ServerInstance->IsChannel(vi.GetString(), MAXBUF)) { throw CoreException("The value of <"+std::string(Values[Index].tag)+":"+Values[Index].value+"> is not a valid channel name"); } - vcc->Set(this, vi); + vcc->Set(this, vi.GetValue()); } break; case DT_CHARPTR: { - ValueContainerChar* vcc = dynamic_cast(Values[Index].val); - if (vcc) - vcc->Set(this, vi); ValueContainerString* vcs = dynamic_cast(Values[Index].val); if (vcs) vcs->Set(this, vi.GetValue()); @@ -1132,28 +1131,30 @@ void ServerConfig::Apply(ServerConfig* old, const std::string &useruid) // write once here, to try it out and make sure its ok ServerInstance->WritePID(this->PID); - FailedPortList pl; - ServerInstance->BindPorts(pl); - /* * These values can only be set on boot. Keep their old values. Do it before we send messages so we actually have a servername. */ if (old) { - memcpy(this->ServerName, old->ServerName, sizeof(this->ServerName)); - memcpy(this->sid, old->sid, sizeof(this->sid)); - } - - if (pl.size()) - { - errstr << "Not all your client ports could be bound.\nThe following port(s) failed to bind:\n"; - - int j = 1; - for (FailedPortList::iterator i = pl.begin(); i != pl.end(); i++, j++) + this->ServerName = old->ServerName; + this->sid = old->sid; + this->argv = old->argv; + this->argc = old->argc; + + // Same for ports... they're bound later on first run. + FailedPortList pl; + ServerInstance->BindPorts(pl); + if (pl.size()) { - char buf[MAXBUF]; - snprintf(buf, MAXBUF, "%d. Address: %s Reason: %s\n", j, i->first.empty() ? "" : i->first.c_str(), i->second.c_str()); - errstr << buf; + errstr << "Not all your client ports could be bound.\nThe following port(s) failed to bind:\n"; + + int j = 1; + for (FailedPortList::iterator i = pl.begin(); i != pl.end(); i++, j++) + { + char buf[MAXBUF]; + snprintf(buf, MAXBUF, "%d. Address: %s Reason: %s\n", j, i->first.empty() ? "" : i->first.c_str(), i->second.c_str()); + errstr << buf; + } } } @@ -1201,12 +1202,6 @@ void ServerConfig::Apply(ServerConfig* old, const std::string &useruid) return; ApplyModules(user); - for (std::vector::iterator i = removed_classes.begin(); i != removed_classes.end(); i++) - { - ConnectClass* c = *i; - if (0 == --c->RefCount) - delete c; - } } void ServerConfig::ApplyModules(User* user) @@ -1230,6 +1225,9 @@ void ServerConfig::ApplyModules(User* user) for (std::set::iterator removing = removed_modules.begin(); removing != removed_modules.end(); removing++) { + // Don't remove cmd_*.so, just remove m_*.so + if (removing->c_str()[0] == 'c') + continue; if (ServerInstance->Modules->Unload(removing->c_str())) { ServerInstance->SNO->WriteToSnoMask('a', "*** REHASH UNLOADED MODULE: %s",removing->c_str()); @@ -1273,7 +1271,7 @@ void ServerConfig::ApplyModules(User* user) ServerInstance->SNO->WriteToSnoMask('a', "*** Successfully rehashed server."); } -bool ServerConfig::LoadConf(FILE* &conf, const char* filename) +bool ServerConfig::LoadConf(FILE* &conf, const char* filename, bool allowexeinc) { std::string line; char ch; @@ -1457,7 +1455,7 @@ bool ServerConfig::LoadConf(FILE* &conf, const char* filename) * LoadConf() and load the included config into the same ConfigDataHash */ long bl = linenumber; - if (!this->ParseLine(filename, line, linenumber)) + if (!this->ParseLine(filename, line, linenumber, allowexeinc)) return false; last_successful_parse = linenumber; @@ -1485,12 +1483,12 @@ bool ServerConfig::LoadConf(FILE* &conf, const char* filename) } -bool ServerConfig::LoadConf(FILE* &conf, const std::string &filename) +bool ServerConfig::LoadConf(FILE* &conf, const std::string &filename, bool allowexeinc) { - return this->LoadConf(conf, filename.c_str()); + return this->LoadConf(conf, filename.c_str(), allowexeinc); } -bool ServerConfig::ParseLine(const std::string &filename, std::string &line, long &linenumber) +bool ServerConfig::ParseLine(const std::string &filename, std::string &line, long &linenumber, bool allowexeinc) { std::string tagname; std::string current_key; @@ -1608,11 +1606,20 @@ bool ServerConfig::ParseLine(const std::string &filename, std::string &line, lon if ((tagname == "include") && (current_key == "file")) { - if (!this->DoInclude(current_value)) + if (!this->DoInclude(current_value, allowexeinc)) return false; } else if ((tagname == "include") && (current_key == "executable")) { + if (!allowexeinc) + { + errstr << "Executable includes are not allowed to use \n" + "This could be an attempt to execute commands from a malicious remote include.\n" + "If you need multiple levels of remote include, create a script to assemble the " + "contents locally or include files using \n"; + return false; + } + /* Pipe an executable and use its stdout as config data */ if (!this->DoPipe(current_value)) return false; @@ -1647,7 +1654,7 @@ bool ServerConfig::DoPipe(const std::string &file) if (conf) { - ret = LoadConf(conf, file.c_str()); + ret = LoadConf(conf, file.c_str(), false); pclose(conf); } else @@ -1661,7 +1668,7 @@ bool ServerConfig::StartsWithWindowsDriveLetter(const std::string &path) return (path.length() > 2 && isalpha(path[0]) && path[1] == ':'); } -bool ServerConfig::DoInclude(const std::string &file) +bool ServerConfig::DoInclude(const std::string &file, bool allowexeinc) { std::string confpath; std::string newfile; @@ -1692,7 +1699,7 @@ bool ServerConfig::DoInclude(const std::string &file) if (conf) { - ret = LoadConf(conf, newfile); + ret = LoadConf(conf, newfile, allowexeinc); fclose(conf); } else @@ -1958,9 +1965,9 @@ bool ServerConfig::FileExists(const char* file) } } -char* ServerConfig::CleanFilename(char* name) +const char* ServerConfig::CleanFilename(const char* name) { - char* p = name + strlen(name); + const char* p = name + strlen(name); while ((p != name) && (*p != '/') && (*p != '\\')) p--; return (p != name ? ++p : p); } @@ -2001,11 +2008,6 @@ std::string ServerConfig::GetFullProgDir() return "/"; } -InspIRCd* ServerConfig::GetInstance() -{ - return ServerInstance; -} - std::string ServerConfig::GetSID() { return sid; @@ -2057,7 +2059,7 @@ bool ValueItem::GetBool() void ConfigReaderThread::Run() { - Config = new ServerConfig(ServerInstance); + Config = new ServerConfig; Config->Read(); done = true; } @@ -2086,7 +2088,7 @@ void ConfigReaderThread::Finish() ServerInstance->ResetMaxBans(); Config->ApplyDisabledCommands(Config->DisabledCommands); User* user = TheUserUID.empty() ? ServerInstance->FindNick(TheUserUID) : NULL; - FOREACH_MOD_I(ServerInstance, I_OnRehash, OnRehash(user)); + FOREACH_MOD(I_OnRehash, OnRehash(user)); ServerInstance->BuildISupport(); delete old; @@ -2100,9 +2102,3 @@ void ConfigReaderThread::Finish() delete this->Config; } } - -template<> -void ValueContainer::Set(ServerConfig* conf, ValueItem const& item) -{ - strlcpy(conf->*vptr, item.GetString(), MAXBUF); -}