Implement new configuration option "AllowedChannelTypes" bug152-AllowedChannelTypes
authorAlexander Barton <alex@barton.de>
Sun, 4 Aug 2013 01:06:53 +0000 (03:06 +0200)
committerAlexander Barton <alex@barton.de>
Sun, 4 Aug 2013 12:10:12 +0000 (14:10 +0200)
The new configuration variable "AllowedChannelTypes" lists all allowed
channel types (channel prefixes) for newly created channels on the local
server. By default, all supported channel types are allowed.

If set to the empty string, local clients can't create new channels at
all, which equals the old "PredefChannelsOnly = yes" setting.

This patch deprecates the "PredefChannelsOnly" variable, too, but it is
still supported and translated to the apropriate "AllowedChannelTypes"
setting. When "PredefChannelsOnly" is processed, a warning message is
logged.

Closes bug #152.

doc/sample-ngircd.conf.tmpl
man/ngircd.conf.5.tmpl
src/ngircd/conf.c
src/ngircd/conf.h
src/ngircd/irc-channel.c

index 31333ec2c7265cb40253a2e63291c781a2d47c90..99960e95f0d16a40b827ed67fd08fe60b39741bf 100644 (file)
        # behavior of ngIRCd. If you want to get started quickly, you most
        # probably don't have to make changes here -- they are all optional.
 
+       # List of allowed channel types (channel prefixes) for newly created
+       # channels on the local server. By default, all supported channel
+       # types are allowed. Set this variable to the empty string to disallow
+       # creation of new channels by local clients at all.
+       ;AllowedChannelTypes = #&+
+
        # Are remote IRC operators allowed to control this server, e.g.
        # use commands like CONNECT, SQUIT, DIE, ...?
        ;AllowRemoteOper = no
        # character prepended to their respective user names!
        ;PAMIsOptional = no
 
-       # Allow Pre-Defined Channels only (see Section [Channels])
-       ;PredefChannelsOnly = no
-
        # Let ngIRCd send an "authentication PING" when a new client connects,
        # and register this client only after receiving the corresponding
        # "PONG" reply.
index 64acd9273456f7d12dc2dba4de5ba8eb5f041bc9..c9d7bf8318c00eb2505432d11b0e6722852e5a43 100644 (file)
@@ -209,6 +209,12 @@ Optional features and configuration options to further tweak the behavior of
 ngIRCd. If you want to get started quickly, you most probably don't have to
 make changes here -- they are all optional.
 .TP
+\fBAllowedChannelTypes\fR (string)
+List of allowed channel types (channel prefixes) for newly created channels
+on the local server. By default, all supported channel types are allowed.
+Set this variable to the empty string to disallow creation of new channels
+by local clients at all. Default: #&+
+.TP
 \fBAllowRemoteOper\fR (boolean)
 Are IRC operators connected to remote servers allowed to control this server,
 e.g. are they allowed to use administrative commands like CONNECT, DIE,
@@ -319,12 +325,6 @@ able to distinguish between Ident'ified and PAM-authenticated users: both
 don't have a "~" character prepended to their respective user names!
 Default: no.
 .TP
-\fBPredefChannelsOnly\fR (boolean)
-If enabled, no new channels can be created. Useful if you do not want to have
-other channels than those defined in [Channel] sections in the configuration
-file on this server.
-Default: no.
-.TP
 \fBRequireAuthPing\fR (boolean)
 Let ngIRCd send an "authentication PING" when a new client connects, and
 register this client only after receiving the corresponding "PONG" reply.
index bae5fa7ad7b8f96467eb200092d0a85440102d7a..70c96092a12912c7042d4d36226f3f6b099dcb64 100644 (file)
@@ -391,6 +391,7 @@ Conf_Test( void )
        puts("");
 
        puts("[OPTIONS]");
+       printf("  AllowedChannelTypes = %s\n", Conf_AllowedChannelTypes);
        printf("  AllowRemoteOper = %s\n", yesno_to_str(Conf_AllowRemoteOper));
        printf("  ChrootDir = %s\n", Conf_Chroot);
        printf("  CloakHost = %s\n", Conf_CloakHost);
@@ -415,7 +416,6 @@ Conf_Test( void )
        printf("  PAM = %s\n", yesno_to_str(Conf_PAM));
        printf("  PAMIsOptional = %s\n", yesno_to_str(Conf_PAMIsOptional));
 #endif
-       printf("  PredefChannelsOnly = %s\n", yesno_to_str(Conf_PredefChannelsOnly));
 #ifndef STRICT_RFC
        printf("  RequireAuthPing = %s\n", yesno_to_str(Conf_AuthPing));
 #endif
