X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fconfigreader.cpp;h=b4f28d04e219f79f967bdbb401724b30e5b217f4;hb=49b693beb75b8292c5b378f46d2b357ebb2fdc8c;hp=5523397f42d021bf4881115ef4375cc21852e949;hpb=32a619dbea500bce8b930aeb6c10e4948607a303;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/configreader.cpp b/src/configreader.cpp index 5523397f4..b4f28d04e 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -23,6 +23,7 @@ /* $CopyInstall: conf/modules.conf.example $(CONPATH) */ /* $CopyInstall: conf/opers.conf.example $(CONPATH) */ /* $CopyInstall: conf/links.conf.example $(CONPATH) */ +/* $CopyInstall: .gdbargs $(BASE) */ #include "inspircd.h" #include @@ -455,18 +456,35 @@ bool ValidateWhoWas(ServerConfig* conf, const char*, const char*, ValueItem &dat */ bool InitConnect(ServerConfig* conf, const char*) { - conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"Reading connect classes..."); + conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"Reading connect classes... class list is:"); - /* - * Remove all connect classes.. we'll reset the pointers in user classes - * once all new classes have been read from config. - */ - while (conf->Classes.begin() != conf->Classes.end()) + for (ClassVector::iterator i = conf->Classes.begin(); i != conf->Classes.end() ; ) { - ConnectClass *c = *conf->Classes.begin(); + ConnectClass* c = *i; - delete c; - conf->Classes.erase(conf->Classes.begin()); + /* + * only delete a class with refcount 0. + * this is needed to avoid trampling on a wild pointer (User::MyClass)! + * it's also the most simple way to do it, given that we're looking at threads.. + * -- w00t + */ + if (c->RefCount == 0) + { + conf->GetInstance()->Logs->Log("CONFIG",DEFAULT, "Removing connect class, refcount is 0!"); + + /* This was causing a crash, because we'd set i to .begin() just here, but then the for loop's increment would + * set it to .begin() + 1. Which if it was already the last thing in the list, wasn't good. + * Now the increment is in the else { } below. + */ + conf->Classes.erase(i); + i = conf->Classes.begin(); // start over so we don't trample on a bad iterator + } + else + { + /* also mark all existing classes disabled, if they still exist in the conf, they will be reenabled. */ + c->SetDisabled(true); + i++; + } } return true; @@ -482,21 +500,21 @@ bool DoConnect(ServerConfig* conf, const char*, char**, ValueList &values, int*) const char* password = values[2].GetString(); int timeout = values[3].GetInteger(); int pingfreq = values[4].GetInteger(); - int flood = values[5].GetInteger(); - int threshold = values[6].GetInteger(); - int sendq = values[7].GetInteger(); - int recvq = values[8].GetInteger(); - int localmax = values[9].GetInteger(); - int globalmax = values[10].GetInteger(); - int port = values[11].GetInteger(); - const char* name = values[12].GetString(); - const char* parent = values[13].GetString(); - int maxchans = values[14].GetInteger(); - unsigned long limit = values[15].GetInteger(); - const char* hashtype = values[16].GetString(); + int sendq = values[5].GetInteger(); + int recvq = values[6].GetInteger(); + int localmax = values[7].GetInteger(); + int globalmax = values[8].GetInteger(); + int port = values[9].GetInteger(); + const char* name = values[10].GetString(); + const char* parent = values[11].GetString(); + int maxchans = values[12].GetInteger(); + unsigned long limit = values[13].GetInteger(); + const char* hashtype = values[14].GetString(); conf->GetInstance()->Logs->Log("CONFIG",DEFAULT,"Adding a connect class!"); + ConnectClass *cc = NULL; + if (*parent) { /* Find 'parent' and inherit a new class from it, @@ -505,13 +523,13 @@ bool DoConnect(ServerConfig* conf, const char*, char**, ValueList &values, int*) ClassVector::iterator item = conf->Classes.begin(); for (; item != conf->Classes.end(); ++item) { - ConnectClass* cc = *item; + cc = *item; conf->GetInstance()->Logs->Log("CONFIG",DEBUG,"Class: %s", cc->GetName().c_str()); if (cc->GetName() == parent) { - ConnectClass* newclass = new ConnectClass(name, cc); - newclass->Update(timeout, flood, *allow ? allow : deny, pingfreq, password, threshold, sendq, recvq, localmax, globalmax, maxchans, port, limit); - conf->Classes.push_back(newclass); + cc = new ConnectClass(name, cc); + cc->Update(timeout, *allow ? allow : deny, pingfreq, password, sendq, recvq, localmax, globalmax, maxchans, port, limit); + conf->Classes.push_back(cc); break; } } @@ -525,13 +543,13 @@ bool DoConnect(ServerConfig* conf, const char*, char**, ValueList &values, int*) /* Find existing class by mask, the mask should be unique */ for (ClassVector::iterator item = conf->Classes.begin(); item != conf->Classes.end(); ++item) { - if ((*item)->GetHost() == allow) + if ((*item)->GetHost() == allow && !(*item)->GetDisabled()) { - (*item)->Update(timeout, flood, allow, pingfreq, password, threshold, sendq, recvq, localmax, globalmax, maxchans, port, limit); + (*item)->Update(timeout, allow, pingfreq, password, sendq, recvq, localmax, globalmax, maxchans, port, limit); return true; } } - ConnectClass* cc = new ConnectClass(name, timeout, flood, allow, pingfreq, password, hashtype, threshold, sendq, recvq, localmax, globalmax, maxchans); + cc = new ConnectClass(name, timeout, allow, pingfreq, password, hashtype, sendq, recvq, localmax, globalmax, maxchans); cc->limit = limit; cc->SetPort(port); conf->Classes.push_back(cc); @@ -541,14 +559,14 @@ bool DoConnect(ServerConfig* conf, const char*, char**, ValueList &values, int*) /* Find existing class by mask, the mask should be unique */ for (ClassVector::iterator item = conf->Classes.begin(); item != conf->Classes.end(); ++item) { - if ((*item)->GetHost() == deny) + if ((*item)->GetHost() == deny && !(*item)->GetDisabled()) { (*item)->Update(name, deny); (*item)->SetPort(port); return true; } } - ConnectClass* cc = new ConnectClass(name, deny); + cc = new ConnectClass(name, deny); cc->SetPort(port); conf->Classes.push_back(cc); } @@ -561,23 +579,6 @@ bool DoConnect(ServerConfig* conf, const char*, char**, ValueList &values, int*) */ bool DoneConnect(ServerConfig *conf, const char*) { - /* - * Update connect classes on all users. - */ - for (std::vector::iterator n = conf->GetInstance()->Users->local_users.begin(); n != conf->GetInstance()->Users->local_users.end(); n++) - { - User *u = *n; - - u->SetClass(); - - /* - * Check that the user falls into a valid class block.. if they don't, - * they need to be quit, which CheckClass will do. -- w00t - */ - u->CheckClass(); - } - - conf->GetInstance()->Logs->Log("CONFIG",DEFAULT, "Done adding connect classes!"); return true; } @@ -740,7 +741,8 @@ void ServerConfig::Read(bool bail, const std::string &useruid) static char announceinvites[MAXBUF]; /* options:announceinvites setting */ static char disabledumodes[MAXBUF]; /* Disabled usermodes */ static char disabledcmodes[MAXBUF]; /* Disabled chanmodes */ - errstr.clear(); + /* std::ostringstream::clear() does not clear the string itself, only the error flags. */ + this->errstr = new std::ostringstream(std::stringstream::in | std::stringstream::out); include_stack.clear(); @@ -813,6 +815,7 @@ void ServerConfig::Read(bool bail, const std::string &useruid) {"security", "hidewhois", "", new ValueContainerChar (this->HideWhoisServer), DT_NOSPACES, NoValidation}, {"security", "hidekills", "", new ValueContainerChar (this->HideKillsServer), DT_NOSPACES, NoValidation}, {"security", "operspywhois", "0", new ValueContainerBool (&this->OperSpyWhois), DT_BOOLEAN, NoValidation}, + {"security", "restrictbannedusers", "1", new ValueContainerBool (&this->RestrictBannedUsers), DT_BOOLEAN, NoValidation}, {"performance", "nouserdns", "0", new ValueContainerBool (&this->NoUserDns), DT_BOOLEAN, NoValidation}, {"options", "syntaxhints", "0", new ValueContainerBool (&this->SyntaxHints), DT_BOOLEAN, NoValidation}, {"options", "cyclehosts", "0", new ValueContainerBool (&this->CycleHosts), DT_BOOLEAN, NoValidation}, @@ -852,18 +855,16 @@ void ServerConfig::Read(bool bail, const std::string &useruid) MultiConfig MultiValues[] = { {"connect", - {"allow", "deny", "password", "timeout", "pingfreq", "flood", - "threshold", "sendq", "recvq", "localmax", "globalmax", "port", + {"allow", "deny", "password", "timeout", "pingfreq", + "sendq", "recvq", "localmax", "globalmax", "port", "name", "parent", "maxchans", "limit", "hash", NULL}, - {"", "", "", "", "120", "", - "", "", "", "3", "3", "0", - "", "", "0", "0", "", + {"", "", "", "", "120", + "", "", "3", "3", "0", + "", "", "0", "0", "", NULL}, - {DT_IPADDRESS|DT_ALLOW_WILD, - DT_IPADDRESS|DT_ALLOW_WILD, - DT_CHARPTR, DT_INTEGER, DT_INTEGER, DT_INTEGER, - DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, + {DT_IPADDRESS|DT_ALLOW_WILD, DT_IPADDRESS|DT_ALLOW_WILD, DT_CHARPTR, DT_INTEGER, DT_INTEGER, + DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_NOSPACES, DT_NOSPACES, DT_INTEGER, DT_INTEGER, DT_CHARPTR}, InitConnect, DoConnect, DoneConnect}, @@ -933,11 +934,14 @@ void ServerConfig::Read(bool bail, const std::string &useruid) /* Make a copy here so if it fails then we can carry on running with an unaffected config */ newconfig.clear(); - if (!this->DoInclude(newconfig, ServerInstance->ConfigFileName, errstr)) + if (!this->DoInclude(newconfig, ServerInstance->ConfigFileName, *errstr)) { - ReportConfigError(errstr.str(), bail, useruid); + ReportConfigError(errstr->str(), bail, useruid); + delete errstr; return; } + + delete errstr; /* The stuff in here may throw CoreException, be sure we're in a position to catch it. */ try @@ -954,8 +958,6 @@ void ServerConfig::Read(bool bail, const std::string &useruid) *item = 0; if (ConfValue(newconfig, ChangedConfig[Index].tag, ChangedConfig[Index].value, "", 0, item, MAXBUF, true) || *item) throw CoreException(std::string("Your configuration contains a deprecated value: <") + ChangedConfig[Index].tag + ":" + ChangedConfig[Index].value + "> - " + ChangedConfig[Index].reason); - else - ServerInstance->Logs->Log("CONFIG",DEBUG,"Deprecated item <%s:%s> does not exist, good.", ChangedConfig[Index].tag, ChangedConfig[Index].value); } /* Read the values of all the tags which occur once or not at all, and call their callbacks. @@ -973,7 +975,10 @@ void ServerConfig::Read(bool bail, const std::string &useruid) /* Silently ignore boot only values */ if (bootonly && !bail) + { + delete Values[Index].val; continue; + } ConfValue(newconfig, Values[Index].tag, Values[Index].value, Values[Index].default_value, 0, item, MAXBUF, allow_newlines); ValueItem vi(item); @@ -1219,12 +1224,6 @@ void ServerConfig::Read(bool bail, const std::string &useruid) // write once here, to try it out and make sure its ok ServerInstance->WritePID(this->PID); - /* Switch over logfiles */ - ServerInstance->Logs->CloseLogs(); - ServerInstance->Logs->OpenFileLogs(); - - ServerInstance->Logs->Log("CONFIG", DEFAULT, "Done reading configuration file."); - /* If we're rehashing, let's load any new modules, and unload old ones */ if (!bail) @@ -1315,24 +1314,11 @@ void ServerConfig::Read(bool bail, const std::string &useruid) } } } - - ServerInstance->Logs->Log("CONFIG", DEFAULT, "Successfully unloaded %lu of %lu modules and loaded %lu of %lu modules.",(unsigned long)rem,(unsigned long)removed_modules.size(),(unsigned long)add,(unsigned long)added_modules.size()); - ServerInstance->Threads->Unlock(); } - if (bail) - { - /** Note: This is safe, the method checks for user == NULL */ - ServerInstance->Threads->Lock(); - User* user = NULL; - if (!useruid.empty()) - user = ServerInstance->FindNick(useruid); - ServerInstance->Parser->SetupCommandTable(user); - ServerInstance->Threads->Unlock(); - } - else + if (!bail) { if (!useruid.empty()) {