]> jfr.im git - solanum.git/commitdiff
ircd: implement EXTENDCHANS, based on ircd-seven (with some improvements from chatircd)
authorWilliam Pitcock <redacted>
Tue, 12 Jan 2016 05:32:23 +0000 (23:32 -0600)
committerWilliam Pitcock <redacted>
Tue, 12 Jan 2016 05:32:23 +0000 (23:32 -0600)
13 files changed:
doc/ircd.conf.example
doc/reference.conf
extensions/Makefile.am
extensions/Makefile.in
extensions/m_extendchans.c [new file with mode: 0644]
include/client.h
include/s_conf.h
ircd/newconf.c
ircd/s_conf.c
ircd/s_user.c
modules/core/m_join.c
modules/m_info.c
modules/m_privs.c

index 6dbdfb0f975c4533dfccb810865e30a29ebd4c38..4bb1d69771bce88a9e0eeaf22b3a722310fae7db 100755 (executable)
@@ -25,6 +25,7 @@
 #loadmodule "extensions/extb_server.la";
 #loadmodule "extensions/extb_ssl.la";
 #loadmodule "extensions/hurt.la";
+#loadmodule "extensions/m_extendchans.la";
 #loadmodule "extensions/m_findforwards.la";
 #loadmodule "extensions/m_identify.la";
 #loadmodule "extensions/no_oper_invis.la";