@@ -758,6 +758,8 @@ Set_Defaults(bool InitServers)
        Conf_PongTimeout = 20;
 
        /* Options */
+       strlcpy(Conf_AllowedChannelTypes, CHANTYPES,
+               sizeof(Conf_AllowedChannelTypes));
        Conf_AllowRemoteOper = false;
 #ifndef STRICT_RFC
        Conf_AuthPing = false;
@@ -792,7 +794,6 @@ Set_Defaults(bool InitServers)
        Conf_PAM = false;
 #endif
        Conf_PAMIsOptional = false;
-       Conf_PredefChannelsOnly = false;
 #ifdef SYSLOG
        Conf_ScrubCTCP = false;
 #ifdef LOG_LOCAL5
@@ -1633,12 +1634,37 @@ static void
 Handle_OPTIONS(const char *File, int Line, char *Var, char *Arg)
 {
        size_t len;
+       char *p;
 
        assert(File != NULL);
        assert(Line > 0);
        assert(Var != NULL);
        assert(Arg != NULL);
 
+       if (strcasecmp(Var, "AllowedChannelTypes") == 0) {
+               p = Arg;
+               Conf_AllowedChannelTypes[0] = '\0';
+               while (*p) {
+                       if (strchr(Conf_AllowedChannelTypes, *p)) {
+                               /* Prefix is already included; ignore it */
+                               p++;
+                               continue;
+                       }
+
+                       if (strchr(CHANTYPES, *p)) {
+                               len = strlen(Conf_AllowedChannelTypes) + 1;
+                               assert(len < sizeof(Conf_AllowedChannelTypes));
+                               Conf_AllowedChannelTypes[len - 1] = *p;
+                               Conf_AllowedChannelTypes[len] = '\0';
+                       } else {
+                               Config_Error(LOG_WARNING,
+                                            "%s, line %d: Unknown channel prefix \"%c\" in \"AllowedChannelTypes\"!",
+                                            File, Line, *p);
+                       }
+                       p++;
+               }
+               return;
+       }
        if (strcasecmp(Var, "AllowRemoteOper") == 0) {
                Conf_AllowRemoteOper = Check_ArgIsTrue(Arg);
                return;
@@ -1731,7 +1757,19 @@ Handle_OPTIONS(const char *File, int Line, char *Var, char *Arg)
                return;
        }
        if (strcasecmp(Var, "PredefChannelsOnly") == 0) {
-               Conf_PredefChannelsOnly = Check_ArgIsTrue(Arg);
+               /*
+                * TODO: This section and support for "PredefChannelsOnly"
+                * could be removed starting with ngIRCd release 22 (one
+                * release after marking it "deprecated") ...
+                */
+               Config_Error(LOG_WARNING,
+                            "%s, line %d (section \"Options\"): \"%s\" is deprecated, please use \"AllowedChannelTypes\"!",
+                            File, Line, Var);
+               if (Check_ArgIsTrue(Arg))
+                       Conf_AllowedChannelTypes[0] = '\0';
+               else
+                       strlcpy(Conf_AllowedChannelTypes, CHANTYPES,
+                               sizeof(Conf_AllowedChannelTypes));
                return;
        }
 #ifndef STRICT_RFC
index bbf4f36c24c4ff29d1c2b3dc99ba58897f658443..93d6785f2adb9499eb3d000e7fa45689c62d950a 100644 (file)
@@ -148,8 +148,8 @@ GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS];
 /** Array of pre-defined channels */
 GLOBAL array Conf_Channels;
 
-/** Flag indicating if only pre-defined channels are allowed (true) or not */
-GLOBAL bool Conf_PredefChannelsOnly;
+/** String containing all locally allowed channel prefixes for new channels */
+GLOBAL char Conf_AllowedChannelTypes[8];
 
 /** Flag indicating if IRC operators are allowed to always use MODE (true) */
 GLOBAL bool Conf_OperCanMode;
index c683640149cd9b618340d4871d69ed35fcac8632..16501becbaed1651625942c0c9f675bf33ce21e9 100644 (file)
@@ -344,7 +344,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
                }
 
                chan = Channel_Search(channame);
-               if (!chan && Conf_PredefChannelsOnly) {
+               if (!chan && !strchr(Conf_AllowedChannelTypes, channame[0])) {
                         /* channel must be created, but forbidden by config */
                        IRC_WriteStrClient(Client, ERR_NOSUCHCHANNEL_MSG,
                                           Client_ID(Client), channame);