Commit Diff


commit - b1786f309ecc29216a8d0b919cd514c8f69f24bf
commit + 3282c1325e491f2fbc7ee388c557f40e1f9eaed6
blob - 8547efc16463fa7ac062f2754f173e5becc93511
blob + 1e96e16e24517cb654db7f52b59b137e4a59efeb
--- INSTALL
+++ INSTALL
@@ -16,6 +16,38 @@ Differences to version 17
 
 - Support for ZeroConf/Bonjour/Rendezvous service registration has been
   removed. The configuration option "NoZeroconf" is no longer available.
+
+- The structure of ngircd.conf has been cleaned up and three new configuration
+  sections have been introduced: [Limits], [Options], and [SSL].
+  Lots of configuration variables stored in the [Global] section are now
+  deprecated there and should be stored in one of these new sections (but
+  still work in [Global]):
+    "AllowRemoteOper"    -> [Options]
+    "ChrootDir"          -> [Options]
+    "ConnectIPv4"        -> [Options]
+    "ConnectIPv6"        -> [Options]
+    "ConnectRetry"       -> [Limits]
+    "MaxConnections"     -> [Limits]
+    "MaxConnectionsIP"   -> [Limits]
+    "MaxJoins"           -> [Limits]
+    "MaxNickLength"      -> [Limits]
+    "NoDNS"              -> [Options], and renamed to "DNS"
+    "NoIdent"            -> [Options], and renamed to "Ident"
+    "NoPAM"              -> [Options], and renamed to "PAM"
+    "OperCanUseMode"     -> [Options]
+    "OperServerMode"     -> [Options]
+    "PingTimeout"        -> [Limits]
+    "PongTimeout"        -> [Limits]
+    "PredefChannelsOnly" -> [Options]
+    "SSLCertFile"        -> [SSL], and renamed to "CertFile"
+    "SSLDHFile"          -> [SSL], and renamed to "DHFile"
+    "SSLKeyFile"         -> [SSL], and renamed to "KeyFile"
+    "SSLKeyFilePassword" -> [SSL], and renamed to "KeyFilePassword"
+    "SSLPorts"           -> [SSL], and renamed to "Ports"
+    "SyslogFacility"     -> [Options]
+    "WebircPassword"     -> [Options]
+  You should adjust your ngircd.conf and run "ngircd --configtest" to make
+  sure that your settings are correct and up to date!
 
 Differences to version 16
 
blob - b5a36b843ca35505f1d05d61d42cf14f00ae5ec9
blob + 0f2e7ee8c609ef1ea3e91e5785168e2bd42ca1dc
--- doc/sample-ngircd.conf.tmpl
+++ doc/sample-ngircd.conf.tmpl
@@ -12,69 +12,37 @@
 # Use "ngircd --configtest" (see manual page ngircd(8)) to validate that the
 # server interprets the configuration file as expected!
 #
-# Please see ngircd.conf(5) for a complete list of configuration options.
+# Please see ngircd.conf(5) for a complete list of configuration options
+# and their descriptions.
 #
 
 [Global]
 	# The [Global] section of this file is used to define the main
 	# configuration of the server, like the server name and the ports
 	# on which the server should be listening.
+	# These settings depend on your personal preferences, so you should
+	# make sure that they correspond to your installation and setup!
 
 	# Server name in the IRC network, must contain at least one dot
 	# (".") and be unique in the IRC network. Required!
 	Name = irc.example.net
 
-	# Info text of the server. This will be shown by WHOIS and
-	# LINKS requests for example.
-	Info = Server Info Text
-
-	# Global password for all users needed to connect to the server.
-	# (Default: not set)
-	;Password = abc
-
-	# Password required for using the WEBIRC command used by some
-	# Web-to-IRC gateways. If not set/empty, the WEBIRC command can't
-	# be used. (Default: not set)
-	;WebircPassword = xyz
-
 	# Information about the server and the administrator, used by the
 	# ADMIN command. Not required by server but by RFC!
 	;AdminInfo1 = Description
 	;AdminInfo2 = Location
 	;AdminEMail = admin@irc.server
 
-	# Ports on which the server should listen. There may be more than
-	# one port, separated with ",". (Default: 6667)
-	;Ports = 6667, 6668, 6669
+	# Info text of the server. This will be shown by WHOIS and
+	# LINKS requests for example.
+	Info = Server Info Text
 
-	# Additional Listen Ports that expect SSL/TLS encrypted connections
-	;SSLPorts = 6697, 9999
-
-	# SSL Server Key
-	;SSLKeyFile = :ETCDIR:/ssl/server-key.pem
-
-	# password to decrypt SSLKeyFile (OpenSSL only)
-	;SSLKeyFilePassword = secret
-
-	# SSL Server Key Certificate
-	;SSLCertFile = :ETCDIR:/ssl/server-cert.pem
-
-	# Diffie-Hellman parameters
-	;SSLDHFile = :ETCDIR:/ssl/dhparams.pem
-
-	# comma separated list of IP addresses on which the server should
+	# Comma separated list of IP addresses on which the server should
 	# listen. Default values are:
 	# "0.0.0.0" or (if compiled with IPv6 support) "::,0.0.0.0"
 	# so the server listens on all IP addresses of the system by default.
 	;Listen = 127.0.0.1,192.168.0.1
 
-	# Syslog "facility" to which ngIRCd should send log messages.
-	# Possible values are system dependant, but most probably auth, daemon,
-	# user and local1 through local7 are possible values; see syslog(3).
-	# Default is "local5" for historical reasons, you probably want to
-	# change this to "daemon", for example.
-	SyslogFacility = local1
-
 	# Text file with the "message of the day" (MOTD). This message will
 	# be shown to all users connecting to the server:
 	;MotdFile = :ETCDIR:/ngircd.motd
@@ -82,6 +50,25 @@
 	# A simple Phrase (<256 chars) if you don't want to use a motd file.
 	;MotdPhrase = "Hello world!"
 
+	# Global password for all users needed to connect to the server.
+	# (Default: not set)
+	;Password = abc
+
+	# This tells ngIRCd to write its current process ID to a file.
+	# Note that the pidfile is written AFTER chroot and switching the
+	# user ID, e.g. the directory the pidfile resides in must be
+	# writeable by the ngIRCd user and exist in the chroot directory.
+	;PidFile = /var/run/ngircd/ngircd.pid
+
+	# Ports on which the server should listen. There may be more than
+	# one port, separated with ",". (Default: 6667)
+	;Ports = 6667, 6668, 6669
+
+	# Group ID under which the ngIRCd should run; you can use the name
+	# of the group or the numerical ID. ATTENTION: For this to work the
+	# server must have been started with root privileges!
+	;ServerGID = 65534
+
 	# User ID under which the server should run; you can use the name
 	# of the user or the numerical ID. ATTENTION: For this to work the
 	# server must have been started with root privileges! In addition,
@@ -89,55 +76,14 @@
 	# otherwise RESTART and REHASH won't work!
 	;ServerUID = 65534
 
-	# Group ID under which the ngircd should run; you can use the name
-	# of the group or the numerical ID. ATTENTION: For this to work the
-	# server must have been started with root privileges!
-	;ServerGID = 65534
+[Limits]
+	# Define some limits and timeouts for this ngIRCd instance. Default
+	# values should be safe, but it is wise to double-check :-)
 
-	# A directory to chroot in when everything is initialized. It
-	# doesn't need to be populated if ngIRCd is compiled as a static
-	# binary. By default ngIRCd won't use the chroot() feature.
-	# ATTENTION: For this to work the server must have been started
-	# with root privileges!
-	;ChrootDir = /var/empty
-
-	# This tells ngircd to write its current process id to a file.
-	# Note that the pidfile is written AFTER chroot and switching uid,
-	# i. e. the Directory the pidfile resides in must be writeable by
-	# the ngircd user and exist in the chroot directory.
-	;PidFile = /var/run/ngircd/ngircd.pid
-
-	# After <PingTimeout> seconds of inactivity the server will send a
-	# PING to the peer to test whether it is alive or not.
-	;PingTimeout = 120
-
-	# If a client fails to answer a PING with a PONG within <PongTimeout>
-	# seconds, it will be disconnected by the server.
-	;PongTimeout = 20
-
 	# The server tries every <ConnectRetry> seconds to establish a link
 	# to not yet (or no longer) connected servers.
 	;ConnectRetry = 60
-
-	# Should IRC Operators be allowed to use the MODE command even if
-	# they are not(!) channel-operators?
-	;OperCanUseMode = no
-
-	# Mask IRC Operator mode requests as if they were coming from the
-	# server? (This is a compatibility hack for ircd-irc2 servers)
-	;OperServerMode = no
-
-	# Are remote IRC operators allowed to control this server, e. g.
-	# use commands like CONNECT, SQUIT, DIE, ...?
-	;AllowRemoteOper = no
 
-	# Allow Pre-Defined Channels only (see Section [Channels])
-	;PredefChannelsOnly = no
-
-	# try to connect to other irc servers using ipv4 and ipv6, if possible
-	;ConnectIPv6 = yes
-	;ConnectIPv4 = yes
-
 	# Maximum number of simultaneous in- and outbound connections the
 	# server is allowed to accept (0: unlimited):
 	;MaxConnections = 0
@@ -154,16 +100,30 @@
 	# maximum nick name length!
 	;MaxNickLength = 9
 
-	# Normally ngIRCd doesn't send any messages to a client until it is
-	# registered. Enable this option to let the daemon send "NOTICE AUTH"
-	# messages to clients while connecting.
-	;NoticeAuth = no
+	# After <PingTimeout> seconds of inactivity the server will send a
+	# PING to the peer to test whether it is alive or not.
+	;PingTimeout = 120
 
-	# Let ngIRCd send an "authentication PING" when a new client connects,
-	# and register this client only after receiving the corresponding
-	# "PONG" reply.
-	;RequireAuthPing = no
+	# If a client fails to answer a PING with a PONG within <PongTimeout>
+	# seconds, it will be disconnected by the server.
+	;PongTimeout = 20
 
+[Options]
+	# Optional features and configuration options to further tweak the
+	# behavior of ngIRCd. If you wan't to get started quickly, you most
+	# probably don't have to make changes here -- they are all optional.
+
+	# Are remote IRC operators allowed to control this server, e.g.
+	# use commands like CONNECT, SQUIT, DIE, ...?
+	;AllowRemoteOper = no
+
+	# A directory to chroot in when everything is initialized. It
+	# doesn't need to be populated if ngIRCd is compiled as a static
+	# binary. By default ngIRCd won't use the chroot() feature.
+	# ATTENTION: For this to work the server must have been started
+	# with root privileges!
+	;ChrootDir = /var/empty
+
 	# Set this hostname for every client instead of the real one.
 	# Please note: don't use the percentage sign ("%"), it is reserved for
 	# future extensions!