@@ -349,6 +350,7 @@ channel {
        knock_delay = 5 minutes;
        knock_delay_channel = 1 minute;
        max_chans_per_user = 15;
+       max_chans_per_user_large = 60;
        max_bans = 100;
        max_bans_large = 500;
        default_split_user_count = 0;
index 1b1bd1a5f34388c6a386bf46947da9e82f90a82e..1b94449fea3b445c40f34db9e28abd02f421478f 100755 (executable)
@@ -64,6 +64,7 @@
  * HURT system                                       -- hurt.la
  * New host mangling (umode +x)                      -- ip_cloaking_4.0.la
  * Old host mangling (umode +h)                      -- ip_cloaking.la
+ * Dynamically extend channel limits                 -- m_extendchans.la
  * Find channel forwards                             -- m_findforwards.la
  * /identify support                                 -- m_identify.la
  * Opers cannot be invisible (umode +i)              -- no_oper_invis.la
@@ -94,6 +95,7 @@
 #loadmodule "extensions/hurt.la";
 #loadmodule "extensions/ip_cloaking_4.0.la";
 #loadmodule "extensions/ip_cloaking.la";
+#loadmodule "extensions/m_extendchans.la";
 #loadmodule "extensions/m_findforwards.la";
 #loadmodule "extensions/m_identify.la";
 #loadmodule "extensions/no_oper_invis.la";
@@ -376,6 +378,7 @@ auth {
         * need_ident   (old + flag)  | require ident for user in this class
         * need_ssl                   | require SSL/TLS for user in this class
         * need_sasl                  | require SASL id for user in this class
+        * extend_chans               | allow this user to join more channels than normal
         */
        flags = kline_exempt, exceed_limit;
        
@@ -735,6 +738,9 @@ channel {
        /* max chans: The maximum number of channels a user can join/be on. */
        max_chans_per_user = 15;
 
+       /* max chans (large): The extended maximum number of channels a user can join. */
+       max_chans_per_user_large = 60;
+
        /* max bans: maximum number of +b/e/I/q modes in a channel */
        max_bans = 100;
 
index 55f8e596a33e05aa8fc642716fd59d4ec702c466..54c06baa0681183f5c7e58ff3972e671069df7e4 100644 (file)
@@ -41,6 +41,7 @@ extension_LTLIBRARIES =               \
   sno_whois.la                 \
   m_42.la                      \
   m_adminwall.la                       \
+  m_extendchans.la             \
   m_findforwards.la            \
   m_identify.la                        \
   m_mkpasswd.la                  \
index 0639b26c302c4ee9f81ab6d0980973551220459f..fb67d342ac956269b0b7a0f2f688a4b263708405 100644 (file)
@@ -227,6 +227,9 @@ m_42_la_OBJECTS = m_42.lo
 m_adminwall_la_LIBADD =
 m_adminwall_la_SOURCES = m_adminwall.c
 m_adminwall_la_OBJECTS = m_adminwall.lo
+m_extendchans_la_LIBADD =
+m_extendchans_la_SOURCES = m_extendchans.c
+m_extendchans_la_OBJECTS = m_extendchans.lo
 m_findforwards_la_LIBADD =
 m_findforwards_la_SOURCES = m_findforwards.c
 m_findforwards_la_OBJECTS = m_findforwards.lo
@@ -353,11 +356,11 @@ SOURCES = chm_adminonly.c chm_nonotice.c chm_operonly.c \
        extb_realname.c extb_server.c extb_ssl.c extb_usermode.c \
        force_user_invis.c hide_uncommon_channels.c hurt.c \
        ip_cloaking.c ip_cloaking_3.0.c ip_cloaking_4.0.c \
-       ip_cloaking_old.c m_42.c m_adminwall.c m_findforwards.c \
-       m_identify.c m_mkpasswd.c m_ojoin.c m_okick.c m_omode.c \
-       m_opme.c m_remove.c m_roleplay.c m_sendbans.c m_webirc.c \
-       no_kill_services.c no_locops.c no_oper_invis.c override.c \
-       restrict-unauthenticated.c sno_channelcreate.c \
+       ip_cloaking_old.c m_42.c m_adminwall.c m_extendchans.c \
+       m_findforwards.c m_identify.c m_mkpasswd.c m_ojoin.c m_okick.c \
+       m_omode.c m_opme.c m_remove.c m_roleplay.c m_sendbans.c \
+       m_webirc.c no_kill_services.c no_locops.c no_oper_invis.c \
+       override.c restrict-unauthenticated.c sno_channelcreate.c \
        sno_farconnect.c sno_globalkline.c sno_globaloper.c \
        sno_whois.c spy_admin_notice.c spy_info_notice.c \
        spy_links_notice.c spy_motd_notice.c spy_stats_notice.c \
@@ -370,11 +373,11 @@ DIST_SOURCES = chm_adminonly.c chm_nonotice.c chm_operonly.c \
        extb_realname.c extb_server.c extb_ssl.c extb_usermode.c \
        force_user_invis.c hide_uncommon_channels.c hurt.c \
        ip_cloaking.c ip_cloaking_3.0.c ip_cloaking_4.0.c \
-       ip_cloaking_old.c m_42.c m_adminwall.c m_findforwards.c \
-       m_identify.c m_mkpasswd.c m_ojoin.c m_okick.c m_omode.c \
-       m_opme.c m_remove.c m_roleplay.c m_sendbans.c m_webirc.c \
-       no_kill_services.c no_locops.c no_oper_invis.c override.c \
-       restrict-unauthenticated.c sno_channelcreate.c \
+       ip_cloaking_old.c m_42.c m_adminwall.c m_extendchans.c \
+       m_findforwards.c m_identify.c m_mkpasswd.c m_ojoin.c m_okick.c \
+       m_omode.c m_opme.c m_remove.c m_roleplay.c m_sendbans.c \
+       m_webirc.c no_kill_services.c no_locops.c no_oper_invis.c \
+       override.c restrict-unauthenticated.c sno_channelcreate.c \
        sno_farconnect.c sno_globalkline.c sno_globaloper.c \
        sno_whois.c spy_admin_notice.c spy_info_notice.c \
        spy_links_notice.c spy_motd_notice.c spy_stats_notice.c \
@@ -624,6 +627,7 @@ extension_LTLIBRARIES = \
   sno_whois.la                 \
   m_42.la                      \
   m_adminwall.la                       \
+  m_extendchans.la             \
   m_findforwards.la            \
   m_identify.la                        \
   m_mkpasswd.la                  \
@@ -807,6 +811,9 @@ m_42.la: $(m_42_la_OBJECTS) $(m_42_la_DEPENDENCIES) $(EXTRA_m_42_la_DEPENDENCIES
 m_adminwall.la: $(m_adminwall_la_OBJECTS) $(m_adminwall_la_DEPENDENCIES) $(EXTRA_m_adminwall_la_DEPENDENCIES) 
        $(AM_V_CCLD)$(LINK) -rpath $(extensiondir) $(m_adminwall_la_OBJECTS) $(m_adminwall_la_LIBADD) $(LIBS)
 
+m_extendchans.la: $(m_extendchans_la_OBJECTS) $(m_extendchans_la_DEPENDENCIES) $(EXTRA_m_extendchans_la_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) -rpath $(extensiondir) $(m_extendchans_la_OBJECTS) $(m_extendchans_la_LIBADD) $(LIBS)
+
 m_findforwards.la: $(m_findforwards_la_OBJECTS) $(m_findforwards_la_DEPENDENCIES) $(EXTRA_m_findforwards_la_DEPENDENCIES) 
        $(AM_V_CCLD)$(LINK) -rpath $(extensiondir) $(m_findforwards_la_OBJECTS) $(m_findforwards_la_LIBADD) $(LIBS)
 
@@ -927,6 +934,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_cloaking_old.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_42.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_adminwall.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_extendchans.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_findforwards.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_identify.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_mkpasswd.Plo@am__quote@
diff --git a/extensions/m_extendchans.c b/extensions/m_extendchans.c
new file mode 100644 (file)
index 0000000..9dd33de
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ *  charybdis
+ *  m_extendchans.c: Allow an oper or service to let a given user join more channels.
+ *
+ *  Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ *  Copyright (C) 1996-2002 Hybrid Development Team
+ *  Copyright (C) 2002-2006 ircd-ratbox development team
+ *  Copyright (C) 2006-2016 ircd-seven development team
+ *  Copyright (C) 2015-2016 ChatLounge IRC Network Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+ *  USA
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "modules.h"
+#include "s_newconf.h"
+#include "send.h"
+#include "numeric.h"
+
+static int mo_extendchans(struct Client *, struct Client *, int, const char **);
+static int me_extendchans(struct Client *, struct Client *, int, const char **);
+
+struct Message extendchans_msgtab = {
+       "EXTENDCHANS", 0, 0, 0, MFLG_SLOW,
+       { mg_unreg, mg_ignore, mg_ignore, mg_ignore, {me_extendchans, 2}, {mo_extendchans, 2}}
+};
+
+mapi_clist_av1 extendchans_clist[] = { &extendchans_msgtab, NULL };
+
+DECLARE_MODULE_AV1(extendchans, NULL, NULL, extendchans_clist, NULL, NULL, "$Revision: $");
+
+static int
+mo_extendchans(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+       struct Client *target_p;
+
+       if(!HasPrivilege(source_p, "oper:extendchans"))
+       {
+               sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "extendchans");
+               return 0;
+       }
+
+       if(EmptyString(parv[1]))
+       {
+               sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "EXTENDCHANS");
+               return 0;
+       }
+
+       if((target_p = find_chasing(source_p, parv[1], NULL)) == NULL)
+               return 0;
+       
+       /* Is the target user local? */
+       if(MyClient(target_p))
+       {
+               sendto_one_notice(target_p, ":*** %s (%s@%s) is extending your channel limit",
+                       source_p->name, source_p->username, source_p->host);
+               SetExtendChans(target_p);
+       }
+       else /* Target user isn't local, so pass it on. */
+       {
+               struct Client *cptr = target_p->servptr;
+               sendto_one(cptr, ":%s ENCAP %s EXTENDCHANS %s",
+                       get_id(source_p, cptr), cptr->name, get_id(target_p, cptr));
+       }
+
+       sendto_one_notice(source_p, ":You have extended the channel limit on: %s (%s@%s)",
+               target_p->name, target_p->username, target_p->orighost);
+
+       return 0;
+}
+
+static int
+me_extendchans(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+       struct Client *target_p;
+
+       target_p = find_person(parv[1]);
+       if(target_p == NULL)
+       {
+               sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), parv[1]);
+               return 0;
+       }
+
+       /* Is the target user local?  If not, pass it on. */
+       if(!MyClient(target_p))
+       {
+               struct Client *cptr = target_p->servptr;
+               sendto_one(cptr, ":%s ENCAP %s EXTENDCHANS %s",
+                       get_id(source_p, cptr), cptr->name, get_id(target_p, cptr));
+               return 0;
+       }
+
+       sendto_one_notice(target_p, ":*** %s (%s@%s) is extending your channel limit",
+               source_p->name, source_p->username, source_p->host);
+       SetExtendChans(target_p);
+
+       return 0;
+}
index 09bc400451cb84a1dd36cb22966c15454e09a775..0ecebc19c4f65fe1a24b8cc670783b4a548d172d 100644 (file)
@@ -420,6 +420,7 @@ struct PreClient
 
 /* overflow flags */
 /* EARLIER FLAGS ARE IN s_newconf.h */
