X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fconf.c;h=5819ef17eda92869fcadecefb627face7d64a374;hp=fae2a28c453efc943e419526fd72fecbb864d789;hb=1964bda252ceb499f4a1f76f3e06d996acc2c821;hpb=4f1b5400e90f2e5107eda8e4f4f8e0b4e2beb14d diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index fae2a28c..5819ef17 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2009 Alexander Barton (alex@barton.de) + * Copyright (c)2001-2010 Alexander Barton (alex@barton.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,29 +39,30 @@ #include "array.h" #include "ngircd.h" #include "conn.h" -#include "client.h" #include "channel.h" #include "defines.h" #include "log.h" #include "match.h" -#include "resolve.h" #include "tool.h" #include "exp.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 size_t Conf_Oper_Count; static size_t Conf_Channel_Count; +static char Conf_MotdFile[FNAME_LEN]; + static void Set_Defaults PARAMS(( bool InitServers )); 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_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 )); @@ -232,7 +233,7 @@ opers_free(void) { struct Conf_Oper *op; size_t len; - + len = array_length(&Conf_Opers, sizeof(*op)); op = array_start(&Conf_Opers); while (len--) { @@ -247,7 +248,7 @@ opers_puts(void) { struct Conf_Oper *op; size_t len; - + len = array_length(&Conf_Opers, sizeof(*op)); op = array_start(&Conf_Opers); while (len--) { @@ -291,16 +292,25 @@ Conf_Test( void ) } puts( "[GLOBAL]" ); - printf( " Name = %s\n", Conf_ServerName ); - printf( " Info = %s\n", Conf_ServerInfo ); - printf( " Password = %s\n", Conf_ServerPwd ); - 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 = %s\n", Conf_MotdPhrase ); - printf( " ChrootDir = %s\n", Conf_Chroot ); - printf( " PidFile = %s\n", Conf_PidFile); + 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); + 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); fputs(" Ports = ", stdout); ports_puts(&Conf_ListenPorts); @@ -321,6 +331,10 @@ Conf_Test( void ) 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); printf(" ConnectRetry = %d\n", Conf_ConnectRetry); @@ -328,9 +342,6 @@ Conf_Test( void ) 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)); - #ifdef WANT_IPV6 printf(" ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6)); printf(" ConnectIPv6 = %s\n", yesno_to_str(Conf_ConnectIPv4)); @@ -340,6 +351,13 @@ Conf_Test( void ) printf(" MaxJoins = %d\n", Conf_MaxJoins > 0 ? Conf_MaxJoins : -1); printf(" MaxNickLength = %u\n\n", Conf_MaxNickLength - 1); + puts("[FEATURES]"); + 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)); + printf(" ZeroConf = %s\n", yesno_to_str(Conf_ZeroConf)); + puts(""); + opers_puts(); for( i = 0; i < MAX_SERVERS; i++ ) { @@ -546,6 +564,27 @@ Conf_IsService(int ConfServer, const char *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 +#ifdef ZEROCONF + Conf_ZeroConf = true; +#else + Conf_ZeroConf = false; +#endif +} + + /** * Initialize configuration settings with their default values. */ @@ -565,7 +604,6 @@ Set_Defaults(bool InitServers) strlcpy(Conf_MotdFile, SYSCONFDIR, sizeof(Conf_MotdFile)); strlcat(Conf_MotdFile, MOTD_FILE, sizeof(Conf_MotdFile)); - strlcpy(Conf_MotdPhrase, MOTD_PHRASE, sizeof(Conf_MotdPhrase)); Conf_UID = Conf_GID = 0; strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot)); @@ -577,8 +615,7 @@ Set_Defaults(bool InitServers) Conf_PingTimeout = 120; Conf_PongTimeout = 20; Conf_ConnectRetry = 60; - Conf_NoDNS = false; - Conf_NoIdent = false; + Conf_DNS = true; Conf_Oper_Count = 0; Conf_Channel_Count = 0; @@ -596,6 +633,15 @@ Set_Defaults(bool InitServers) Conf_MaxJoins = 10; Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT; +#ifdef SYSLOG +#ifdef LOG_LOCAL5 + Conf_SyslogFacility = LOG_LOCAL5; +#else + Conf_SyslogFacility = 0; +#endif +#endif + Set_Defaults_Optional(); + /* Initialize server configuration structures */ if (InitServers) { for (i = 0; i < MAX_SERVERS; @@ -614,6 +660,37 @@ no_listenports(void) return cnt == 0; } +static void +Read_Motd(const char *filename) +{ + char line[127]; + FILE *fp; + + if (*filename == '\0') + return; + + fp = fopen(filename, "r"); + if (!fp) { + Log(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'); + + /* add text including \0 */ + if (!array_catb(&Conf_Motd, line, strlen(line) + 1)) { + Log(LOG_WARNING, "Cannot add MOTD text: %s", strerror(errno)); + break; + } + } + fclose(fp); +} + static bool Read_Config( bool ngircd_starting ) { @@ -744,6 +821,7 @@ Read_Config( bool ngircd_starting ) 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 ); @@ -777,6 +855,10 @@ Read_Config( bool ngircd_starting ) Config_Error(LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME); exit(1); } + + /* No MOTD phrase configured? (re)try motd file. */ + if (array_bytes(&Conf_Motd) == 0) + Read_Motd(Conf_MotdFile); return true; } /* Read_Config */ @@ -792,7 +874,8 @@ Check_ArgIsTrue( const char *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; @@ -813,6 +896,66 @@ static unsigned int Handle_MaxNickLength(int Line, const char *Arg) } /* 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; + } + if(strcasecmp(Var, "NoZeroConf") == 0) { + Conf_ZeroConf = !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 ) { @@ -845,6 +988,13 @@ Handle_GLOBAL( int Line, char *Var, char *Arg ) 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)) + Config_Error_TooLong(Line, Var); + return; + } if( strcasecmp( Var, "AdminInfo1" ) == 0 ) { /* Administrative info #1 */ len = strlcpy( Conf_ServerAdmin1, Arg, sizeof( Conf_ServerAdmin1 )); @@ -872,17 +1022,25 @@ Handle_GLOBAL( int Line, char *Var, char *Arg ) return; } if( strcasecmp( Var, "MotdFile" ) == 0 ) { - /* "Message of the day" (MOTD) file */ 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 ) { /* "Message of the day" phrase (instead of file) */ - len = strlcpy( Conf_MotdPhrase, Arg, sizeof( Conf_MotdPhrase )); - if (len >= sizeof( Conf_MotdPhrase )) + len = strlen(Arg); + if (len == 0) + return; + if (len >= LINE_LEN) { 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)); + Using_MotdFile = false; return; } if( strcasecmp( Var, "ChrootDir" ) == 0 ) { @@ -960,22 +1118,15 @@ Handle_GLOBAL( int Line, char *Var, char *Arg ) 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 + + 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 @@ -1089,12 +1240,50 @@ Handle_GLOBAL( int Line, char *Var, char *Arg ) Conf_SSLOptions.DHFile = strdup_warn( Arg ); return; } +#endif +#ifdef SYSLOG + if (strcasecmp(Var, "SyslogFacility") == 0) { + Conf_SyslogFacility = ngt_SyslogFacilityID(Arg, + Conf_SyslogFacility); + 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; + } + if(strcasecmp(Var, "ZeroConf") == 0) { + /* register services using ZeroConf */ + Conf_ZeroConf = Check_ArgIsTrue(Arg); + return; + } +} + static void Handle_OPERATOR( int Line, char *Var, char *Arg ) { @@ -1395,6 +1584,12 @@ Validate_Config(bool Configtest, bool Rehash) "No administrative information configured but required by RFC!"); } +#ifdef PAM + if (Conf_ServerPwd[0]) + Config_Error(LOG_ERR, + "This server uses PAM, \"Password\" will be ignored!"); +#endif + #ifdef DEBUG servers = servers_once = 0; for (i = 0; i < MAX_SERVERS; i++) { @@ -1460,6 +1655,29 @@ va_dcl } /* Config_Error */ +#ifdef DEBUG + +GLOBAL void +Conf_DebugDump(void) +{ + int i; + + Log(LOG_DEBUG, "Configured servers:"); + for (i = 0; i < MAX_SERVERS; i++) { + if (! Conf_Server[i].name[0]) + continue; + Log(LOG_DEBUG, + " - %s: %s:%d, last=%ld, group=%d, flags=%d, conn=%d", + Conf_Server[i].name, Conf_Server[i].host, + Conf_Server[i].port, Conf_Server[i].lasttry, + Conf_Server[i].group, Conf_Server[i].flags, + Conf_Server[i].conn_id); + } +} /* Conf_DebugDump */ + +#endif + + static void Init_Server_Struct( CONF_SERVER *Server ) { @@ -1474,7 +1692,7 @@ Init_Server_Struct( CONF_SERVER *Server ) if( NGIRCd_Passive ) Server->flags = CONF_SFLAG_DISABLED; - Resolve_Init(&Server->res_stat); + Proc_InitStruct(&Server->res_stat); Server->conn_id = NONE; memset(&Server->bind_addr, 0, sizeof(&Server->bind_addr)); } /* Init_Server_Struct */