* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
- *
- * Configuration management (reading, parsing & validation)
*/
-
#include "portab.h"
+/**
+ * @file
+ * Configuration management (reading, parsing & validation)
+ */
+
#include "imp.h"
#include <assert.h>
#include <errno.h>
#include "conf.h"
-static bool Use_Log = true;
+static bool Use_Log = true, Using_MotdFile = true;
static CONF_SERVER New_Server;
static int New_Server_Idx;
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_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 ));
{
struct Conf_Oper *op;
size_t len;
-
+
len = array_length(&Conf_Opers, sizeof(*op));
op = array_start(&Conf_Opers);
while (len--) {
{
struct Conf_Oper *op;
size_t len;
-
+
len = array_length(&Conf_Opers, sizeof(*op));
op = array_start(&Conf_Opers);
while (len--) {
printf(" AdminInfo1 = %s\n", Conf_ServerAdmin1);
printf(" AdminInfo2 = %s\n", Conf_ServerAdmin2);
printf(" AdminEMail = %s\n", Conf_ServerAdminMail);
- printf(" MotdFile = %s\n", Conf_MotdFile);
- printf(" MotdPhrase = %.32s\n", array_bytes(&Conf_Motd) ? (const char*) array_start(&Conf_Motd) : "");
+ if (Using_MotdFile) {
+ printf(" MotdFile = %s\n", Conf_MotdFile);
+ printf(" MotdPhrase =\n");
+ } else {
+ printf(" MotdFile = \n");
+ printf(" MotdPhrase = %s\n", array_bytes(&Conf_Motd)
+ ? (const char*) array_start(&Conf_Motd) : "");
+ }
printf(" ChrootDir = %s\n", Conf_Chroot);
printf(" PidFile = %s\n", Conf_PidFile);
printf(" Listen = %s\n", Conf_ListenAddress);
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));
- printf(" NoDNS = %s\n", yesno_to_str(Conf_NoDNS));
- printf(" NoIdent = %s\n", yesno_to_str(Conf_NoIdent));
- printf(" NoPAM = %s\n", yesno_to_str(Conf_NoPAM));
- printf(" NoZeroConf = %s\n", yesno_to_str(Conf_NoZeroConf));
-
#ifdef WANT_IPV6
printf(" ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6));
printf(" ConnectIPv6 = %s\n", yesno_to_str(Conf_ConnectIPv4));
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\n", Conf_MaxNickLength - 1);
+ printf(" MaxNickLength = %u\n", Conf_MaxNickLength - 1);
+ printf(" NoticeAuth = %s\n", yesno_to_str(Conf_NoticeAuth));
+ 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));
+#endif
+
+ printf("\n[FEATURES]\n");
+ printf(" DNS = %s\n", yesno_to_str(Conf_DNS));
+ printf(" Ident = %s\n", yesno_to_str(Conf_Ident));
+ printf(" PAM = %s\n", yesno_to_str(Conf_PAM));
+ puts("");
opers_puts();
} /* 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
+}
+
+
/**
* Initialize configuration settings with their default values.
*/
Conf_PingTimeout = 120;
Conf_PongTimeout = 20;
Conf_ConnectRetry = 60;
- Conf_NoDNS = false;
- Conf_NoIdent = false;
- Conf_NoPAM = false;
- Conf_NoZeroConf = false;
+ Conf_DNS = true;
+ Conf_NoticeAuth = false;
Conf_Oper_Count = 0;
Conf_Channel_Count = 0;
Conf_MaxJoins = 10;
Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT;
+ strcpy(Conf_CloakHost, "");
+ Conf_CloakUserToNick = false;
+
#ifdef SYSLOG
#ifdef LOG_LOCAL5
Conf_SyslogFacility = LOG_LOCAL5;
#endif
#endif
+#ifndef STRICT_RFC
+ Conf_AuthPing = false;
+#endif
+
+ 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);
} /* Set_Defaults */
fp = fopen(filename, "r");
if (!fp) {
- Log(LOG_WARNING, "Can't read MOTD file \"%s\": %s",
+ Config_Error(LOG_WARNING, "Can't read MOTD file \"%s\": %s",
filename, strerror(errno));
return;
}
array_free(&Conf_Motd);
+ Using_MotdFile = true;
while (fgets(line, (int)sizeof line, fp)) {
ngt_TrimLastChr( line, '\n');
/* 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 )
+ if (strcasecmp( section, "[GLOBAL]" ) == 0 ||
+ strcasecmp( section, "[FEATURES]") == 0)
continue;
if( strcasecmp( section, "[SERVER]" ) == 0 ) {
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 );
} /* Check_ArgIsTrue */
-static unsigned int Handle_MaxNickLength(int Line, const char *Arg)
+static unsigned int
+Handle_MaxNickLength(int Line, const char *Arg)
{
unsigned new;
} /* Handle_MaxNickLength */
+static void
+WarnIdent(int UNUSED Line)
+{
+#ifndef IDENTAUTH
+ 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");
+ }
+#endif
+}
+
+static void
+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");
+ }
+#endif
+}
+
+static bool
+CheckLegacyNoOption(const char *Var, const char *Arg)
+{
+ if( strcasecmp( Var, "NoDNS" ) == 0 ) {
+ Conf_DNS = !Check_ArgIsTrue( Arg );
+ return true;
+ }
+ if (strcasecmp(Var, "NoIdent") == 0) {
+ Conf_Ident = !Check_ArgIsTrue(Arg);
+ return true;
+ }
+ if(strcasecmp(Var, "NoPAM") == 0) {
+ Conf_PAM = !Check_ArgIsTrue(Arg);
+ return true;
+ }
+ return false;
+}
+
+static const char *
+NoNo(const char *str)
+{
+ assert(strncasecmp("no", str, 2) == 0 && str[2]);
+ return str + 2;
+}
+
+static const char *
+InvertArg(const char *arg)
+{
+ return yesno_to_str(!Check_ArgIsTrue(arg));
+}
static void
Handle_GLOBAL( int Line, char *Var, char *Arg )
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 );
+ 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 ));
len = strlcpy( Conf_MotdFile, Arg, sizeof( Conf_MotdFile ));
if (len >= sizeof( Conf_MotdFile ))
Config_Error_TooLong( Line, Var );
- Read_Motd(Arg);
return;
}
if( strcasecmp( Var, "MotdPhrase" ) == 0 ) {
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));
+ Using_MotdFile = false;
return;
}
if( strcasecmp( Var, "ChrootDir" ) == 0 ) {
pwd = getpwnam( Arg );
if( pwd ) Conf_UID = pwd->pw_uid;
else {
-#ifdef HAVE_ISDIGIT
- if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var );
- else
-#endif
Conf_UID = (unsigned int)atoi( Arg );
+ if (!Conf_UID && strcmp(Arg, "0"))
+ Config_Error_NaN(Line, Var);
}
return;
}
grp = getgrnam( Arg );
if( grp ) Conf_GID = grp->gr_gid;
else {
-#ifdef HAVE_ISDIGIT
- if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var );
- else
-#endif
- Conf_GID = (unsigned int)atoi( Arg );
+ Conf_GID = (unsigned int)atoi(Arg);
+ if (!Conf_GID && strcmp(Arg, "0"))
+ Config_Error_NaN( Line, Var );
}
return;
}
Conf_PredefChannelsOnly = Check_ArgIsTrue( Arg );
return;
}
- if( strcasecmp( Var, "NoDNS" ) == 0 ) {
- /* don't do reverse dns lookups when clients connect? */
- Conf_NoDNS = Check_ArgIsTrue( Arg );
- return;
- }
- if (strcasecmp(Var, "NoIdent") == 0) {
- /* don't do IDENT lookups when clients connect? */
- Conf_NoIdent = Check_ArgIsTrue(Arg);
-#ifndef IDENTAUTH
- if (!Conf_NoIdent) {
- /* user has enabled ident lookups explicitly, but ... */
- Config_Error(LOG_WARNING,
- "%s: line %d: NoIdent=False, but ngircd was built without IDENT support",
- NGIRCd_ConfFile, Line);
- }
-#endif
- return;
- }
- if(strcasecmp(Var, "NoPAM") == 0) {
- /* don't use PAM library to authenticate users */
- Conf_NoPAM = Check_ArgIsTrue(Arg);
- return;
- }
- if(strcasecmp(Var, "NoZeroConf") == 0) {
- /* don't register services using ZeroConf */
- Conf_NoZeroConf = Check_ArgIsTrue(Arg);
+
+ 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);
return;
}
#ifdef WANT_IPV6
}
if( strcasecmp( Var, "MaxConnections" ) == 0 ) {
/* Maximum number of connections. 0 -> "no limit". */
-#ifdef HAVE_ISDIGIT
- if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var);
- else
-#endif
Conf_MaxConnections = atol( Arg );
+ if (!Conf_MaxConnections && strcmp(Arg, "0"))
+ Config_Error_NaN(Line, Var);
return;
}
if( strcasecmp( Var, "MaxConnectionsIP" ) == 0 ) {
/* Maximum number of simultaneous connections from one IP. 0 -> "no limit" */
-#ifdef HAVE_ISDIGIT
- if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var );
- else
-#endif
Conf_MaxConnectionsIP = atoi( Arg );
+ if (!Conf_MaxConnectionsIP && strcmp(Arg, "0"))
+ Config_Error_NaN(Line, Var);
return;
}
if( strcasecmp( Var, "MaxJoins" ) == 0 ) {
/* Maximum number of channels a user can join. 0 -> "no limit". */
-#ifdef HAVE_ISDIGIT
- if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var );
- else
-#endif
Conf_MaxJoins = atoi( Arg );
+ if (!Conf_MaxJoins && strcmp(Arg, "0"))
+ Config_Error_NaN(Line, Var);
return;
}
if( strcasecmp( Var, "MaxNickLength" ) == 0 ) {
Conf_MaxNickLength = Handle_MaxNickLength(Line, Arg);
return;
}
+ if(strcasecmp(Var, "NoticeAuth") == 0) {
+ /* send NOTICE AUTH messages to clients on connect */
+ Conf_NoticeAuth = Check_ArgIsTrue(Arg);
+ return;
+ }
if( strcasecmp( Var, "Listen" ) == 0 ) {
/* IP-Address to bind sockets */
Conf_SyslogFacility);
return;
}
+#endif
+#ifndef STRICT_RFC
+ if (strcasecmp(Var, "RequireAuthPing") == 0 ) {
+ /* Require new clients to do an "autheticatin PING-PONG" */
+ Conf_AuthPing = Check_ArgIsTrue(Arg);
+ return;
+ }
#endif
Config_Error(LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!",
NGIRCd_ConfFile, Line, Var);
} /* Handle_GLOBAL */
+static void
+Handle_FEATURES(int Line, char *Var, char *Arg)
+{
+ 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 );
+ return;
+ }
+ if (strcasecmp(Var, "Ident") == 0) {
+ /* do IDENT lookups when clients connect? */
+ Conf_Ident = Check_ArgIsTrue(Arg);
+ WarnIdent(Line);
+ return;
+ }
+ if(strcasecmp(Var, "PAM") == 0) {
+ /* use PAM library to authenticate users */
+ Conf_PAM = Check_ArgIsTrue(Arg);
+ WarnPAM(Line);
+ return;
+ }
+
+ Config_Error(LOG_ERR,
+ "%s, line %d (section \"Features\"): Unknown variable \"%s\"!",
+ NGIRCd_ConfFile, Line, Var);
+}
+
static void
Handle_OPERATOR( int Line, char *Var, char *Arg )
{
if( strcasecmp( Var, "Port" ) == 0 ) {
/* Port to which this server should connect */
port = atol( Arg );
- if( port > 0 && port < 0xFFFF )
+ if (port >= 0 && port < 0xFFFF)
New_Server.port = (UINT16)port;
else
- Config_Error( LOG_ERR, "%s, line %d (section \"Server\"): Illegal port number %ld!",
- NGIRCd_ConfFile, Line, port );
+ Config_Error(LOG_ERR,
+ "%s, line %d (section \"Server\"): Illegal port number %ld!",
+ NGIRCd_ConfFile, Line, port );
return;
}
#ifdef SSL_SUPPORT
#endif
if( strcasecmp( Var, "Group" ) == 0 ) {
/* Server group */
-#ifdef HAVE_ISDIGIT
- if( ! isdigit( (int)*Arg ))
- Config_Error_NaN( Line, Var );
- else
-#endif
New_Server.group = atoi( Arg );
+ if (!New_Server.group && strcmp(Arg, "0"))
+ Config_Error_NaN(Line, Var);
return;
}
if( strcasecmp( Var, "Passive" ) == 0 ) {
if( strcasecmp( Var, "MaxUsers" ) == 0 ) {
/* maximum user limit, mode l */
chan->maxusers = (unsigned long) atol(Arg);
- if (chan->maxusers == 0)
+ if (!chan->maxusers && strcmp(Arg, "0"))
Config_Error_NaN(Line, Var);
return;
}