+#define FLAGS2_EXTENDCHANS     0x00200000
 #define FLAGS2_EXEMPTRESV      0x00400000
 #define FLAGS2_EXEMPTKLINE      0x00800000
 #define FLAGS2_EXEMPTFLOOD      0x01000000
@@ -536,6 +537,8 @@ struct PreClient
 #define SetExemptResv(x)       ((x)->flags2 |= FLAGS2_EXEMPTRESV)
 #define IsIPSpoof(x)            ((x)->flags2 & FLAGS2_IP_SPOOFING)
 #define SetIPSpoof(x)           ((x)->flags2 |= FLAGS2_IP_SPOOFING)
+#define IsExtendChans(x)       ((x)->flags2 & FLAGS2_EXTENDCHANS)
+#define SetExtendChans(x)      ((x)->flags2 |= FLAGS2_EXTENDCHANS)
 
 /* for local users: flood grace period is over
  * for servers: mentioned in networknotice.c notice
index 42e267051805f5ee23d27b8e04cf9cb0b2033d70..3e71f7153d7cf8035a5c8ca77a9ed22f748d18c8 100644 (file)
@@ -110,6 +110,7 @@ struct ConfItem
 #define CONF_FLAGS_EXEMPTSHIDE         0x00010000
 #define CONF_FLAGS_EXEMPTJUPE          0x00020000      /* exempt from resv generating warnings */
 #define CONF_FLAGS_NEED_SASL           0x00040000