@@ -172,16 +132,72 @@
 	# Set every clients' user name to their nick name
 	;CloakUserToNick = yes
 
-[Features]
+	# Try to connect to other IRC servers using IPv4 and IPv6, if possible.
+	;ConnectIPv6 = yes
+	;ConnectIPv4 = yes
+
 	# Do any DNS lookups when a client connects to the server.
 	;DNS = yes
 
-	# Do any IDENT lookups if ngIRCd has been compiled with support for it.
+	# Do IDENT lookups if ngIRCd has been compiled with support for it.
 	;Ident = yes
 
+	# Normally ngIRCd doesn't send any messages to a client until it is
+	# registered. Enable this option to let the daemon send "NOTICE AUTH"
+	# messages to clients while connecting.
+	;NoticeAuth = no
+
+	# Should IRC Operators be allowed to use the MODE command even if
+	# they are not(!) channel-operators?
+	;OperCanUseMode = no
+
+	# Mask IRC Operator mode requests as if they were coming from the
+	# server? (This is a compatibility hack for ircd-irc2 servers)
+	;OperServerMode = no
+
 	# Use PAM if ngIRCd has been compiled with support for it.
 	;PAM = 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.
+	;RequireAuthPing = no
+
+	# Syslog "facility" to which ngIRCd should send log messages.
+	# Possible values are system dependent, but most probably auth, daemon,
+	# user and local1 through local7 are possible values; see syslog(3).
+	# Default is "local5" for historical reasons, you probably want to
+	# change this to "daemon", for example.
+	;SyslogFacility = local1
+
+	# Password required for using the WEBIRC command used by some
+	# Web-to-IRC gateways. If not set/empty, the WEBIRC command can't
+	# be used. (Default: not set)
+	;WebircPassword = xyz
+
+;[SSL]
+	# SSL-related configuration options. Please note that this section
+	# is only available when ngIRCd is compiled with support for SSL!
+	# So don't forget to remove the ";" above if this is the case ...
+
+	# SSL Server Key Certificate
+	;SSLCertFile = :ETCDIR:/ssl/server-cert.pem
+
+	# Diffie-Hellman parameters
+	;SSLDHFile = :ETCDIR:/ssl/dhparams.pem
+
+	# SSL Server Key
+	;SSLKeyFile = :ETCDIR:/ssl/server-key.pem
+
+	# password to decrypt SSLKeyFile (OpenSSL only)
+	;SSLKeyFilePassword = secret
+
+	# Additional Listen Ports that expect SSL/TLS encrypted connections
+	;SSLPorts = 6697, 9999
+
 [Operator]
 	# [Operator] sections are used to define IRC Operators. There may be
 	# more than one [Operator] block, one for each local operator.
blob - d1a0a64a8996a483edebc868a9f13931bbbf4381
blob + 68b4080097797f6018595a5892213098e14d8359
--- man/ngircd.conf.5.tmpl
+++ man/ngircd.conf.5.tmpl
@@ -1,7 +1,7 @@
 .\"
 .\" ngircd.conf(5) manual page template
 .\"
-.TH ngircd.conf 5 "Mar 2011" ngircd "ngIRCd Manual"
+.TH ngircd.conf 5 "Jun 2011" ngircd "ngIRCd Manual"
 .SH NAME
 ngircd.conf \- configuration file of ngIRCd
 .SH SYNOPSIS
@@ -10,11 +10,12 @@ ngircd.conf \- configuration file of ngIRCd
 .BR ngircd.conf
 is the configuration file of the
 .BR ngircd (8)
-Internet Relay Chat (IRC) daemon which you should adept to your local
+Internet Relay Chat (IRC) daemon, which must be customized to the local
 preferences and needs.
 .PP
 Most variables can be modified while the ngIRCd daemon is already running:
-It will reload its configuration when a HUP signal is received.
+It will reload its configuration file when a HUP signal or REHASH command
+is received.
 .SH "FILE FORMAT"
 The file consists of sections and parameters. A section begins with the name
 of the section in square brackets and continues until the next section
@@ -45,123 +46,96 @@ and
 Boolean values are
 .I true
 if they are "yes", "true", or any non-null integer. Text strings are used 1:1
-without leading and following spaces; there is not way to quote strings. And
+without leading and following spaces; there is no way to quote strings. And
 for numbers all decimal integer values are valid.
 .PP
 In addition, some string or numerical variables accept lists of values,
 separated by commas (",").
 .SH "SECTION OVERVIEW"
-The file can contain blocks of four types: [Global], [Operator], [Server],
-and [Channel].
+The file can contain blocks of seven types: [Global], [Limits], [Options],
+[SSL], [Operator], [Server], and [Channel].
 .PP
 The main configuration of the server is stored in the
 .I [Global]
-section, like the server name, administrative information and the
-ports on which the server should be listening. IRC operators of this
-server are defined in
+section, like the server name, administrative information and the ports on
+which the server should be listening. The variables in this section have to be
+adjusted to the local requirements most of the time, whereas all the variables
+in the other sections can be left on there defaults very often.
+.PP
+Options in the
+.I [Limits]
+block are used to tweak different limits and timeouts of the daemon, like the
+maximum number of clients allowed to connect to this server. Variables in the
+.I [Options]
+section can be used to enable or disable specific features of ngIRCd, like
+support for IDENT, PAM, IPv6, and protocol and cloaking features. The
+.I [SSL]
+block contains all SSL-related configuration variables. These three sections
+are all optional.
+.PP
+IRC operators of this server are defined in
 .I [Operator]
-blocks.
-.I [Features]
-can be used to disable compile-time features at run time, e.g. if ngircd
-was built to support ident lookups, but you do not want ngircd to perform
-ident lookups you can disable them here.
-This section is optional.
+blocks. Links to remote servers are configured in
 .I [Server]
-is the section where server links are configured. And
+sections. And
 .I [Channel]
 blocks are used to configure pre-defined ("persistent") IRC channels.
 .PP
-There can be more than one [Operator], [Server] and [Channel] sections
-per configuration file, but only one [Global] and one [Features] section.
+There can be more than one [Operator], [Server] and [Channel] section per
+configuration file (one for each operator, server, and channel), but only
+exactly one [Global], one [Limits], one [Options], and one [SSL] section.
 .SH [GLOBAL]
 The
 .I [Global]
-section is used to define the server main configuration, like the server
-name and the ports on which the server should be listening.
+section of this file is used to define the main configuration of the server,
+like the server name and the ports on which the server should be listening.
+These settings depend on your personal preferences, so you should make sure
+that they correspond to your installation and setup!
 .TP
-\fBName\fR (string)
+\fBName\fR (string; required)
 Server name in the IRC network. This is an individual name of the IRC
 server, it is not related to the DNS host name. It must be unique in the
 IRC network and must contain at least one dot (".") character.
 .TP
+\fBAdminInfo1\fR, \fBAdminInfo2\fR, \fBAdminEMail\fR (string)
+Information about the server and the administrator, used by the ADMIN
+command. This information is not required by the server but by RFC!
+.TP
 \fBInfo\fR (string)
 Info text of the server. This will be shown by WHOIS and LINKS requests for
 example.
 .TP
-\fBPassword\fR (string)
-Global password for all users needed to connect to the server. The default
-is empty, so no password is required.
-.TP
-\fBWebircPassword\fR (string)
-Password required for using the WEBIRC command used by some Web-to-IRC
-gateways. If not set or empty, the WEBIRC command can't be used.
-Default: not set.
-.TP
-\fBAdminInfo1\fR, \fBAdminInfo2\fR, \fBAdminEMail\fR (string)
-Information about the server and the administrator, used by the ADMIN
-command.
-.TP
-\fBPorts\fR (list of numbers)
-Ports on which the server should listen. There may be more than one port,
-separated with commas (","). Default: 6667, unless \fBSSL_Ports\fR are also
-specified.
-.TP
-\fBSSLPorts\fR (list of numbers)
-Same as \fBPorts\fR , except that ngIRCd will expect incoming connections
-to be SSL/TLS encrypted. Common port numbers for SSL-encrypted IRC are 6669
-and 6697. Default: none.
-.TP
-\fBSSLKeyFile\fR (string)
-Filename of SSL Server Key to be used for SSL connections. This is required for
-SSL/TLS support.
-.TP
-\fBSSLKeyFilePassword\fR (string)
-(OpenSSL only:) Password to decrypt private key.
-.TP
-\fBSSLCertFile\fR (string)
-Certificate file of the private key.
-.TP
-\fBSSLDHFile\fR (string)
-Name of the Diffie-Hellman Parameter file. Can be created with gnutls
-"certtool \-\-generate-dh-params" or "openssl dhparam".
-If this file is not present, it will be generated on startup when ngIRCd
-was compiled with gnutls support (this may take some time). If ngIRCd
-was compiled with OpenSSL, then (Ephemeral)-Diffie-Hellman Key Exchanges and several
-Cipher Suites will not be available.
-.TP
 \fBListen\fR (list of strings)
 A comma separated list of IP address on which the server should listen.
 If unset, the defaults value is "0.0.0.0" or, if ngIRCd was compiled
 with IPv6 support, "::,0.0.0.0". So the server listens on all configured
 IP addresses and interfaces by default.
 .TP
-\fBSyslogFacility\fR (string)
-Syslog "facility" to which ngIRCd should send log messages. Possible
-values are system dependant, but most probably "auth", "daemon", "user"
-and "local1" through "local7" are possible values; see syslog(3).
-Default is "local5" for historical reasons, you probably want to
-change this to "daemon", for example.
-.TP
 \fBMotdFile\fR (string)
-Text file with the "message of the day" (MOTD). This message will be shown
-to all users connecting to the server. Changes made to this file
-take effect when ngircd is instructed to re-read its configuration file.
+Text file with the "message of the day" (MOTD). This message will be shown to
+all users connecting to the server. Please note: Changes made to this file
+take effect when ngircd starts up or is instructed to re-read its
+configuration file.
 .TP
 \fBMotdPhrase\fR (string)
 A simple Phrase (<256 chars) if you don't want to use a MOTD file.
 .TP
-\fBServerUID\fR (string or number)
-User ID under which the server should run; you can use the name of the user
-or the numerical ID.
-.PP
-.RS
-.B Attention:
-.br
-For this to work the server must have been
-started with root privileges! In addition, the configuration and MOTD files
-must be readable by this user, otherwise RESTART and REHASH won't work!
-.RE
+\fBPassword\fR (string)
+Global password for all users needed to connect to the server. The default is
+empty, so no password is required. Please note: This feature is not available
+if ngIRCd is using PAM!
 .TP
