summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/inspircd.conf.example7
-rw-r--r--include/configreader.h6
-rw-r--r--include/users.h29
-rw-r--r--src/channels.cpp21
-rw-r--r--src/configreader.cpp10
-rw-r--r--src/users.cpp5
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,