+#define CONF_FLAGS_EXTEND_CHANS                0x00080000
 #define CONF_FLAGS_ENCRYPTED            0x00200000
 #define CONF_FLAGS_EXEMPTDNSBL         0x04000000
 
@@ -132,6 +133,7 @@ struct ConfItem
 #define IsConfEncrypted(x)      ((x)->flags & CONF_FLAGS_ENCRYPTED)
 #define IsNeedSasl(x)          ((x)->flags & CONF_FLAGS_NEED_SASL)
 #define IsConfExemptDNSBL(x)   ((x)->flags & CONF_FLAGS_EXEMPTDNSBL)
+#define IsConfExtendChans(x)   ((x)->flags & CONF_FLAGS_EXTEND_CHANS)
 #define IsConfSSLNeeded(x)     ((x)->flags & CONF_FLAGS_NEED_SSL)
 
 /* flag definitions for opers now in client.h */
@@ -248,6 +250,7 @@ struct config_channel_entry
        int max_bans;
        int max_bans_large;
        int max_chans_per_user;
+       int max_chans_per_user_large;
        int no_create_on_split;
        int no_join_on_split;
        int default_split_server_count;
index 6569308403ed1c67d2719b55c128fedba5d3eda8..f6cbd44b604147b79b9cc9fffdb3bbf81087d860 100644 (file)
@@ -344,6 +344,7 @@ static struct mode_table auth_table[] = {
        {"have_ident",          CONF_FLAGS_NEED_IDENTD  },
        {"need_ssl",            CONF_FLAGS_NEED_SSL     },
        {"need_sasl",           CONF_FLAGS_NEED_SASL    },
+       {"extend_chans",        CONF_FLAGS_EXTEND_CHANS },
        {NULL, 0}
 };
 
@@ -2440,6 +2441,7 @@ static struct ConfEntry conf_channel_table[] =
        { "max_bans",           CF_INT,   NULL, 0, &ConfigChannel.max_bans              },
        { "max_bans_large",     CF_INT,   NULL, 0, &ConfigChannel.max_bans_large        },
        { "max_chans_per_user", CF_INT,   NULL, 0, &ConfigChannel.max_chans_per_user    },