+\fBPidFile\fR (string)
+This tells ngIRCd to write its current process ID to a file. Note that the
+pidfile is written AFTER chroot and switching the user ID, e.g. the directory
+the pidfile resides in must be writeable by the ngIRCd user and exist in the
+chroot directory (if configured, see above).
+.TP
+\fBPorts\fR (list of numbers)
+Ports on which the server should listen. There may be more than one port,
+separated with commas (","). Default: 6667, unless \fBSSL_Ports\fR are also
+specified.
+.TP
 \fBServerGID\fR (string or number)
 Group ID under which the ngIRCd should run; you can use the name of the
 group or the numerical ID.
@@ -169,70 +143,28 @@ group or the numerical ID.
 .RS
 .B Attention:
 .br
-For this to work the server must have
-been started with root privileges!
+For this to work the server must have been started with root privileges!
 .RE
 .TP
-\fBChrootDir\fR (string)
-A directory to chroot in when everything is initialized. It doesn't need
-to be populated if ngIRCd is compiled as a static binary. By default ngIRCd
-won't use the chroot() feature.
+\fBServerUID\fR (string or number)
+User ID under which the server should run; you can use the name of the user
+or the numerical ID.
 .PP
 .RS
 .B Attention:
 .br
-For this to work the server must have
-been started with root privileges!
+For this to work the server must have been started with root privileges! In
+addition, the configuration and MOTD files must be readable by this user,
+otherwise RESTART and REHASH won't work!
 .RE
+.SH [LIMITS]
+Define some limits and timeouts for this ngIRCd instance. Default values
+should be safe, but it is wise to double-check :-)
 .TP
-\fBPidFile\fR (string)
-This tells ngIRCd to write its current process ID to a file. Note that the
-pidfile is written AFTER chroot and switching the user ID, i. e. the
-directory the pidfile resides in must be writeable by the ngIRCd user and
-exist in the chroot directory (if configured, see above).
-.RE
-.TP
-\fBPingTimeout\fR (number)
-After <PingTimeout> seconds of inactivity the server will send a PING to
-the peer to test whether it is alive or not. Default: 120.
-.TP
-\fBPongTimeout\fR (number)
-If a client fails to answer a PING with a PONG within <PongTimeout>
-seconds, it will be disconnected by the server. Default: 20.
-.TP
 \fBConnectRetry\fR (number)
 The server tries every <ConnectRetry> seconds to establish a link to not yet
 (or no longer) connected servers. Default: 60.
-.TP
-\fBOperCanUseMode\fR (boolean)
-Should IRC Operators be allowed to use the MODE command even if they are
-not(!) channel-operators? Default: no.
 .TP
-\fBOperServerMode\fR (boolean)
-If \fBOperCanUseMode\fR is enabled, this may lead the compatibility problems with
-Servers that run the ircd-irc2 Software. This Option "masks" mode requests
-by non-chanops as if they were coming from the server. Default: no.
-.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,
-SQUIT, ... that affect this server? Default: no.
-.TP
-\fBPredefChannelsOnly\fR (boolean)
-If enabled, no new channels can be created. Useful if
-you do not want to have channels other than those defined in
-[Channel] sections in the configuration file.
-Default: no.
-.TP
-\fBConnectIPv4\fR (boolean)
-Set this to no if you do not want ngIRCd to connect to other IRC servers using
-IPv4. This allows usage of ngIRCd in IPv6-only setups.
-Default: yes.
-.TP
-\fBConnectIPv6\fR (boolean)
-Set this to no if you do not want ngIRCd to connect to other irc servers using IPv6.
-Default: yes.
-.TP
 \fBMaxConnections\fR (number)
 Maximum number of simultaneous in- and outbound connections the server is
 allowed to accept (0: unlimited). Default: 0.
