diff --git a/doc/sample-ngircd.conf.tmpl b/doc/sample-ngircd.conf.tmpl index 31333ec2..99960e95 100644 --- a/doc/sample-ngircd.conf.tmpl +++ b/doc/sample-ngircd.conf.tmpl @@ -128,6 +128,12 @@ # 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 @@ -209,9 +215,6 @@ # 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. diff --git a/man/ngircd.conf.5.tmpl b/man/ngircd.conf.5.tmpl index 64acd927..c9d7bf83 100644 --- a/man/ngircd.conf.5.tmpl +++ b/man/ngircd.conf.5.tmpl @@ -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. diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index bae5fa7a..70c96092 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -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 diff --git a/src/ngircd/conf.h b/src/ngircd/conf.h index bbf4f36c..93d6785f 100644 --- a/src/ngircd/conf.h +++ b/src/ngircd/conf.h @@ -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; diff --git a/src/ngircd/irc-channel.c b/src/ngircd/irc-channel.c index c6836401..16501bec 100644 --- a/src/ngircd/irc-channel.c +++ b/src/ngircd/irc-channel.c @@ -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);