+       { "max_chans_per_user_large", CF_INT,   NULL, 0, &ConfigChannel.max_chans_per_user_large        },
        { "no_create_on_split", CF_YESNO, NULL, 0, &ConfigChannel.no_create_on_split    },
        { "no_join_on_split",   CF_YESNO, NULL, 0, &ConfigChannel.no_join_on_split      },
        { "only_ascii_channels", CF_YESNO, NULL, 0, &ConfigChannel.only_ascii_channels },
index ebd6919bb8fc6a82da5c1d69de3b3c5f71e34b06..214fc553acc2044272f3308ea36ef88cca3808a7 100644 (file)
@@ -780,6 +780,7 @@ set_default_conf(void)
        ConfigChannel.knock_delay = 300;
        ConfigChannel.knock_delay_channel = 60;
        ConfigChannel.max_chans_per_user = 15;
+       ConfigChannel.max_chans_per_user_large = 60;
        ConfigChannel.max_bans = 25;
        ConfigChannel.max_bans_large = 500;
        ConfigChannel.only_ascii_channels = NO;
index ad95ff54dd8a705635da97622b762f7d4e7a1412..55a0bb557771e4250e7d6d9ff78c12e724c5a856 100644 (file)
@@ -868,6 +868,12 @@ report_and_set_user_flags(struct Client *source_p, struct ConfItem *aconf)
                SetExemptShide(source_p);
                sendto_one_notice(source_p, ":*** You are exempt from serverhiding");
        }
+
+       if(IsConfExtendChans(aconf))
+       {
+               SetExtendChans(source_p);
+               sendto_one_notice(source_p, ":*** You are exempt from normal channel limits");
+       }
 }
 
 static void
@@ -1309,6 +1315,7 @@ oper_up(struct Client *source_p, struct oper_conf *oper_p)
 
        Count.oper++;
 
+       SetExtendChans(source_p);
        SetExemptKline(source_p);
 
        source_p->flags2 |= oper_p->flags;
index b45728e3b97565bdfa349e39cd55519325460f2f..a19e23357f909be3184a6074c1e1f1d1f42e8ee1 100644 (file)
@@ -278,9 +278,9 @@ m_join(struct Client *client_p, struct Client *source_p, int parc, const char *p
 
                if((rb_dlink_list_length(&source_p->user->channel) >=
                    (unsigned long) ConfigChannel.max_chans_per_user) &&
-                  (!IsOper(source_p) ||
+                  (!IsExtendChans(source_p) ||
                    (rb_dlink_list_length(&source_p->user->channel) >=
-                    (unsigned long) ConfigChannel.max_chans_per_user * 3)))
+                    (unsigned long) ConfigChannel.max_chans_per_user_large)))
                {
                        sendto_one(source_p, form_str(ERR_TOOMANYCHANNELS),
                                   me.name, source_p->name, name);
index 301b964572794a832098c47bcbc63a1a59759c36..202716a658ef9afc0353d8a0d1cb3143ea3399f6 100644 (file)
@@ -584,6 +584,12 @@ static struct InfoStruct info_table[] = {
                &ConfigChannel.max_chans_per_user,
                "Maximum number of channels a user can join",
        },
+       {
+               "max_chans_per_user_large",
+               OUTPUT_DECIMAL,
+               &ConfigChannel.max_chans_per_user_large,
+               "Maximum extended number of channels a user can join",
+       },
        {
                "no_create_on_split",
                OUTPUT_BOOLEAN_YN,
index 65cbbf7d29b388064dfe73fb481d64b36b307b87..8388442ae85fe33e8d3ee4d060c61b82cb2fa607 100644 (file)
@@ -69,6 +69,7 @@ static struct mode_table auth_client_table[] = {
        {"spambot_exempt",      FLAGS2_EXEMPTSPAMBOT    },
        {"shide_exempt",        FLAGS2_EXEMPTSHIDE      },
        {"jupe_exempt",         FLAGS2_EXEMPTJUPE       },
+       {"extend_chans",        FLAGS2_EXTENDCHANS      },
        {NULL, 0}
 };