@@ -251,16 +183,34 @@ Maximum length of an user nick name (Default: 9, as in
 note that all servers in an IRC network MUST use the same maximum nick name
 length!
 .TP
-\fBNoticeAuth\fR (boolean)
-Normally ngIRCd doesn't send any messages to a client until it is registered.
-Enable this option to let the daemon send "NOTICE AUTH" messages to clients
-while connecting. Default: no.
+\fBPingTimeout\fR (number)
+After <PingTimeout> seconds of inactivity the server will send a PING to
+the peer to test whether it is alive or not. Default: 120.
 .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.
-Default: no.
+\fBPongTimeout\fR (number)
+If a client fails to answer a PING with a PONG within <PongTimeout>
+seconds, it will be disconnected by the server. Default: 20.
+.SH [OPTIONS]
+Optional features and configuration options to further tweak the behavior of
+ngIRCd. If you wan't to get started quickly, you most probably don't have to
+make changes here -- they are all optional.
 .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,
+SQUIT, ... that affect this server? Default: no.
+.TP
+\fBChrootDir\fR (string)
+A directory to chroot in when everything is initialized. It doesn't need
+to be populated if ngIRCd is compiled as a static binary. By default ngIRCd
+won't use the chroot() feature.
+.PP
+.RS
+.B Attention:
+.br
+For this to work the server must have been started with root privileges!
+.RE
+.TP
 \fBCloakHost\fR (string)
 Set this hostname for every client instead of the real one. Default: empty,
 don't change.
@@ -274,28 +224,19 @@ Don't use the percentage sign ("%"), it is reserved fo
 \fBCloakUserToNick\fR (boolean)
 Set every clients' user name to their nick name and hide the one supplied
 by the IRC client. Default: no.
-.SH [OPERATOR]
-.I [Operator]
-sections are used to define IRC Operators. There may be more than one
-.I [Operator]
-block, one for each local operator.
 .TP
-\fBName\fR (string)
-ID of the operator (may be different of the nick name).
+\fBConnectIPv4\fR (boolean)
+Set this to no if you do not want ngIRCd to connect to other IRC servers using
+the IPv4 protocol. This allows the usage of ngIRCd in IPv6-only setups.
+Default: yes.
 .TP
-\fBPassword\fR (string)
-Password of the IRC operator.
-.TP
-\fBMask\fR (string)
-Mask that is to be checked before an /OPER for this account is accepted.
-Example: nick!ident@*.example.com
-.SH [FEATURES]
-An optional section that can be used to disable features at
-run-time. A feature is enabled by default if if ngircd was built with
-support for it.
+\fBConnectIPv6\fR (boolean)
+Set this to no if you do not want ngIRCd to connect to other IRC servers using
+the IPv6 protocol.
+Default: yes.
 .TP
 \fBDNS\fR (boolean)
-If set to false, ngIRCd will not make DNS lookups when clients connect.
+If set to false, ngIRCd will not make any DNS lookups when clients connect.
 If you configure the daemon to connect to other servers, ngIRCd may still
 perform a DNS lookup if required.
 Default: yes.
@@ -305,11 +246,92 @@ If ngIRCd is compiled with IDENT support this can be u
 lookups at run time.
 Default: yes.
 .TP
+\fBNoticeAuth\fR (boolean)
+Normally ngIRCd doesn't send any messages to a client until it is registered.
+Enable this option to let the daemon send "NOTICE AUTH" messages to clients
+while connecting. Default: no.
+.TP
+\fBOperCanUseMode\fR (boolean)
+Should IRC Operators be allowed to use the MODE command even if they are
+not(!) channel-operators? Default: no.
+.TP
+\fBOperServerMode\fR (boolean)
+If \fBOperCanUseMode\fR is enabled, this may lead the compatibility problems
+with Servers that run the ircd-irc2 Software. This Option "masks" mode
+requests by non-chanops as if they were coming from the server. Default: no;
+only enable it if you have ircd-irc2 servers in your IRC network.
+.TP
 \fBPAM\fR (boolean)
 If ngIRCd is compiled with PAM support this can be used to disable all calls
 to the PAM library at runtime; all users connecting without password are
 allowed to connect, all passwords given will fail.
 Default: yes.
+.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.
+Default: no.
+.TP
+\fBSyslogFacility\fR (string)
+Syslog "facility" to which ngIRCd should send log messages. Possible
+values are system dependent, but most probably "auth", "daemon", "user"
+and "local1" through "local7" are possible values; see syslog(3).
+Default is "local5" for historical reasons, you probably want to
+change this to "daemon", for example.
+.TP
+\fBWebircPassword\fR (string)
+Password required for using the WEBIRC command used by some Web-to-IRC
+gateways. If not set or empty, the WEBIRC command can't be used.
+Default: not set.
+.SH [SSL]
+All SSL-related configuration variables are located in the
+.I [SSL]
+section. Please note that this whole section is only recognized by ngIRCd
+when it is compiled with support for SSL using OpenSSL or GnuTLS!
+.TP
+\fBSSLCertFile\fR (string)
+SSL Certificate file of the private server key.
+.TP
+\fBSSLDHFile\fR (string)
+Name of the Diffie-Hellman Parameter file. Can be created with GnuTLS
+"certtool \-\-generate-dh-params" or "openssl dhparam". If this file is not
+present, it will be generated on startup when ngIRCd was compiled with GnuTLS
+support (this may take some time). If ngIRCd was compiled with OpenSSL, then
+(Ephemeral)-Diffie-Hellman Key Exchanges and several Cipher Suites will not be
+available.
+.TP
+\fBSSLKeyFile\fR (string)
+Filename of SSL Server Key to be used for SSL connections. This is required
+for SSL/TLS support.
+.TP
+\fBSSLKeyFilePassword\fR (string)
+OpenSSL only: Password to decrypt the private key file.
+.TP
+\fBSSLPorts\fR (list of numbers)
+Same as \fBPorts\fR , except that ngIRCd will expect incoming connections
+to be SSL/TLS encrypted. Common port numbers for SSL-encrypted IRC are 6669
+and 6697. Default: none.
+.SH [OPERATOR]
+.I [Operator]
+sections are used to define IRC Operators. There may be more than one
+.I [Operator]
+block, one for each local operator.
+.TP
+\fBName\fR (string)
+ID of the operator (may be different of the nick name).
+.TP
+\fBPassword\fR (string)
+Password of the IRC operator.
+.TP
+\fBMask\fR (string)
+Mask that is to be checked before an /OPER for this account is accepted.
+Example: nick!ident@*.example.com
 .SH [SERVER]
 Other servers are configured in
 .I [Server]
blob - 326b433af62d49b512ba3fd42986b5d7c9381a3a
blob + 92409409e76b93f51c040b8f5cd91718987b3cca
--- src/ngircd/conf.c
+++ src/ngircd/conf.c
@@ -64,7 +64,8 @@ static bool Read_Config PARAMS(( bool ngircd_starting 
 static bool Validate_Config PARAMS(( bool TestOnly, bool Rehash ));
 
 static void Handle_GLOBAL PARAMS(( int Line, char *Var, char *Arg ));
-static void Handle_FEATURES PARAMS(( int Line, char *Var, char *Arg ));
+static void Handle_LIMITS PARAMS(( int Line, char *Var, char *Arg ));
+static void Handle_OPTIONS PARAMS(( int Line, char *Var, char *Arg ));
 static void Handle_OPERATOR PARAMS(( int Line, char *Var, char *Arg ));
 static void Handle_SERVER PARAMS(( int Line, char *Var, char *Arg ));
 static void Handle_CHANNEL PARAMS(( int Line, char *Var, char *Arg ));
@@ -88,6 +89,8 @@ static void Init_Server_Struct PARAMS(( CONF_SERVER *S
 
 #ifdef SSL_SUPPORT
 
+static void Handle_SSL PARAMS(( int Line, char *Var, char *Ark ));
+
 struct SSLOptions Conf_SSLOptions;
 
 /**
@@ -108,58 +111,29 @@ ConfSSL_Init(void)
 }
 
 /**
- * Output SSL configuration variable containing a file name.
- * And make sure that the given file is readable.
+ * Make sure that a configured file is readable.
  *
- * @returns true when the file is readable.
+ * Currently, this function is only used for SSL-related options ...
+ *
+ * @param Var Configuration variable
+ * @param Filename Configured filename
  */
-static bool
-ssl_print_configvar(const char *name, const char *file)
+static void
+CheckFileReadable(const char *Var, const char *Filename)
 {
 	FILE *fp;
 
-	if (!file) {
-		printf("  %s =\n", name);
-		return true;
-	}
+	if (!Filename)
+		return;
 
-	fp = fopen(file, "r");
+	fp = fopen(Filename, "r");
 	if (fp)
 		fclose(fp);
 	else
-		fprintf(stderr, "ERROR: %s \"%s\": %s\n",
-			name, file, strerror(errno));
-
-	printf("  %s = %s\n", name, file);
-	return fp != NULL;
+		Config_Error(LOG_ERR, "Can't read \"%s\" (\"%s\"): %s",
+			     Filename, Var, strerror(errno));
 }
 
-/**
- * Output SSL-related configuration variables.
- *
- * @returns true when all SSL-related configuration variables are valid.
- */
-static bool
-ConfSSL_Puts(void)
-{
-	bool ret;
-
-	ret = ssl_print_configvar("SSLKeyFile", Conf_SSLOptions.KeyFile);
-
-	if (!ssl_print_configvar("SSLCertFile", Conf_SSLOptions.CertFile))
-		ret = false;
-
-	if (!ssl_print_configvar("SSLDHFile", Conf_SSLOptions.DHFile))
-		ret = false;
-
-	if (array_bytes(&Conf_SSLOptions.KeyFilePassword))
-		puts("  SSLKeyFilePassword = <secret>");
-
-	array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
-
-	return ret;
-}
-
 #endif
 
 
@@ -333,23 +307,19 @@ Conf_Test( void )
 	config_valid = Validate_Config(true, false);
 
 	/* Valid tty? */
-	if( isatty( fileno( stdin )) && isatty( fileno( stdout ))) {
-		puts( "OK, press enter to see a dump of your service configuration ..." );
-		getchar( );
-	} else {
-		puts( "Ok, dump of your server configuration follows:\n" );
-	}
+	if(isatty(fileno(stdin)) && isatty(fileno(stdout))) {
+		puts("OK, press enter to see a dump of your server configuration ...");
+		getchar();
+	} else
+		puts("Ok, dump of your server configuration follows:\n");
 
-	puts( "[GLOBAL]" );
+	puts("[GLOBAL]");
 	printf("  Name = %s\n", Conf_ServerName);
-	printf("  Info = %s\n", Conf_ServerInfo);
-#ifndef PAM
-	printf("  Password = %s\n", Conf_ServerPwd);
-#endif
-	printf("  WebircPassword = %s\n", Conf_WebircPwd);
 	printf("  AdminInfo1 = %s\n", Conf_ServerAdmin1);
 	printf("  AdminInfo2 = %s\n", Conf_ServerAdmin2);
 	printf("  AdminEMail = %s\n", Conf_ServerAdminMail);
+	printf("  Info = %s\n", Conf_ServerInfo);
+	printf("  Listen = %s\n", Conf_ListenAddress);
 	if (Using_MotdFile) {
 		printf("  MotdFile = %s\n", Conf_MotdFile);
 		printf("  MotdPhrase =\n");
@@ -358,60 +328,82 @@ Conf_Test( void )
 		printf("  MotdPhrase = %s\n", array_bytes(&Conf_Motd)
 		       ? (const char*) array_start(&Conf_Motd) : "");
 	}
-	printf("  ChrootDir = %s\n", Conf_Chroot);
+#ifndef PAM
+	printf("  Password = %s\n", Conf_ServerPwd);
+#endif
 	printf("  PidFile = %s\n", Conf_PidFile);
-	printf("  Listen = %s\n", Conf_ListenAddress);
-	fputs("  Ports = ", stdout);
+	printf("  Ports = ");
 	ports_puts(&Conf_ListenPorts);
-#ifdef SSL_SUPPORT
-	fputs("  SSLPorts = ", stdout);
-	ports_puts(&Conf_SSLOptions.ListenPorts);
-	if (!ConfSSL_Puts())
-		config_valid = false;
-#endif
-
-	pwd = getpwuid(Conf_UID);
-	if (pwd)
-		printf("  ServerUID = %s\n", pwd->pw_name);
-	else
-		printf("  ServerUID = %ld\n", (long)Conf_UID);
 	grp = getgrgid(Conf_GID);
 	if (grp)
 		printf("  ServerGID = %s\n", grp->gr_name);
 	else
 		printf("  ServerGID = %ld\n", (long)Conf_GID);
-#ifdef SYSLOG
-	printf("  SyslogFacility = %s\n",
-	       ngt_SyslogFacilityName(Conf_SyslogFacility));
-#endif
-	printf("  PingTimeout = %d\n", Conf_PingTimeout);
-	printf("  PongTimeout = %d\n", Conf_PongTimeout);
+	pwd = getpwuid(Conf_UID);
+	if (pwd)
+		printf("  ServerUID = %s\n", pwd->pw_name);
+	else
+		printf("  ServerUID = %ld\n", (long)Conf_UID);
+	puts("");
+
+	puts("[LIMITS]");
 	printf("  ConnectRetry = %d\n", Conf_ConnectRetry);
-	printf("  OperCanUseMode = %s\n", yesno_to_str(Conf_OperCanMode));
-	printf("  OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode));
-	printf("  AllowRemoteOper = %s\n", yesno_to_str(Conf_AllowRemoteOper));
-	printf("  PredefChannelsOnly = %s\n", yesno_to_str(Conf_PredefChannelsOnly));
-#ifdef WANT_IPV6
-	printf("  ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6));
-	printf("  ConnectIPv6 = %s\n", yesno_to_str(Conf_ConnectIPv4));
-#endif
 	printf("  MaxConnections = %ld\n", Conf_MaxConnections);
 	printf("  MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP);
 	printf("  MaxJoins = %d\n", Conf_MaxJoins > 0 ? Conf_MaxJoins : -1);
 	printf("  MaxNickLength = %u\n", Conf_MaxNickLength - 1);
-	printf("  NoticeAuth = %s\n", yesno_to_str(Conf_NoticeAuth));
+	printf("  PingTimeout = %d\n", Conf_PingTimeout);
+	printf("  PongTimeout = %d\n", Conf_PongTimeout);
+	puts("");
+
+	puts("[OPTIONS]");
+	printf("  AllowRemoteOper = %s\n", yesno_to_str(Conf_AllowRemoteOper));
+	printf("  ChrootDir = %s\n", Conf_Chroot);
 	printf("  CloakHost = %s\n", Conf_CloakHost);
 	printf("  CloakUserToNick = %s\n", yesno_to_str(Conf_CloakUserToNick));
-#ifndef STRICT_RFC
-	printf("  RequireAuthPing = %s\n", yesno_to_str(Conf_AuthPing));
+#ifdef WANT_IPV6
+	printf("  ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6));
+	printf("  ConnectIPv6 = %s\n", yesno_to_str(Conf_ConnectIPv4));
 #endif
-
-	printf("\n[FEATURES]\n");
 	printf("  DNS = %s\n", yesno_to_str(Conf_DNS));
+#ifdef IDENT
 	printf("  Ident = %s\n", yesno_to_str(Conf_Ident));
+#endif
+	printf("  NoticeAuth = %s\n", yesno_to_str(Conf_NoticeAuth));
+	printf("  OperCanUseMode = %s\n", yesno_to_str(Conf_OperCanMode));
+	printf("  OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode));
+#ifdef PAM
 	printf("  PAM = %s\n", yesno_to_str(Conf_PAM));
+#endif
+	printf("  PredefChannelsOnly = %s\n", yesno_to_str(Conf_PredefChannelsOnly));
+#ifndef STRICT_RFC
+	printf("  RequireAuthPing = %s\n", yesno_to_str(Conf_AuthPing));
+#endif
+#ifdef SYSLOG
+	printf("  SyslogFacility = %s\n",
+	       ngt_SyslogFacilityName(Conf_SyslogFacility));
+#endif
+	printf("  WebircPassword = %s\n", Conf_WebircPwd);
 	puts("");
 
+#ifdef SSL_SUPPORT
+	puts("[SSL]");
+	printf("  CertFile = %s\n", Conf_SSLOptions.CertFile
+					? Conf_SSLOptions.CertFile : "");
+	printf("  DHFile = %s\n", Conf_SSLOptions.DHFile
+					? Conf_SSLOptions.DHFile : "");
+	printf("  KeyFile = %s\n", Conf_SSLOptions.KeyFile
+					? Conf_SSLOptions.KeyFile : "");
+	if (array_bytes(&Conf_SSLOptions.KeyFilePassword))
+		puts("  KeyFilePassword = <secret>");
+	else
+		puts("  KeyFilePassword = ");
+	array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
+	printf("  Ports = ");
+	ports_puts(&Conf_SSLOptions.ListenPorts);
+	puts("");
+#endif
+
 	opers_puts();
 
 	for( i = 0; i < MAX_SERVERS; i++ ) {
@@ -641,22 +633,6 @@ GLOBAL bool
 Conf_IsService(int ConfServer, const char *Nick)
 {
 	return MatchCaseInsensitive(Conf_Server[ConfServer].svs_mask, Nick);
-} /* Conf_IsService */
-
-
-static void
-Set_Defaults_Optional(void)
-{
-#ifdef IDENTAUTH
-	Conf_Ident = true;
-#else
-	Conf_Ident = false;
-#endif
-#ifdef PAM
-	Conf_PAM = true;
-#else
-	Conf_PAM = false;
-#endif
 }
 
 /**
@@ -667,50 +643,60 @@ Set_Defaults(bool InitServers)
 {
 	int i;
 
+	/* Global */
 	strcpy(Conf_ServerName, "");
-	snprintf(Conf_ServerInfo, sizeof Conf_ServerInfo, "%s %s",
-		 PACKAGE_NAME, PACKAGE_VERSION);
-	strcpy(Conf_ServerPwd, "");
-
 	strcpy(Conf_ServerAdmin1, "");
 	strcpy(Conf_ServerAdmin2, "");
 	strcpy(Conf_ServerAdminMail, "");
-
+	snprintf(Conf_ServerInfo, sizeof Conf_ServerInfo, "%s %s",
+		 PACKAGE_NAME, PACKAGE_VERSION);
+	free(Conf_ListenAddress);
+	Conf_ListenAddress = NULL;
+	array_free(&Conf_Motd);
 	strlcpy(Conf_MotdFile, SYSCONFDIR, sizeof(Conf_MotdFile));
 	strlcat(Conf_MotdFile, MOTD_FILE, sizeof(Conf_MotdFile));
-
-	Conf_UID = Conf_GID = 0;
-	strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot));
+	strcpy(Conf_ServerPwd, "");
 	strlcpy(Conf_PidFile, PID_FILE, sizeof(Conf_PidFile));
+	Conf_UID = Conf_GID = 0;
 
-	free(Conf_ListenAddress);
-	Conf_ListenAddress = NULL;
-
-	Conf_PingTimeout = 120;
-	Conf_PongTimeout = 20;
+	/* Limits */
 	Conf_ConnectRetry = 60;
-	Conf_DNS = true;
-	Conf_NoticeAuth = false;
-
-	Conf_Oper_Count = 0;
-	Conf_Channel_Count = 0;
-
-	Conf_OperCanMode = false;
-	Conf_OperServerMode = false;
-	Conf_AllowRemoteOper = false;
-	Conf_PredefChannelsOnly = false;
-
-	Conf_ConnectIPv4 = true;
-	Conf_ConnectIPv6 = true;
-
 	Conf_MaxConnections = 0;
 	Conf_MaxConnectionsIP = 5;
 	Conf_MaxJoins = 10;
 	Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT;
+	Conf_PingTimeout = 120;
+	Conf_PongTimeout = 20;
 
+	/* Options */
+	Conf_AllowRemoteOper = false;
+#ifndef STRICT_RFC
+	Conf_AuthPing = false;
+#endif
+	strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot));
 	strcpy(Conf_CloakHost, "");
 	Conf_CloakUserToNick = false;
-
+	Conf_ConnectIPv4 = true;
+#ifdef WANT_IPV6
+	Conf_ConnectIPv6 = true;
+#else
+	Conf_ConnectIPv6 = false;
+#endif
+	Conf_DNS = true;
+#ifdef IDENTAUTH
+	Conf_Ident = true;
+#else
+	Conf_Ident = false;
+#endif
+	Conf_NoticeAuth = false;
+	Conf_OperCanMode = false;
+	Conf_OperServerMode = false;
+#ifdef PAM
+	Conf_PAM = true;
+#else
+	Conf_PAM = false;
+#endif
+	Conf_PredefChannelsOnly = false;
 #ifdef SYSLOG
 #ifdef LOG_LOCAL5
 	Conf_SyslogFacility = LOG_LOCAL5;
@@ -719,20 +705,15 @@ Set_Defaults(bool InitServers)
 #endif
 #endif
 
-#ifndef STRICT_RFC
-	Conf_AuthPing = false;
-#endif
+	/* Initialize IRC operators and channels */
+	Conf_Oper_Count = 0;
+	Conf_Channel_Count = 0;
 
-	Set_Defaults_Optional();
-
 	/* Initialize server configuration structures */
 	if (InitServers) {
 		for (i = 0; i < MAX_SERVERS;
 		     Init_Server_Struct(&Conf_Server[i++]));
 	}
-
-	/* Free MOTD; this is important when reloading the configuration */
-	array_free(&Conf_Motd);
 }
 
 /**
@@ -872,8 +853,10 @@ Read_Config( bool ngircd_starting )
 		/* Is this the beginning of a new section? */
 		if(( str[0] == '[' ) && ( str[strlen( str ) - 1] == ']' )) {
 			strlcpy( section, str, sizeof( section ));
-			if (strcasecmp( section, "[GLOBAL]" ) == 0 ||
-			    strcasecmp( section, "[FEATURES]") == 0)
+			if (strcasecmp(section, "[GLOBAL]") == 0 ||
+			    strcasecmp(section, "[LIMITS]") == 0 ||
+			    strcasecmp(section, "[OPTIONS]") == 0 ||
+			    strcasecmp(section, "[SSL]") == 0)
 				continue;
 
 			if( strcasecmp( section, "[SERVER]" ) == 0 ) {
@@ -909,7 +892,9 @@ Read_Config( bool ngircd_starting )
 				continue;
 			}
 
-			Config_Error( LOG_ERR, "%s, line %d: Unknown section \"%s\"!", NGIRCd_ConfFile, line, section );
+			Config_Error(LOG_ERR,
+				     "%s, line %d: Unknown section \"%s\"!",
+				     NGIRCd_ConfFile, line, section);
 			section[0] = 0x1;
 		}
 		if( section[0] == 0x1 ) continue;
@@ -924,12 +909,26 @@ Read_Config( bool ngircd_starting )
 		var = str; ngt_TrimStr( var );
 		arg = ptr + 1; ngt_TrimStr( arg );
 
-		if( strcasecmp( section, "[GLOBAL]" ) == 0 ) Handle_GLOBAL( line, var, arg );
-		else if( strcasecmp( section, "[FEATURES]" ) == 0 ) Handle_FEATURES( line, var, arg );
-		else if( strcasecmp( section, "[OPERATOR]" ) == 0 ) Handle_OPERATOR( line, var, arg );
-		else if( strcasecmp( section, "[SERVER]" ) == 0 ) Handle_SERVER( line, var, arg );
-		else if( strcasecmp( section, "[CHANNEL]" ) == 0 ) Handle_CHANNEL( line, var, arg );
-		else Config_Error( LOG_ERR, "%s, line %d: Variable \"%s\" outside section!", NGIRCd_ConfFile, line, var );
+		if(strcasecmp(section, "[GLOBAL]") == 0)
+			Handle_GLOBAL(line, var, arg);
+		else if(strcasecmp(section, "[LIMITS]") == 0)
+			Handle_LIMITS(line, var, arg);
+		else if(strcasecmp(section, "[OPTIONS]") == 0)
+			Handle_OPTIONS(line, var, arg);
+#ifdef SSL_SUPPORT
+		else if(strcasecmp(section, "[SSL]") == 0)
+			Handle_SSL(line, var, arg);
+#endif
+		else if(strcasecmp(section, "[OPERATOR]") == 0)
+			Handle_OPERATOR(line, var, arg);
+		else if(strcasecmp(section, "[SERVER]") == 0)
+			Handle_SERVER(line, var, arg);
+		else if(strcasecmp(section, "[CHANNEL]") == 0)
+			Handle_CHANNEL(line, var, arg);
+		else
+			Config_Error(LOG_ERR,
+				     "%s, line %d: Variable \"%s\" outside section!",
+				     NGIRCd_ConfFile, line, var);
 	}
 
 	/* Close configuration file */
@@ -963,6 +962,14 @@ Read_Config( bool ngircd_starting )
 	/* No MOTD phrase configured? (re)try motd file. */
 	if (array_bytes(&Conf_Motd) == 0)
 		Read_Motd(Conf_MotdFile);
+
+#ifdef SSL_SUPPORT
+	/* Make sure that all SSL-related files are readable */
+	CheckFileReadable("CertFile", Conf_SSLOptions.CertFile);
+	CheckFileReadable("DHFile", Conf_SSLOptions.DHFile);
+	CheckFileReadable("KeyFile", Conf_SSLOptions.KeyFile);
+#endif
+
 	return true;
 }
 
@@ -1020,13 +1027,29 @@ WarnIdent(int UNUSED Line)
 	if (Conf_Ident) {
 		/* user has enabled ident lookups explicitly, but ... */
 		Config_Error(LOG_WARNING,
-			"%s: line %d: %s=True, but ngircd was built without support",
-			NGIRCd_ConfFile, Line, "Ident");
+			"%s: line %d: \"Ident = yes\", but ngircd was built without IDENT support!",
+			NGIRCd_ConfFile, Line);
 	}
 #endif
 }
 
 /**
+ * Output a warning messages if IPv6 is configured but not compiled in.
+ */
+static void
+WarnIPv6(int UNUSED Line)
+{
+#ifndef WANT_IPV6
+	if (Conf_ConnectIPv6) {
+		/* user has enabled IPv6 explicitly, but ... */
+		Config_Error(LOG_WARNING,
+			"%s: line %d: \"ConnectIPv6 = yes\", but ngircd was built without IPv6 support!",
+			NGIRCd_ConfFile, Line);
+	}
+#endif
+}
+
+/**
  * Output a warning messages if PAM is configured but not compiled in.
  */
 static void
@@ -1035,8 +1058,8 @@ WarnPAM(int UNUSED Line)
 #ifndef PAM
 	if (Conf_PAM) {
 		Config_Error(LOG_WARNING,
-			"%s: line %d: %s=True, but ngircd was built without support",
-			NGIRCd_ConfFile, Line, "PAM");
+			"%s: line %d: \"PAM = yes\", but ngircd was built without PAM support!",
+			NGIRCd_ConfFile, Line);
 	}
 #endif
 }
