X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fconf.c;h=034281c06a86ac7c42bc3edb6adffcaa3fb0d0ae;hp=97634af919e609259922d82138208afb4f8043ec;hb=b68bb560e9140c0ec783ea02773aef50d11ac06d;hpb=d2f54abbedb299a8c3d32295c24397535a4bd2af diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index 97634af9..034281c0 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors. * * 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 @@ -55,12 +55,10 @@ 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 Read_Config PARAMS(( bool TestOnly, bool IsStarting )); static bool Validate_Config PARAMS(( bool TestOnly, bool Rehash )); static void Handle_GLOBAL PARAMS(( int Line, char *Var, char *Arg )); @@ -208,7 +206,7 @@ ports_parse(array *a, int Line, char *Arg) GLOBAL void Conf_Init( void ) { - Read_Config( true ); + Read_Config(false, true); Validate_Config(false, false); } @@ -220,7 +218,7 @@ Conf_Init( void ) GLOBAL bool Conf_Rehash( void ) { - if (!Read_Config(false)) + if (!Read_Config(false, false)) return false; Validate_Config(false, true); @@ -265,18 +263,18 @@ static void opers_puts(void) { struct Conf_Oper *op; - size_t len; + size_t count, i; - len = array_length(&Conf_Opers, sizeof(*op)); + count = array_length(&Conf_Opers, sizeof(*op)); op = array_start(&Conf_Opers); - while (len--) { - assert(op->name[0]); + for (i = 0; i < count; i++, op++) { + if (!op->name[0]) + continue; puts("[OPERATOR]"); printf(" Name = %s\n", op->name); printf(" Password = %s\n", op->pwd); printf(" Mask = %s\n\n", op->mask ? op->mask : ""); - op++; } } @@ -301,7 +299,7 @@ Conf_Test( void ) Use_Log = false; - if (! Read_Config(true)) + if (!Read_Config(true, true)) return 1; config_valid = Validate_Config(true, false); @@ -348,7 +346,7 @@ Conf_Test( void ) puts("[LIMITS]"); printf(" ConnectRetry = %d\n", Conf_ConnectRetry); - printf(" MaxConnections = %ld\n", Conf_MaxConnections); + printf(" MaxConnections = %d\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); @@ -360,6 +358,8 @@ Conf_Test( void ) printf(" AllowRemoteOper = %s\n", yesno_to_str(Conf_AllowRemoteOper)); printf(" ChrootDir = %s\n", Conf_Chroot); printf(" CloakHost = %s\n", Conf_CloakHost); + printf(" CloakHostModeX = %s\n", Conf_CloakHostModeX); + printf(" CloakHostSalt = %s\n", Conf_CloakHostSalt); printf(" CloakUserToNick = %s\n", yesno_to_str(Conf_CloakUserToNick)); #ifdef WANT_IPV6 printf(" ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6)); @@ -375,6 +375,7 @@ Conf_Test( void ) printf(" OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode)); #ifdef PAM printf(" PAM = %s\n", yesno_to_str(Conf_PAM)); + printf(" PAMIsOptional = %s\n", yesno_to_str(Conf_PAMIsOptional)); #endif printf(" PredefChannelsOnly = %s\n", yesno_to_str(Conf_PredefChannelsOnly)); #ifndef STRICT_RFC @@ -493,6 +494,14 @@ Conf_SetServer( int ConfServer, CONN_ID Idx ) assert( ConfServer > NONE ); assert( Idx > NONE ); + if (Conf_Server[ConfServer].conn_id > NONE && + Conf_Server[ConfServer].conn_id != Idx) { + Log(LOG_ALERT, + "Trying to update connection index for already registered server \"%s\": %d/%d - ignored.", + Conf_Server[ConfServer].name, + Conf_Server[ConfServer].conn_id, Idx); + return; + } Conf_Server[ConfServer].conn_id = Idx; } @@ -627,14 +636,41 @@ Conf_AddServer(const char *Name, UINT16 Port, const char *Host, } /** - * Check if the given nick name is an service. + * Check if the given nick name is reserved for services on a particular server. * + * @param ConfServer The server index to check. + * @param Nick The nick name to check. * @returns true if the given nick name belongs to an "IRC service". */ GLOBAL bool -Conf_IsService(int ConfServer, const char *Nick) +Conf_NickIsService(int ConfServer, const char *Nick) { - return MatchCaseInsensitive(Conf_Server[ConfServer].svs_mask, Nick); + assert (ConfServer >= 0); + assert (ConfServer < MAX_SERVERS); + + return MatchCaseInsensitiveList(Conf_Server[ConfServer].svs_mask, + Nick, ","); +} + +/** + * Check if the given nick name is blocked for "normal client" use. + * + * @param ConfServer The server index or NONE to check all configured servers. + * @param Nick The nick name to check. + * @returns true if the given nick name belongs to an "IRC service". + */ +GLOBAL bool +Conf_NickIsBlocked(const char *Nick) +{ + int i; + + for(i = 0; i < MAX_SERVERS; i++) { + if (!Conf_Server[i].name[0]) + continue; + if (Conf_NickIsService(i, Nick)) + return true; + } + return false; } /** @@ -644,6 +680,7 @@ static void Set_Defaults(bool InitServers) { int i; + char random[RANDOM_SALT_LEN + 1]; /* Global */ strcpy(Conf_ServerName, ""); @@ -677,6 +714,8 @@ Set_Defaults(bool InitServers) #endif strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot)); strcpy(Conf_CloakHost, ""); + strcpy(Conf_CloakHostModeX, ""); + strcpy(Conf_CloakHostSalt, ngt_RandomStr(random, RANDOM_SALT_LEN)); Conf_CloakUserToNick = false; Conf_ConnectIPv4 = true; #ifdef WANT_IPV6 @@ -699,6 +738,7 @@ Set_Defaults(bool InitServers) #else Conf_PAM = false; #endif + Conf_PAMIsOptional = false; Conf_PredefChannelsOnly = false; #ifdef SYSLOG Conf_ScrubCTCP = false; @@ -709,10 +749,6 @@ Set_Defaults(bool InitServers) #endif #endif - /* Initialize IRC operators and channels */ - Conf_Oper_Count = 0; - Conf_Channel_Count = 0; - /* Initialize server configuration structures */ if (InitServers) { for (i = 0; i < MAX_SERVERS; @@ -782,11 +818,12 @@ Read_Motd(const char *filename) * successfully; false otherwise. */ static bool -Read_Config( bool ngircd_starting ) +Read_Config(bool TestOnly, bool IsStarting) { char section[LINE_LEN], str[LINE_LEN], *var, *arg, *ptr; const UINT16 defaultport = 6667; int line, i, n; + size_t count; FILE *fd; /* Open configuration file */ @@ -795,16 +832,19 @@ Read_Config( bool ngircd_starting ) /* No configuration file found! */ Config_Error( LOG_ALERT, "Can't read configuration \"%s\": %s", NGIRCd_ConfFile, strerror( errno )); - if (!ngircd_starting) + if (!IsStarting) return false; Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME ); exit( 1 ); } opers_free(); - Set_Defaults( ngircd_starting ); + Set_Defaults(IsStarting); - Config_Error( LOG_INFO, "Reading configuration from \"%s\" ...", NGIRCd_ConfFile ); + if (TestOnly) + Config_Error(LOG_INFO, + "Reading configuration from \"%s\" ...", + NGIRCd_ConfFile ); /* Clean up server configuration structure: mark all already * configured servers as "once" so that they are deleted @@ -857,10 +897,13 @@ 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, "[LIMITS]") == 0 || - strcasecmp(section, "[OPTIONS]") == 0 || - strcasecmp(section, "[SSL]") == 0) + if (strcasecmp(section, "[GLOBAL]") == 0 + || strcasecmp(section, "[LIMITS]") == 0 + || strcasecmp(section, "[OPTIONS]") == 0 +#ifdef SSL_SUPPORT + || strcasecmp(section, "[SSL]") == 0 +#endif + ) continue; if( strcasecmp( section, "[SERVER]" ) == 0 ) { @@ -887,12 +930,30 @@ Read_Config( bool ngircd_starting ) else New_Server_Idx = i; continue; } + if (strcasecmp(section, "[CHANNEL]") == 0) { - Conf_Channel_Count++; + count = array_length(&Conf_Channels, + sizeof(struct Conf_Channel)); + if (!array_alloc(&Conf_Channels, + sizeof(struct Conf_Channel), + count)) { + Config_Error(LOG_ERR, + "Could not allocate memory for new operator (line %d)", + line); + } continue; } + if (strcasecmp(section, "[OPERATOR]") == 0) { - Conf_Oper_Count++; + count = array_length(&Conf_Opers, + sizeof(struct Conf_Oper)); + if (!array_alloc(&Conf_Opers, + sizeof(struct Conf_Oper), + count)) { + Config_Error(LOG_ERR, + "Could not allocate memory for new channel (line &d)", + line); + } continue; } @@ -1293,7 +1354,9 @@ Handle_GLOBAL( int Line, char *Var, char *Arg ) else { Conf_GID = (unsigned int)atoi(Arg); if (!Conf_GID && strcmp(Arg, "0")) - Config_Error_NaN(Line, Var); + Config_Error(LOG_WARNING, + "%s, line %d: Value of \"%s\" is not a valid group name or ID!", + NGIRCd_ConfFile, Line, Var); } return; } @@ -1304,7 +1367,9 @@ Handle_GLOBAL( int Line, char *Var, char *Arg ) else { Conf_UID = (unsigned int)atoi(Arg); if (!Conf_UID && strcmp(Arg, "0")) - Config_Error_NaN(Line, Var); + Config_Error(LOG_WARNING, + "%s, line %d: Value of \"%s\" is not a valid user name or ID!", + NGIRCd_ConfFile, Line, Var); } return; } @@ -1367,7 +1432,7 @@ Handle_LIMITS(int Line, char *Var, char *Arg) return; } if (strcasecmp(Var, "MaxConnections") == 0) { - Conf_MaxConnections = atol(Arg); + Conf_MaxConnections = atoi(Arg); if (!Conf_MaxConnections && strcmp(Arg, "0")) Config_Error_NaN(Line, Var); return; @@ -1444,6 +1509,18 @@ Handle_OPTIONS(int Line, char *Var, char *Arg) Config_Error_TooLong(Line, Var); return; } + if (strcasecmp(Var, "CloakHostModeX") == 0) { + len = strlcpy(Conf_CloakHostModeX, Arg, sizeof(Conf_CloakHostModeX)); + if (len >= sizeof(Conf_CloakHostModeX)) + Config_Error_TooLong(Line, Var); + return; + } + if (strcasecmp(Var, "CloakHostSalt") == 0) { + len = strlcpy(Conf_CloakHostSalt, Arg, sizeof(Conf_CloakHostSalt)); + if (len >= sizeof(Conf_CloakHostSalt)) + Config_Error_TooLong(Line, Var); + return; + } if (strcasecmp(Var, "CloakUserToNick") == 0) { Conf_CloakUserToNick = Check_ArgIsTrue(Arg); return; @@ -1487,6 +1564,10 @@ Handle_OPTIONS(int Line, char *Var, char *Arg) WarnPAM(Line); return; } + if (strcasecmp(Var, "PAMIsOptional") == 0 ) { + Conf_PAMIsOptional = Check_ArgIsTrue(Arg); + return; + } if (strcasecmp(Var, "PredefChannelsOnly") == 0) { Conf_PredefChannelsOnly = Check_ArgIsTrue(Arg); return; @@ -1584,13 +1665,11 @@ Handle_OPERATOR( int Line, char *Var, char *Arg ) assert( Line > 0 ); assert( Var != NULL ); assert( Arg != NULL ); - assert( Conf_Oper_Count > 0 ); - op = array_alloc(&Conf_Opers, sizeof(*op), Conf_Oper_Count - 1); - if (!op) { - Config_Error(LOG_ERR, "Could not allocate memory for operator (%d:%s = %s)", Line, Var, Arg); + op = array_get(&Conf_Opers, sizeof(*op), + array_length(&Conf_Opers, sizeof(*op)) - 1); + if (!op) return; - } if (strcasecmp(Var, "Name") == 0) { /* Name of IRC operator */ @@ -1756,21 +1835,17 @@ static void Handle_CHANNEL(int Line, char *Var, char *Arg) { size_t len; - size_t chancount; struct Conf_Channel *chan; assert( Line > 0 ); assert( Var != NULL ); assert( Arg != NULL ); - assert(Conf_Channel_Count > 0); - - chancount = Conf_Channel_Count - 1; - chan = array_alloc(&Conf_Channels, sizeof(*chan), chancount); - if (!chan) { - Config_Error(LOG_ERR, "Could not allocate memory for predefined channel (%d:%s = %s)", Line, Var, Arg); + chan = array_get(&Conf_Channels, sizeof(*chan), + array_length(&Conf_Channels, sizeof(*chan)) - 1); + if (!chan) return; - } + if (strcasecmp(Var, "Name") == 0) { if (!Handle_Channelname(chan, Arg)) Config_Error_TooLong(Line, Var); @@ -1917,8 +1992,10 @@ Validate_Config(bool Configtest, bool Rehash) } } Log(LOG_DEBUG, - "Configuration: Operators=%d, Servers=%d[%d], Channels=%d", - Conf_Oper_Count, servers, servers_once, Conf_Channel_Count); + "Configuration: Operators=%ld, Servers=%d[%d], Channels=%ld", + array_length(&Conf_Opers, sizeof(struct Conf_Oper)), + servers, servers_once, + array_length(&Conf_Channels, sizeof(struct Conf_Channel))); #endif return config_valid; @@ -2048,7 +2125,7 @@ Init_Server_Struct( CONF_SERVER *Server ) Proc_InitStruct(&Server->res_stat); Server->conn_id = NONE; - memset(&Server->bind_addr, 0, sizeof(&Server->bind_addr)); + memset(&Server->bind_addr, 0, sizeof(Server->bind_addr)); } /* -eof- */