diff options
-rw-r--r-- | docs/inspircd.conf.example | 7 | ||||
-rw-r--r-- | include/configreader.h | 6 | ||||
-rw-r--r-- | include/users.h | 29 | ||||
-rw-r--r-- | src/channels.cpp | 21 | ||||
-rw-r--r-- | src/configreader.cpp | 10 | ||||
-rw-r--r-- | src/users.cpp | 5 |
6 files changed, 59 insertions, 19 deletions
diff --git a/docs/inspircd.conf.example b/docs/inspircd.conf.example index d23e47b69..11853b604 100644 --- a/docs/inspircd.conf.example +++ b/docs/inspircd.conf.example @@ -203,7 +203,7 @@ # password="blahblah" timeout="10" timeout="blah" # # flood="5" threshold="8" pingfreq="120" sendq="99999" # # revcq="696969" localmax="3" globalmax="3" # -# port="6660"> # +# port="6660" maxchans="50"> # # # # <connect name="blocked" deny="127.0.0.1" port="6667"> # # # @@ -220,6 +220,11 @@ # you do this, any options not explicitly specified in the tag will # # be copied from the parent. # # # +# If the value maxchans is included, this overrides all other max # +# channels related settings, including the seperate oper maximum. # +# You may set this to any (sane) value you wish and it applies to # +# all users within this connect tag. # +# # # You may optionally include timeout="x" on any allow line, which # # specifies the amount of time given before an unknown connection # # is closed if USER/NICK/PASS are not given. This value is in secs # diff --git a/include/configreader.h b/include/configreader.h index 7c5592432..648b02eb1 100644 --- a/include/configreader.h +++ b/include/configreader.h @@ -182,11 +182,11 @@ struct MultiConfig /** Tag name */ const char* tag; /** One or more items within tag */ - char* items[15]; + char* items[17]; /** One or more defaults for items within tags */ - char* items_default[15]; + char* items_default[17]; /** One or more data types */ - int datatype[15]; + int datatype[17]; /** Initialization function */ MultiNotify init_function; /** Validation function */ diff --git a/include/users.h b/include/users.h index 8628e2c21..66ca2b9cc 100644 --- a/include/users.h +++ b/include/users.h @@ -164,6 +164,11 @@ class CoreExport ConnectClass : public classbase /** Global max when connecting by this connection class */ unsigned long maxglobal; + + /** Max channels for this class + */ + unsigned int maxchans; + /** Port number this connect class applies to */ int port; @@ -190,16 +195,16 @@ public: */ ConnectClass(const std::string &thename, unsigned int timeout, unsigned int fld, const std::string &hst, unsigned int ping, const std::string &pas, unsigned int thres, unsigned long sendq, unsigned long recvq, - unsigned long maxl, unsigned long maxg, int p = 0) : + unsigned long maxl, unsigned long maxg, unsigned int maxc, int p = 0) : type(CC_ALLOW), name(thename), registration_timeout(timeout), flood(fld), host(hst), pingtime(ping), pass(pas), - threshold(thres), sendqmax(sendq), recvqmax(recvq), maxlocal(maxl), maxglobal(maxg), port(p) { } + threshold(thres), sendqmax(sendq), recvqmax(recvq), maxlocal(maxl), maxglobal(maxg), maxchans(maxc), port(p) { } /** Create a new connect class to DENY connections * @param thename Name of the connect class * @param hst The IP mask to deny */ ConnectClass(const std::string &thename, const std::string &hst) : type(CC_DENY), name(thename), registration_timeout(0), - flood(0), host(hst), pingtime(0), pass(""), threshold(0), sendqmax(0), recvqmax(0), maxlocal(0), maxglobal(0), port(0) { } + flood(0), host(hst), pingtime(0), pass(""), threshold(0), sendqmax(0), recvqmax(0), maxlocal(0), maxglobal(0), maxchans(0), port(0) { } /* Create a new connect class based on another class * @param thename The name of the connect class @@ -208,7 +213,8 @@ public: ConnectClass(const std::string &thename, const ConnectClass &source) : type(source.type), name(thename), registration_timeout(source.registration_timeout), flood(source.flood), host(source.host), pingtime(source.pingtime), pass(source.pass), threshold(source.threshold), sendqmax(source.sendqmax), - recvqmax(source.recvqmax), maxlocal(source.maxlocal), maxglobal(source.maxglobal), port(source.port) + recvqmax(source.recvqmax), maxlocal(source.maxlocal), maxglobal(source.maxglobal), maxchans(source.maxchans), + port(source.port) { } @@ -216,7 +222,7 @@ public: */ void Update(unsigned int timeout, unsigned int fld, const std::string &hst, unsigned int ping, const std::string &pas, unsigned int thres, unsigned long sendq, unsigned long recvq, - unsigned long maxl, unsigned long maxg, int p) + unsigned long maxl, unsigned long maxg, unsigned int maxc, int p) { if (timeout) registration_timeout = timeout; @@ -238,10 +244,17 @@ public: maxlocal = maxl; if (maxg) maxglobal = maxg; + if (maxc) + maxchans = maxc; if (p) port = p; } + int GetMaxChans() + { + return maxchans; + } + /** Returns the type, CC_ALLOW or CC_DENY */ char GetType() @@ -437,6 +450,10 @@ class CoreExport userrec : public connection */ char* operquit; + /** Max channels for this user + */ + unsigned int MaxChans; + public: /** Resolvers for looking up this users IP address * This will occur if and when res_reverse completes. @@ -465,6 +482,8 @@ class CoreExport userrec : public connection */ void StartDNSLookup(); + unsigned int GetMaxChans(); + /** The users nickname. * An invalid nickname indicates an unregistered connection prior to the NICK command. * Use InspIRCd::IsNick() to validate nicknames. diff --git a/src/channels.cpp b/src/channels.cpp index 6ba5aaa5f..bd8a9719c 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -219,9 +219,9 @@ chanrec* chanrec::JoinUser(InspIRCd* Instance, userrec *user, const char* cn, bo */ if (IS_LOCAL(user) && !override) { - if (IS_OPER(user)) + if (user->GetMaxChans()) { - if (user->chans.size() >= Instance->Config->OperMaxChans) + if (user->chans.size() >= user->GetMaxChans()) { user->WriteServ("405 %s %s :You are on too many channels",user->nick, cn); return NULL; @@ -229,10 +229,21 @@ chanrec* chanrec::JoinUser(InspIRCd* Instance, userrec *user, const char* cn, bo } else { - if (user->chans.size() >= Instance->Config->MaxChans) + if (IS_OPER(user)) { - user->WriteServ("405 %s %s :You are on too many channels",user->nick, cn); - return NULL; + if (user->chans.size() >= Instance->Config->OperMaxChans) + { + user->WriteServ("405 %s %s :You are on too many channels",user->nick, cn); + return NULL; + } + } + else + { + if (user->chans.size() >= Instance->Config->MaxChans) + { + user->WriteServ("405 %s %s :You are on too many channels",user->nick, cn); + return NULL; + } } } } diff --git a/src/configreader.cpp b/src/configreader.cpp index 189fbb59b..b3258eb2e 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -407,6 +407,7 @@ bool DoConnect(ServerConfig* conf, const char* tag, char** entries, ValueList &v int port = values[11].GetInteger(); const char* name = values[12].GetString(); const char* parent = values[13].GetString(); + int maxchans = values[14].GetInteger(); if (*parent) { @@ -418,8 +419,7 @@ bool DoConnect(ServerConfig* conf, const char* tag, char** entries, ValueList &v if (item->GetName() == name) { ConnectClass c(name, *item); - c.Update(timeout, flood, std::string(*allow ? allow : deny), pingfreq, password, threshold, sendq, recvq, localmax, globalmax, 0); - c.SetPort(port); + c.Update(timeout, flood, std::string(*allow ? allow : deny), pingfreq, password, threshold, sendq, recvq, localmax, globalmax, maxchans, port); conf->Classes.push_back(c); } } @@ -429,7 +429,7 @@ bool DoConnect(ServerConfig* conf, const char* tag, char** entries, ValueList &v { if (*allow) { - ConnectClass c(name, timeout, flood, allow, pingfreq, password, threshold, sendq, recvq, localmax, globalmax); + ConnectClass c(name, timeout, flood, allow, pingfreq, password, threshold, sendq, recvq, localmax, globalmax, maxchans); c.SetPort(port); conf->Classes.push_back(c); } @@ -672,7 +672,7 @@ void ServerConfig::Read(bool bail, userrec* user) {"connect", {"allow", "deny", "password", "timeout", "pingfreq", "flood", "threshold", "sendq", "recvq", "localmax", "globalmax", "port", - "name", "parent", + "name", "parent", "maxchans", NULL}, {"", "", "", "", "120", "", "", "", "", "3", "3", "0", @@ -680,7 +680,7 @@ void ServerConfig::Read(bool bail, userrec* user) NULL}, {DT_CHARPTR, DT_CHARPTR, DT_CHARPTR, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, - DT_CHARPTR, DT_CHARPTR}, + DT_CHARPTR, DT_CHARPTR, DT_INTEGER}, InitConnect, DoConnect, DoneConnect}, {"uline", diff --git a/src/users.cpp b/src/users.cpp index eb676b06a..4854849ad 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -1040,6 +1040,7 @@ void userrec::CheckClass(const std::string &explicit_class) this->threshold = a->GetThreshold(); this->sendqmax = a->GetSendqMax(); this->recvqmax = a->GetRecvqMax(); + this->MaxChans = a->GetMaxChans(); } void userrec::FullConnect() @@ -1853,6 +1854,10 @@ void userrec::SplitChanList(userrec* dest, const std::string &cl) } } +unsigned int userrec::GetMaxChans() +{ + return this->MaxChans; +} /* looks up a users password for their connection class (<ALLOW>/<DENY> tags) * NOTE: If the <ALLOW> or <DENY> tag specifies an ip, and this user resolves, |