@@ -1044,8 +1067,8 @@ WarnPAM(int UNUSED Line)
 /**
  * Handle legacy "NoXXX" options in [GLOBAL] section.
  *
- * TODO: This function and support for "NoXXX" should be removed starting
- * with ngIRCd release 19! (One release after marking it "deprecated").
+ * TODO: This function and support for "NoXXX" could be removed starting
+ * with ngIRCd release 19 (one release after marking it "deprecated").
  *
  * @param Var	Variable name.
  * @param Arg	Argument string.
@@ -1054,7 +1077,7 @@ WarnPAM(int UNUSED Line)
 static bool
 CheckLegacyNoOption(const char *Var, const char *Arg)
 {
-	if( strcasecmp( Var, "NoDNS" ) == 0 ) {
+	if(strcasecmp(Var, "NoDNS") == 0) {
 		Conf_DNS = !Check_ArgIsTrue( Arg );
 		return true;
 	}
@@ -1070,6 +1093,56 @@ CheckLegacyNoOption(const char *Var, const char *Arg)
 }
 
 /**
+ * Handle deprecated legacy options in [GLOBAL] section.
+ *
+ * TODO: This function and support for these options in the [Global] section
+ * could be removed starting with ngIRCd release 19 (one release after
+ * marking it "deprecated").
+ *
+ * @param Var	Variable name.
+ * @param Arg	Argument string.
+ * @returns	true if a legacy option has been processed; false otherwise.
+ */
+static const char*
+CheckLegacyGlobalOption(int Line, char *Var, char *Arg)
+{
+	if (strcasecmp(Var, "AllowRemoteOper") == 0
+	    || strcasecmp(Var, "ChrootDir") == 0
+	    || strcasecmp(Var, "ConnectIPv4") == 0
+	    || strcasecmp(Var, "ConnectIPv6") == 0
+	    || strcasecmp(Var, "OperCanUseMode") == 0
+	    || strcasecmp(Var, "OperServerMode") == 0
+	    || strcasecmp(Var, "PredefChannelsOnly") == 0
+	    || strcasecmp(Var, "SyslogFacility") == 0
+	    || strcasecmp(Var, "WebircPassword") == 0) {
+		Handle_OPTIONS(Line, Var, Arg);
+		return "[Options]";
+	}
+	if (strcasecmp(Var, "ConnectRetry") == 0
+	    || strcasecmp(Var, "MaxConnections") == 0
+	    || strcasecmp(Var, "MaxConnectionsIP") == 0
+	    || strcasecmp(Var, "MaxJoins") == 0
+	    || strcasecmp(Var, "MaxNickLength") == 0
+	    || strcasecmp(Var, "PingTimeout") == 0
+	    || strcasecmp(Var, "PongTimeout") == 0) {
+		Handle_LIMITS(Line, Var, Arg);
+		return "[Limits]";
+	}
+#ifdef SSL_SUPPORT
+	if (strcasecmp(Var, "SSLCertFile") == 0
+	    || strcasecmp(Var, "SSLDHFile") == 0
+	    || strcasecmp(Var, "SSLKeyFile") == 0
+	    || strcasecmp(Var, "SSLKeyFilePassword") == 0
+	    || strcasecmp(Var, "SSLPorts") == 0) {
+		Handle_SSL(Line, Var + 3, Arg);
+		return "[SSL]";
+	}
+#endif
+
+	return NULL;
+}
+
+/**
  * Strip "no" prefix of a string.
  *
  * TODO: This function and support for "NoXXX" should be removed starting
@@ -1113,289 +1186,304 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
 	struct passwd *pwd;
 	struct group *grp;
 	size_t len;
+	const char *section;
 
-	assert( Line > 0 );
-	assert( Var != NULL );
-	assert( Arg != NULL );
+	assert(Line > 0);
+	assert(Var != NULL);
+	assert(Arg != NULL);
 
-	if( strcasecmp( Var, "Name" ) == 0 ) {
-		/* Server name */
-		len = strlcpy( Conf_ServerName, Arg, sizeof( Conf_ServerName ));
-		if (len >= sizeof( Conf_ServerName ))
-			Config_Error_TooLong( Line, Var );
+	if (strcasecmp(Var, "Name") == 0) {
+		len = strlcpy(Conf_ServerName, Arg, sizeof(Conf_ServerName));
+		if (len >= sizeof(Conf_ServerName))
+			Config_Error_TooLong(Line, Var);
 		return;
 	}
-	if( strcasecmp( Var, "CloakHost" ) == 0 ) {
-		/* Client hostname */
-		len = strlcpy( Conf_CloakHost, Arg, sizeof( Conf_CloakHost ));
-		if (len >= sizeof( Conf_CloakHost ))
-			Config_Error_TooLong( Line, Var );
+	if (strcasecmp(Var, "AdminInfo1") == 0) {
+		len = strlcpy(Conf_ServerAdmin1, Arg, sizeof(Conf_ServerAdmin1));
+		if (len >= sizeof(Conf_ServerAdmin1))
+			Config_Error_TooLong(Line, Var);
 		return;
 	}
-	if( strcasecmp( Var, "CloakUserToNick" ) == 0 ) {
-		/* Use client nick name as user name */
-		Conf_CloakUserToNick = Check_ArgIsTrue( Arg );
-		return;
-	}
-	if( strcasecmp( Var, "Info" ) == 0 ) {
-		/* Info text of server */
-		len = strlcpy( Conf_ServerInfo, Arg, sizeof( Conf_ServerInfo ));
-		if (len >= sizeof( Conf_ServerInfo ))
-			Config_Error_TooLong ( Line, Var );
-		return;
-	}
-	if( strcasecmp( Var, "Password" ) == 0 ) {
-		/* Global server password */
-		len = strlcpy( Conf_ServerPwd, Arg, sizeof( Conf_ServerPwd ));
-		if (len >= sizeof( Conf_ServerPwd ))
-			Config_Error_TooLong( Line, Var );
-		return;
-	}
-	if (strcasecmp(Var, "WebircPassword") == 0) {
-		/* Password required for WEBIRC command */
-		len = strlcpy(Conf_WebircPwd, Arg, sizeof(Conf_WebircPwd));
-		if (len >= sizeof(Conf_WebircPwd))
+	if (strcasecmp(Var, "AdminInfo2") == 0) {
+		len = strlcpy(Conf_ServerAdmin2, Arg, sizeof(Conf_ServerAdmin2));
+		if (len >= sizeof(Conf_ServerAdmin2))
 			Config_Error_TooLong(Line, Var);
 		return;
 	}
-	if( strcasecmp( Var, "AdminInfo1" ) == 0 ) {
-		/* Administrative info #1 */
-		len = strlcpy( Conf_ServerAdmin1, Arg, sizeof( Conf_ServerAdmin1 ));
-		if (len >= sizeof( Conf_ServerAdmin1 ))
-			Config_Error_TooLong ( Line, Var );
-		return;
-	}
-	if( strcasecmp( Var, "AdminInfo2" ) == 0 ) {
-		/* Administrative info #2 */
-		len = strlcpy( Conf_ServerAdmin2, Arg, sizeof( Conf_ServerAdmin2 ));
-		if (len >= sizeof( Conf_ServerAdmin2 ))
-			Config_Error_TooLong ( Line, Var );
+	if (strcasecmp(Var, "AdminEMail") == 0) {
+		len = strlcpy(Conf_ServerAdminMail, Arg,
+			sizeof(Conf_ServerAdminMail));
+		if (len >= sizeof(Conf_ServerAdminMail))
+			Config_Error_TooLong(Line, Var);
 		return;
 	}
-	if( strcasecmp( Var, "AdminEMail" ) == 0 ) {
-		/* Administrative email contact */
-		len = strlcpy( Conf_ServerAdminMail, Arg, sizeof( Conf_ServerAdminMail ));
-		if (len >= sizeof( Conf_ServerAdminMail ))
-			Config_Error_TooLong( Line, Var );
+	if (strcasecmp(Var, "Info") == 0) {
+		len = strlcpy(Conf_ServerInfo, Arg, sizeof(Conf_ServerInfo));
+		if (len >= sizeof(Conf_ServerInfo))
+			Config_Error_TooLong(Line, Var);
 		return;
 	}
-
-	if( strcasecmp( Var, "Ports" ) == 0 ) {
-		ports_parse(&Conf_ListenPorts, Line, Arg);
+	if (strcasecmp(Var, "Listen") == 0) {
+		if (Conf_ListenAddress) {
+			Config_Error(LOG_ERR,
+				     "Multiple Listen= options, ignoring: %s",
+				     Arg);
+			return;
+		}
+		Conf_ListenAddress = strdup_warn(Arg);
+		/* If allocation fails, we're in trouble: we cannot ignore the
+		 * error -- otherwise ngircd would listen on all interfaces. */
+		if (!Conf_ListenAddress) {
+			Config_Error(LOG_ALERT,
+				     "%s exiting due to fatal errors!",
+				     PACKAGE_NAME);
+			exit(1);
+		}
 		return;
 	}
-	if( strcasecmp( Var, "MotdFile" ) == 0 ) {
-		len = strlcpy( Conf_MotdFile, Arg, sizeof( Conf_MotdFile ));
-		if (len >= sizeof( Conf_MotdFile ))
-			Config_Error_TooLong( Line, Var );
+	if (strcasecmp(Var, "MotdFile") == 0) {
+		len = strlcpy(Conf_MotdFile, Arg, sizeof(Conf_MotdFile));
+		if (len >= sizeof(Conf_MotdFile))
+			Config_Error_TooLong(Line, Var);
 		return;
 	}
-	if( strcasecmp( Var, "MotdPhrase" ) == 0 ) {
-		/* "Message of the day" phrase (instead of file) */
+	if (strcasecmp(Var, "MotdPhrase") == 0) {
 		len = strlen(Arg);
 		if (len == 0)
 			return;
 		if (len >= LINE_LEN) {
-			Config_Error_TooLong( Line, Var );
+			Config_Error_TooLong(Line, Var);
 			return;
 		}
 		if (!array_copyb(&Conf_Motd, Arg, len + 1))
-			Config_Error(LOG_WARNING, "%s, line %d: Could not append MotdPhrase: %s",
-							NGIRCd_ConfFile, Line, strerror(errno));
+			Config_Error(LOG_WARNING,
+				     "%s, line %d: Could not append MotdPhrase: %s",
+				     NGIRCd_ConfFile, Line, strerror(errno));
 		Using_MotdFile = false;
 		return;
 	}
-	if( strcasecmp( Var, "ChrootDir" ) == 0 ) {
-		/* directory for chroot() */
-		len = strlcpy( Conf_Chroot, Arg, sizeof( Conf_Chroot ));
-		if (len >= sizeof( Conf_Chroot ))
-			Config_Error_TooLong( Line, Var );
+	if(strcasecmp(Var, "Password") == 0) {
+		len = strlcpy(Conf_ServerPwd, Arg, sizeof(Conf_ServerPwd));
+		if (len >= sizeof(Conf_ServerPwd))
+			Config_Error_TooLong(Line, Var);
 		return;
 	}
-	if ( strcasecmp( Var, "PidFile" ) == 0 ) {
-		/* name of pidfile */
-		len = strlcpy( Conf_PidFile, Arg, sizeof( Conf_PidFile ));
-		if (len >= sizeof( Conf_PidFile ))
-			Config_Error_TooLong( Line, Var );
+	if (strcasecmp(Var, "PidFile") == 0) {
+		len = strlcpy(Conf_PidFile, Arg, sizeof(Conf_PidFile));
+		if (len >= sizeof(Conf_PidFile))
+			Config_Error_TooLong(Line, Var);
 		return;
 	}
-	if( strcasecmp( Var, "ServerUID" ) == 0 ) {
-		/* UID the daemon should switch to */
-		pwd = getpwnam( Arg );
-		if( pwd ) Conf_UID = pwd->pw_uid;
-		else {
-			Conf_UID = (unsigned int)atoi( Arg );
-			if (!Conf_UID && strcmp(Arg, "0"))
-				Config_Error_NaN(Line, Var);
-		}
+	if (strcasecmp(Var, "Ports") == 0) {
+		ports_parse(&Conf_ListenPorts, Line, Arg);
 		return;
 	}
-	if( strcasecmp( Var, "ServerGID" ) == 0 ) {
-		/* GID the daemon should use */
-		grp = getgrnam( Arg );
-		if( grp ) Conf_GID = grp->gr_gid;
+	if (strcasecmp(Var, "ServerGID") == 0) {
+		grp = getgrnam(Arg);
+		if (grp)
+			Conf_GID = grp->gr_gid;
 		else {
 			Conf_GID = (unsigned int)atoi(Arg);
 			if (!Conf_GID && strcmp(Arg, "0"))
-				Config_Error_NaN( Line, Var );
+				Config_Error_NaN(Line, Var);
 		}
 		return;
 	}
-	if( strcasecmp( Var, "PingTimeout" ) == 0 ) {
-		/* PING timeout */
-		Conf_PingTimeout = atoi( Arg );
-		if( Conf_PingTimeout < 5 ) {
-			Config_Error( LOG_WARNING, "%s, line %d: Value of \"PingTimeout\" too low!",
-									NGIRCd_ConfFile, Line );
-			Conf_PingTimeout = 5;
+	if (strcasecmp(Var, "ServerUID") == 0) {
+		pwd = getpwnam(Arg);
+		if (pwd)
+			Conf_UID = pwd->pw_uid;
+		else {
+			Conf_UID = (unsigned int)atoi(Arg);
+			if (!Conf_UID && strcmp(Arg, "0"))
+				Config_Error_NaN(Line, Var);
 		}
 		return;
 	}
-	if( strcasecmp( Var, "PongTimeout" ) == 0 ) {
-		/* PONG timeout */
-		Conf_PongTimeout = atoi( Arg );
-		if( Conf_PongTimeout < 5 ) {
-			Config_Error( LOG_WARNING, "%s, line %d: Value of \"PongTimeout\" too low!",
-									NGIRCd_ConfFile, Line );
-			Conf_PongTimeout = 5;
+
+	if (CheckLegacyNoOption(Var, Arg)) {
+		/* TODO: This function and support for "NoXXX" could be
+		 * be removed starting with ngIRCd release 19 (one release
+		 * after marking it "deprecated"). */
+		Config_Error(LOG_WARNING,
+			     "%s, line %d (section \"Global\"): \"No\"-Prefix is deprecated, use \"%s = %s\" in [Options] section!",
+			     NGIRCd_ConfFile, Line, NoNo(Var), InvertArg(Arg));
+		if (strcasecmp(Var, "NoIdent") == 0)
+			WarnIdent(Line);
+		else if (strcasecmp(Var, "NoPam") == 0)
+			WarnPAM(Line);
+		return;
+	}
+	if ((section = CheckLegacyGlobalOption(Line, Var, Arg))) {
+		/** TODO: This function and support for these options in the
+		 * [Global] section could be removed starting with ngIRCd
+		 * release 19 (one release after marking it "deprecated"). */
+		if (strncasecmp(Var, "SSL", 3) == 0) {
+			Config_Error(LOG_WARNING,
+				     "%s, line %d (section \"Global\"): \"%s\" is deprecated here, move it to %s and rename to \"%s\"!",
+				     NGIRCd_ConfFile, Line, Var, section,
+				     Var + 3);
+		} else {
+			Config_Error(LOG_WARNING,
+				     "%s, line %d (section \"Global\"): \"%s\" is deprecated here, move it to %s!",
+				     NGIRCd_ConfFile, Line, Var, section);
 		}
 		return;
 	}
-	if( strcasecmp( Var, "ConnectRetry" ) == 0 ) {
-		/* Seconds between connection attempts to other servers */
-		Conf_ConnectRetry = atoi( Arg );
-		if( Conf_ConnectRetry < 5 ) {
-			Config_Error( LOG_WARNING, "%s, line %d: Value of \"ConnectRetry\" too low!",
-									NGIRCd_ConfFile, Line );
+
+	Config_Error_Section(Line, Var, "Global");
+}
+
+/**
+ * Handle variable in [Limits] configuration section.
+ *
+ * @param Line	Line numer in configuration file.
+ * @param Var	Variable name.
+ * @param Arg	Variable argument.
+ */
+static void
+Handle_LIMITS(int Line, char *Var, char *Arg)
+{
+	assert(Line > 0);
+	assert(Var != NULL);
+	assert(Arg != NULL);
+
+	if (strcasecmp(Var, "ConnectRetry") == 0) {
+		Conf_ConnectRetry = atoi(Arg);
+		if (Conf_ConnectRetry < 5) {
+			Config_Error(LOG_WARNING,
+				     "%s, line %d: Value of \"ConnectRetry\" too low!",
+				     NGIRCd_ConfFile, Line);
 			Conf_ConnectRetry = 5;
 		}
 		return;
 	}
-	if( strcasecmp( Var, "PredefChannelsOnly" ) == 0 ) {
-		/* Should we only allow pre-defined-channels? (i.e. users cannot create their own channels) */
-		Conf_PredefChannelsOnly = Check_ArgIsTrue( Arg );
+	if (strcasecmp(Var, "MaxConnections") == 0) {
+		Conf_MaxConnections = atol(Arg);
+		if (!Conf_MaxConnections && strcmp(Arg, "0"))
+			Config_Error_NaN(Line, Var);
 		return;
 	}
-
-	if (CheckLegacyNoOption(Var, Arg)) {
-		Config_Error(LOG_WARNING, "%s, line %d: \"No\"-Prefix has been removed, use \"%s = %s\" in [FEATURES] section instead",
-					NGIRCd_ConfFile, Line, NoNo(Var), InvertArg(Arg));
-		if (strcasecmp(Var, "NoIdent") == 0)
-			WarnIdent(Line);
-		else if (strcasecmp(Var, "NoPam") == 0)
-			WarnPAM(Line);
+	if (strcasecmp(Var, "MaxConnectionsIP") == 0) {
+		Conf_MaxConnectionsIP = atoi(Arg);
+		if (!Conf_MaxConnectionsIP && strcmp(Arg, "0"))
+			Config_Error_NaN(Line, Var);
 		return;
 	}
-#ifdef WANT_IPV6
-	/* the default setting for all the WANT_IPV6 special options is 'true' */
-	if( strcasecmp( Var, "ConnectIPv6" ) == 0 ) {
-		/* connect to other hosts using ipv6, if they have an AAAA record? */
-		Conf_ConnectIPv6 = Check_ArgIsTrue( Arg );
+	if (strcasecmp(Var, "MaxJoins") == 0) {
+		Conf_MaxJoins = atoi(Arg);
+		if (!Conf_MaxJoins && strcmp(Arg, "0"))
+			Config_Error_NaN(Line, Var);
 		return;
 	}
-	if( strcasecmp( Var, "ConnectIPv4" ) == 0 ) {
-		/* connect to other hosts using ipv4.
-		 * again, this can be used for ipv6-only setups */
-		Conf_ConnectIPv4 = Check_ArgIsTrue( Arg );
+	if (strcasecmp(Var, "MaxNickLength") == 0) {
+		Conf_MaxNickLength = Handle_MaxNickLength(Line, Arg);
 		return;
 	}
-#endif
-	if( strcasecmp( Var, "OperCanUseMode" ) == 0 ) {
-		/* Are IRC operators allowed to use MODE in channels they aren't Op in? */
-		Conf_OperCanMode = Check_ArgIsTrue( Arg );
+	if (strcasecmp(Var, "PingTimeout") == 0) {
+		Conf_PingTimeout = atoi(Arg);
+		if (Conf_PingTimeout < 5) {
+			Config_Error(LOG_WARNING,
+				     "%s, line %d: Value of \"PingTimeout\" too low!",
+				     NGIRCd_ConfFile, Line);
+			Conf_PingTimeout = 5;
+		}
 		return;
 	}
-	if( strcasecmp( Var, "OperServerMode" ) == 0 ) {
-		/* Mask IRC operator as if coming from the server? (ircd-irc2 compat hack) */
-		Conf_OperServerMode = Check_ArgIsTrue( Arg );
+	if (strcasecmp(Var, "PongTimeout") == 0) {
+		Conf_PongTimeout = atoi(Arg);
+		if (Conf_PongTimeout < 5) {
+			Config_Error(LOG_WARNING,
+				     "%s, line %d: Value of \"PongTimeout\" too low!",
+				     NGIRCd_ConfFile, Line);
+			Conf_PongTimeout = 5;
+		}
 		return;
 	}
-	if(strcasecmp(Var, "AllowRemoteOper") == 0) {
-		/* Are remote IRC operators allowed to control this server? */
+
+	Config_Error_Section(Line, Var, "Limits");
+}
+
+/**
+ * Handle variable in [Options] configuration section.
+ *
+ * @param Line	Line numer in configuration file.
+ * @param Var	Variable name.
+ * @param Arg	Variable argument.
+ */
+static void
+Handle_OPTIONS(int Line, char *Var, char *Arg)
+{
+	size_t len;
+
+	assert(Line > 0);
+	assert(Var != NULL);
+	assert(Arg != NULL);
+
+	if (strcasecmp(Var, "AllowRemoteOper") == 0) {
 		Conf_AllowRemoteOper = Check_ArgIsTrue(Arg);
 		return;
 	}
-	if( strcasecmp( Var, "MaxConnections" ) == 0 ) {
-		/* Maximum number of connections. 0 -> "no limit". */
-		Conf_MaxConnections = atol( Arg );
-		if (!Conf_MaxConnections && strcmp(Arg, "0"))
-			Config_Error_NaN(Line, Var);
+	if (strcasecmp(Var, "ChrootDir") == 0) {
+		len = strlcpy(Conf_Chroot, Arg, sizeof(Conf_Chroot));
+		if (len >= sizeof(Conf_Chroot))
+			Config_Error_TooLong(Line, Var);
 		return;
 	}
-	if( strcasecmp( Var, "MaxConnectionsIP" ) == 0 ) {
-		/* Maximum number of simultaneous connections from one IP. 0 -> "no limit" */
-		Conf_MaxConnectionsIP = atoi( Arg );
-		if (!Conf_MaxConnectionsIP && strcmp(Arg, "0"))
-			Config_Error_NaN(Line, Var);
+	if (strcasecmp(Var, "CloakHost") == 0) {
+		len = strlcpy(Conf_CloakHost, Arg, sizeof(Conf_CloakHost));
+		if (len >= sizeof(Conf_CloakHost))
+			Config_Error_TooLong(Line, Var);
 		return;
 	}
-	if( strcasecmp( Var, "MaxJoins" ) == 0 ) {
-		/* Maximum number of channels a user can join. 0 -> "no limit". */
-		Conf_MaxJoins = atoi( Arg );
-		if (!Conf_MaxJoins && strcmp(Arg, "0"))
-			Config_Error_NaN(Line, Var);
+	if (strcasecmp(Var, "CloakUserToNick") == 0) {
+		Conf_CloakUserToNick = Check_ArgIsTrue(Arg);
 		return;
 	}
-	if( strcasecmp( Var, "MaxNickLength" ) == 0 ) {
-		/* Maximum length of a nick name; must be same on all servers
-		 * within the IRC network! */
-		Conf_MaxNickLength = Handle_MaxNickLength(Line, Arg);
+	if (strcasecmp(Var, "ConnectIPv6") == 0) {
+		Conf_ConnectIPv6 = Check_ArgIsTrue(Arg);
+		WarnIPv6(Line);
 		return;
 	}
-	if(strcasecmp(Var, "NoticeAuth") == 0) {
-		/* send NOTICE AUTH messages to clients on connect */
+	if (strcasecmp(Var, "ConnectIPv4") == 0) {
+		Conf_ConnectIPv4 = Check_ArgIsTrue(Arg);
+		return;
+	}
+	if (strcasecmp(Var, "DNS") == 0) {
+		Conf_DNS = Check_ArgIsTrue(Arg);
+		return;
+	}
+	if (strcasecmp(Var, "Ident") == 0) {
+		Conf_Ident = Check_ArgIsTrue(Arg);
+		WarnIdent(Line);
+		return;
+	}
+	if (strcasecmp(Var, "NoticeAuth") == 0) {
 		Conf_NoticeAuth = Check_ArgIsTrue(Arg);
 		return;
 	}
-
-	if( strcasecmp( Var, "Listen" ) == 0 ) {
-		/* IP-Address to bind sockets */
-		if (Conf_ListenAddress) {
-			Config_Error(LOG_ERR, "Multiple Listen= options, ignoring: %s", Arg);
-			return;
-		}
-		Conf_ListenAddress = strdup_warn(Arg);
-		/*
-		 * if allocation fails, we're in trouble:
-		 * we cannot ignore the error -- otherwise ngircd
-		 * would listen on all interfaces.
-		 */
-		if (!Conf_ListenAddress) {
-			Config_Error(LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME);
-			exit(1);
-		}
+	if (strcasecmp(Var, "OperCanUseMode") == 0) {
+		Conf_OperCanMode = Check_ArgIsTrue(Arg);
 		return;
 	}
-
-#ifdef SSL_SUPPORT
-	if( strcasecmp( Var, "SSLPorts" ) == 0 ) {
-		ports_parse(&Conf_SSLOptions.ListenPorts, Line, Arg);
+	if (strcasecmp(Var, "OperServerMode") == 0) {
+		Conf_OperServerMode = Check_ArgIsTrue(Arg);
 		return;
 	}
-
-	if( strcasecmp( Var, "SSLKeyFile" ) == 0 ) {
-		assert(Conf_SSLOptions.KeyFile == NULL );
-		Conf_SSLOptions.KeyFile = strdup_warn(Arg);
+	if (strcasecmp(Var, "PAM") == 0) {
+		Conf_PAM = Check_ArgIsTrue(Arg);
+		WarnPAM(Line);
 		return;
 	}
-	if( strcasecmp( Var, "SSLCertFile" ) == 0 ) {
-		assert(Conf_SSLOptions.CertFile == NULL );
-		Conf_SSLOptions.CertFile = strdup_warn(Arg);
+	if (strcasecmp(Var, "PredefChannelsOnly") == 0) {
+		Conf_PredefChannelsOnly = Check_ArgIsTrue(Arg);
 		return;
 	}
-
-	if( strcasecmp( Var, "SSLKeyFilePassword" ) == 0 ) {
-		assert(array_bytes(&Conf_SSLOptions.KeyFilePassword) == 0);
-		if (!array_copys(&Conf_SSLOptions.KeyFilePassword, Arg))
-			Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Could not copy %s: %s!",
-								NGIRCd_ConfFile, Line, Var, strerror(errno));
+#ifndef STRICT_RFC
+	if (strcasecmp(Var, "RequireAuthPing") == 0) {
+		Conf_AuthPing = Check_ArgIsTrue(Arg);
 		return;
 	}
-	if( strcasecmp( Var, "SSLDHFile" ) == 0 ) {
-		assert(Conf_SSLOptions.DHFile == NULL);
-		Conf_SSLOptions.DHFile = strdup_warn( Arg );
-                return;
-        }
 #endif
 #ifdef SYSLOG
 	if (strcasecmp(Var, "SyslogFacility") == 0) {
@@ -1404,52 +1492,65 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
 		return;
 	}
 #endif
-#ifndef STRICT_RFC
-	if (strcasecmp(Var, "RequireAuthPing") == 0 ) {
-		/* Require new clients to do an "autheticatin PING-PONG" */
-		Conf_AuthPing = Check_ArgIsTrue(Arg);
+	if (strcasecmp(Var, "WebircPassword") == 0) {
+		len = strlcpy(Conf_WebircPwd, Arg, sizeof(Conf_WebircPwd));
+		if (len >= sizeof(Conf_WebircPwd))
+			Config_Error_TooLong(Line, Var);
 		return;
 	}
-#endif
 
-	Config_Error_Section(Line, Var, "Global");
+	Config_Error_Section(Line, Var, "Options");
 }
 
+#ifdef SSL_SUPPORT
 
 /**
- * Handle variable in [Features] configuration section.
+ * Handle variable in [SSL] configuration section.
  *
  * @param Line	Line numer in configuration file.
  * @param Var	Variable name.
  * @param Arg	Variable argument.
  */
 static void
-Handle_FEATURES(int Line, char *Var, char *Arg)
+Handle_SSL(int Line, char *Var, char *Arg)
 {
-	assert( Line > 0 );
-	assert( Var != NULL );
-	assert( Arg != NULL );
+	assert(Line > 0);
+	assert(Var != NULL);
+	assert(Arg != NULL);
 
-	if( strcasecmp( Var, "DNS" ) == 0 ) {
-		/* do reverse dns lookups when clients connect? */
-		Conf_DNS = Check_ArgIsTrue( Arg );
+	if (strcasecmp(Var, "CertFile") == 0) {
+		assert(Conf_SSLOptions.CertFile == NULL);
+		Conf_SSLOptions.CertFile = strdup_warn(Arg);
 		return;
 	}
-	if (strcasecmp(Var, "Ident") == 0) {
-		/* do IDENT lookups when clients connect? */
-		Conf_Ident = Check_ArgIsTrue(Arg);
-		WarnIdent(Line);
+	if (strcasecmp(Var, "DHFile") == 0) {
+		assert(Conf_SSLOptions.DHFile == NULL);
+		Conf_SSLOptions.DHFile = strdup_warn(Arg);
 		return;
 	}
-	if(strcasecmp(Var, "PAM") == 0) {
-		/* use PAM library to authenticate users */
-		Conf_PAM = Check_ArgIsTrue(Arg);
-		WarnPAM(Line);
+	if (strcasecmp(Var, "KeyFile") == 0) {
+		assert(Conf_SSLOptions.KeyFile == NULL);
+		Conf_SSLOptions.KeyFile = strdup_warn(Arg);
 		return;
 	}
-
-	Config_Error_Section(Line, Var, "Options");
+	if (strcasecmp(Var, "KeyFilePassword") == 0) {
+		assert(array_bytes(&Conf_SSLOptions.KeyFilePassword) == 0);
+		if (!array_copys(&Conf_SSLOptions.KeyFilePassword, Arg))
+			Config_Error(LOG_ERR,
+				     "%s, line %d (section \"SSL\"): Could not copy %s: %s!",
+				     NGIRCd_ConfFile, Line, Var,
+				     strerror(errno));
+		return;
+	}
+	if (strcasecmp(Var, "Ports") == 0) {
+		ports_parse(&Conf_SSLOptions.ListenPorts, Line, Arg);
+		return;
+	}
+
+	Config_Error_Section(Line, Var, "SSL");
 }
+
+#endif
 
 /**
  * Handle variable in [Operator] configuration section.
@@ -1787,7 +1888,7 @@ Validate_Config(bool Configtest, bool Rehash)
 #ifdef PAM
 	if (Conf_ServerPwd[0])
 		Config_Error(LOG_ERR,
-			     "This server uses PAM, \"Password\" will be ignored!");
+			     "This server uses PAM, \"Password\" in [Global] section will be ignored!");
 #endif
 
 #ifdef DEBUG
@@ -1878,8 +1979,13 @@ va_dcl
 	vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
 	va_end( ap );
 
-	if (Use_Log) Log( Level, "%s", msg );
-	else puts( msg );
+	if (!Use_Log) {
+		if (Level <= LOG_WARNING)
+			printf(" - %s\n", msg);
+		else
+			puts(msg);
+	} else
+		Log(Level, "%s", msg);
 }
 
 #ifdef DEBUG
blob - 43851f655098d29a5ea27c5dba6e89d77762f601
blob + f65f7065c4ab1ee5337ae935c251168edddb8c5c
--- src/testsuite/ngircd-test1.conf
+++ src/testsuite/ngircd-test1.conf
@@ -7,11 +7,13 @@
 	Ports = 6789
 	MotdFile = ngircd-test1.motd
 	AdminEMail = admin@irc.server
+
+[Limits]
 	MaxConnectionsIP = 0
-	OperCanUseMode = yes
 	MaxJoins = 4
 
-[Features]
+[Options]
+	OperCanUseMode = yes
 	Ident = no
 	PAM = no
 
blob - 54c1232d3ae3854fc281c2be2796d4e16a1bafae
blob + 5d2e28f2e48c95e5dcaeb7d878b045839c163dae
--- src/testsuite/ngircd-test2.conf
+++ src/testsuite/ngircd-test2.conf
@@ -7,11 +7,13 @@
 	Ports = 6790
 	MotdFile = ngircd-test2.motd
 	AdminEMail = admin@irc.server2
+
+[Limits]
 	MaxConnectionsIP = 0
-	OperCanUseMode = yes
 	MaxJoins = 4
 
-[Features]
+[Options]
+	OperCanUseMode = yes
 	Ident = no
 	PAM = no