mirror of
https://github.com/rsyslog/rsyslog.git
synced 2025-12-16 11:00:41 +01:00
This change allows to include extra CA files so that no "unable to get issuer certificates" issue is obtained when using chained cert files. Proposed new parameter name is "NetstreamDriverCAExtraFiles" fixes #4851 Signed-off-by: Sergio Arroutbi <sarroutb@redhat.com>
1466 lines
52 KiB
C
1466 lines
52 KiB
C
/* glbl.c - this module holds global defintions and data items.
|
|
* These are shared among the runtime library. Their use should be
|
|
* limited to cases where it is actually needed. The main intension for
|
|
* implementing them was support for the transistion from v2 to v4
|
|
* (with fully modular design), but it turned out that there may also
|
|
* be some other good use cases besides backwards-compatibility.
|
|
*
|
|
* Module begun 2008-04-16 by Rainer Gerhards
|
|
*
|
|
* Copyright 2008-2021 Rainer Gerhards and Adiscon GmbH.
|
|
*
|
|
* This file is part of the rsyslog runtime library.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
* -or-
|
|
* see COPYING.ASL20 in the source distribution
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include <stdlib.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/wait.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <pthread.h>
|
|
#include <ctype.h>
|
|
#include <assert.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include "rsyslog.h"
|
|
#include "obj.h"
|
|
#include "unicode-helper.h"
|
|
#include "cfsysline.h"
|
|
#include "glbl.h"
|
|
#include "prop.h"
|
|
#include "atomic.h"
|
|
#include "errmsg.h"
|
|
#include "action.h"
|
|
#include "parserif.h"
|
|
#include "rainerscript.h"
|
|
#include "srUtils.h"
|
|
#include "operatingstate.h"
|
|
#include "net.h"
|
|
#include "rsconf.h"
|
|
#include "queue.h"
|
|
#include "dnscache.h"
|
|
#include "parser.h"
|
|
#include "timezones.h"
|
|
|
|
/* some defaults */
|
|
#ifndef DFLT_NETSTRM_DRVR
|
|
# define DFLT_NETSTRM_DRVR ((uchar*)"ptcp")
|
|
#endif
|
|
|
|
/* static data */
|
|
DEFobjStaticHelpers
|
|
DEFobjCurrIf(prop)
|
|
DEFobjCurrIf(net)
|
|
|
|
/* static data
|
|
* For this object, these variables are obviously what makes the "meat" of the
|
|
* class...
|
|
*/
|
|
|
|
static struct cnfobj *mainqCnfObj = NULL;/* main queue object, to be used later in startup sequence */
|
|
static int bPreserveFQDN = 0; /* should FQDNs always be preserved? */
|
|
static prop_t *propLocalIPIF = NULL;/* IP address to report for the local host (default is 127.0.0.1) */
|
|
static int propLocalIPIF_set = 0; /* is propLocalIPIF already set? */
|
|
static prop_t *propLocalHostName = NULL;/* our hostname as FQDN - read-only after startup */
|
|
static prop_t *propLocalHostNameToDelete = NULL;/* see GenerateLocalHostName function hdr comment! */
|
|
static uchar *LocalHostName = NULL;/* our hostname - read-only after startup, except HUP */
|
|
static uchar *LocalHostNameOverride = NULL;/* user-overridden hostname - read-only after startup */
|
|
static uchar *LocalFQDNName = NULL;/* our hostname as FQDN - read-only after startup, except HUP */
|
|
static uchar *LocalDomain = NULL;/* our local domain name - read-only after startup, except HUP */
|
|
static int iMaxLine = 8096;
|
|
int bTerminateInputs = 0; /* global switch that inputs shall terminate ASAP (1=> terminate) */
|
|
int glblUnloadModules = 1;
|
|
char** glblDbgFiles = NULL;
|
|
size_t glblDbgFilesNum = 0;
|
|
int glblDbgWhitelist = 1;
|
|
int glblPermitCtlC = 0;
|
|
|
|
pid_t glbl_ourpid;
|
|
#ifndef HAVE_ATOMIC_BUILTINS
|
|
DEF_ATOMIC_HELPER_MUT(mutTerminateInputs);
|
|
#endif
|
|
#ifdef USE_UNLIMITED_SELECT
|
|
static int iFdSetSize = howmany(FD_SETSIZE, __NFDBITS) * sizeof (fd_mask); /* size of select() bitmask in bytes */
|
|
#endif
|
|
static uchar *SourceIPofLocalClient = NULL; /* [ar] Source IP for local client to be used on multihomed host */
|
|
|
|
/* tables for interfacing with the v6 config system */
|
|
static struct cnfparamdescr cnfparamdescr[] = {
|
|
{ "workdirectory", eCmdHdlrString, 0 },
|
|
{ "operatingstatefile", eCmdHdlrString, 0 },
|
|
{ "dropmsgswithmaliciousdnsptrrecords", eCmdHdlrBinary, 0 },
|
|
{ "localhostname", eCmdHdlrGetWord, 0 },
|
|
{ "preservefqdn", eCmdHdlrBinary, 0 },
|
|
{ "debug.onshutdown", eCmdHdlrBinary, 0 },
|
|
{ "debug.logfile", eCmdHdlrString, 0 },
|
|
{ "debug.gnutls", eCmdHdlrNonNegInt, 0 },
|
|
{ "debug.unloadmodules", eCmdHdlrBinary, 0 },
|
|
{ "defaultnetstreamdrivercafile", eCmdHdlrString, 0 },
|
|
{ "defaultnetstreamdriverkeyfile", eCmdHdlrString, 0 },
|
|
{ "defaultnetstreamdrivercertfile", eCmdHdlrString, 0 },
|
|
{ "defaultnetstreamdriver", eCmdHdlrString, 0 },
|
|
{ "netstreamdrivercaextrafiles", eCmdHdlrString, 0 },
|
|
{ "maxmessagesize", eCmdHdlrSize, 0 },
|
|
{ "oversizemsg.errorfile", eCmdHdlrGetWord, 0 },
|
|
{ "oversizemsg.report", eCmdHdlrBinary, 0 },
|
|
{ "oversizemsg.input.mode", eCmdHdlrGetWord, 0 },
|
|
{ "reportchildprocessexits", eCmdHdlrGetWord, 0 },
|
|
{ "action.reportsuspension", eCmdHdlrBinary, 0 },
|
|
{ "action.reportsuspensioncontinuation", eCmdHdlrBinary, 0 },
|
|
{ "parser.controlcharacterescapeprefix", eCmdHdlrGetChar, 0 },
|
|
{ "parser.droptrailinglfonreception", eCmdHdlrBinary, 0 },
|
|
{ "parser.escapecontrolcharactersonreceive", eCmdHdlrBinary, 0 },
|
|
{ "parser.spacelfonreceive", eCmdHdlrBinary, 0 },
|
|
{ "parser.escape8bitcharactersonreceive", eCmdHdlrBinary, 0},
|
|
{ "parser.escapecontrolcharactertab", eCmdHdlrBinary, 0},
|
|
{ "parser.escapecontrolcharacterscstyle", eCmdHdlrBinary, 0 },
|
|
{ "parser.parsehostnameandtag", eCmdHdlrBinary, 0 },
|
|
{ "parser.permitslashinprogramname", eCmdHdlrBinary, 0 },
|
|
{ "stdlog.channelspec", eCmdHdlrString, 0 },
|
|
{ "janitor.interval", eCmdHdlrPositiveInt, 0 },
|
|
{ "senders.reportnew", eCmdHdlrBinary, 0 },
|
|
{ "senders.reportgoneaway", eCmdHdlrBinary, 0 },
|
|
{ "senders.timeoutafter", eCmdHdlrPositiveInt, 0 },
|
|
{ "senders.keeptrack", eCmdHdlrBinary, 0 },
|
|
{ "inputs.timeout.shutdown", eCmdHdlrPositiveInt, 0 },
|
|
{ "privdrop.group.keepsupplemental", eCmdHdlrBinary, 0 },
|
|
{ "privdrop.group.id", eCmdHdlrPositiveInt, 0 },
|
|
{ "privdrop.group.name", eCmdHdlrGID, 0 },
|
|
{ "privdrop.user.id", eCmdHdlrPositiveInt, 0 },
|
|
{ "privdrop.user.name", eCmdHdlrUID, 0 },
|
|
{ "net.ipprotocol", eCmdHdlrGetWord, 0 },
|
|
{ "net.acladdhostnameonfail", eCmdHdlrBinary, 0 },
|
|
{ "net.aclresolvehostname", eCmdHdlrBinary, 0 },
|
|
{ "net.enabledns", eCmdHdlrBinary, 0 },
|
|
{ "net.permitACLwarning", eCmdHdlrBinary, 0 },
|
|
{ "abortonuncleanconfig", eCmdHdlrBinary, 0 },
|
|
{ "variables.casesensitive", eCmdHdlrBinary, 0 },
|
|
{ "environment", eCmdHdlrArray, 0 },
|
|
{ "processinternalmessages", eCmdHdlrBinary, 0 },
|
|
{ "umask", eCmdHdlrFileCreateMode, 0 },
|
|
{ "security.abortonidresolutionfail", eCmdHdlrBinary, 0 },
|
|
{ "internal.developeronly.options", eCmdHdlrInt, 0 },
|
|
{ "internalmsg.ratelimit.interval", eCmdHdlrPositiveInt, 0 },
|
|
{ "internalmsg.ratelimit.burst", eCmdHdlrPositiveInt, 0 },
|
|
{ "internalmsg.severity", eCmdHdlrSeverity, 0 },
|
|
{ "errormessagestostderr.maxnumber", eCmdHdlrPositiveInt, 0 },
|
|
{ "shutdown.enable.ctlc", eCmdHdlrBinary, 0 },
|
|
{ "default.action.queue.timeoutshutdown", eCmdHdlrInt, 0 },
|
|
{ "default.action.queue.timeoutactioncompletion", eCmdHdlrInt, 0 },
|
|
{ "default.action.queue.timeoutenqueue", eCmdHdlrInt, 0 },
|
|
{ "default.action.queue.timeoutworkerthreadshutdown", eCmdHdlrInt, 0 },
|
|
{ "default.ruleset.queue.timeoutshutdown", eCmdHdlrInt, 0 },
|
|
{ "default.ruleset.queue.timeoutactioncompletion", eCmdHdlrInt, 0 },
|
|
{ "default.ruleset.queue.timeoutenqueue", eCmdHdlrInt, 0 },
|
|
{ "default.ruleset.queue.timeoutworkerthreadshutdown", eCmdHdlrInt, 0 },
|
|
{ "reverselookup.cache.ttl.default", eCmdHdlrNonNegInt, 0 },
|
|
{ "reverselookup.cache.ttl.enable", eCmdHdlrBinary, 0 },
|
|
{ "parser.supportcompressionextension", eCmdHdlrBinary, 0 },
|
|
{ "shutdown.queue.doublesize", eCmdHdlrBinary, 0 },
|
|
{ "debug.files", eCmdHdlrArray, 0 },
|
|
{ "debug.whitelist", eCmdHdlrBinary, 0 }
|
|
};
|
|
static struct cnfparamblk paramblk =
|
|
{ CNFPARAMBLK_VERSION,
|
|
sizeof(cnfparamdescr)/sizeof(struct cnfparamdescr),
|
|
cnfparamdescr
|
|
};
|
|
|
|
static struct cnfparamvals *cnfparamvals = NULL;
|
|
/* we need to support multiple calls into our param block, so we need
|
|
* to persist the current settings. Note that this must be re-set
|
|
* each time a new config load begins (TODO: create interface?)
|
|
*/
|
|
|
|
int
|
|
glblGetMaxLine(rsconf_t *cnf)
|
|
{
|
|
/* glblGetMaxLine might be invoked before our configuration exists */
|
|
return((cnf != NULL) ? cnf->globals.iMaxLine : iMaxLine);
|
|
}
|
|
|
|
|
|
int
|
|
GetGnuTLSLoglevel(rsconf_t *cnf)
|
|
{
|
|
return(cnf->globals.iGnuTLSLoglevel);
|
|
}
|
|
|
|
/* define a macro for the simple properties' set and get functions
|
|
* (which are always the same). This is only suitable for pretty
|
|
* simple cases which require neither checks nor memory allocation.
|
|
*/
|
|
#define SIMP_PROP(nameFunc, nameVar, dataType) \
|
|
SIMP_PROP_GET(nameFunc, nameVar, dataType) \
|
|
SIMP_PROP_SET(nameFunc, nameVar, dataType)
|
|
#define SIMP_PROP_SET(nameFunc, nameVar, dataType) \
|
|
static rsRetVal Set##nameFunc(dataType newVal) \
|
|
{ \
|
|
nameVar = newVal; \
|
|
return RS_RET_OK; \
|
|
}
|
|
#define SIMP_PROP_GET(nameFunc, nameVar, dataType) \
|
|
static dataType Get##nameFunc(void) \
|
|
{ \
|
|
return(nameVar); \
|
|
}
|
|
|
|
SIMP_PROP(PreserveFQDN, bPreserveFQDN, int)
|
|
SIMP_PROP(mainqCnfObj, mainqCnfObj, struct cnfobj *)
|
|
#ifdef USE_UNLIMITED_SELECT
|
|
SIMP_PROP(FdSetSize, iFdSetSize, int)
|
|
#endif
|
|
|
|
#undef SIMP_PROP
|
|
#undef SIMP_PROP_SET
|
|
#undef SIMP_PROP_GET
|
|
|
|
/* This is based on the previous SIMP_PROP but as a getter it uses
|
|
* additional parameter specifying the configuration it belongs to.
|
|
* The setter uses loadConf
|
|
*/
|
|
#define SIMP_PROP(nameFunc, nameVar, dataType) \
|
|
SIMP_PROP_GET(nameFunc, nameVar, dataType) \
|
|
SIMP_PROP_SET(nameFunc, nameVar, dataType)
|
|
#define SIMP_PROP_SET(nameFunc, nameVar, dataType) \
|
|
static rsRetVal Set##nameFunc(dataType newVal) \
|
|
{ \
|
|
loadConf->globals.nameVar = newVal; \
|
|
return RS_RET_OK; \
|
|
}
|
|
#define SIMP_PROP_GET(nameFunc, nameVar, dataType) \
|
|
static dataType Get##nameFunc(rsconf_t *cnf) \
|
|
{ \
|
|
return(cnf->globals.nameVar); \
|
|
}
|
|
|
|
SIMP_PROP(DropMalPTRMsgs, bDropMalPTRMsgs, int)
|
|
SIMP_PROP(DisableDNS, bDisableDNS, int)
|
|
SIMP_PROP(ParserEscapeControlCharactersCStyle, parser.bParserEscapeCCCStyle, int)
|
|
SIMP_PROP(ParseHOSTNAMEandTAG, parser.bParseHOSTNAMEandTAG, int)
|
|
SIMP_PROP(OptionDisallowWarning, optionDisallowWarning, int)
|
|
/* We omit setter on purpose, because we want to customize it */
|
|
SIMP_PROP_GET(DfltNetstrmDrvrCAF, pszDfltNetstrmDrvrCAF, uchar*)
|
|
SIMP_PROP_GET(DfltNetstrmDrvrCertFile, pszDfltNetstrmDrvrCertFile, uchar*)
|
|
SIMP_PROP_GET(DfltNetstrmDrvrKeyFile, pszDfltNetstrmDrvrKeyFile, uchar*)
|
|
SIMP_PROP_GET(NetstrmDrvrCAExtraFiles, pszNetstrmDrvrCAExtraFiles, uchar*)
|
|
SIMP_PROP_GET(ParserControlCharacterEscapePrefix, parser.cCCEscapeChar, uchar)
|
|
SIMP_PROP_GET(ParserDropTrailingLFOnReception, parser.bDropTrailingLF, int)
|
|
SIMP_PROP_GET(ParserEscapeControlCharactersOnReceive, parser.bEscapeCCOnRcv, int)
|
|
SIMP_PROP_GET(ParserSpaceLFOnReceive, parser.bSpaceLFOnRcv, int)
|
|
SIMP_PROP_GET(ParserEscape8BitCharactersOnReceive, parser.bEscape8BitChars, int)
|
|
SIMP_PROP_GET(ParserEscapeControlCharacterTab, parser.bEscapeTab, int)
|
|
|
|
#undef SIMP_PROP
|
|
#undef SIMP_PROP_SET
|
|
#undef SIMP_PROP_GET
|
|
|
|
/* return global input termination status
|
|
* rgerhards, 2009-07-20
|
|
*/
|
|
static int GetGlobalInputTermState(void)
|
|
{
|
|
return ATOMIC_FETCH_32BIT(&bTerminateInputs, &mutTerminateInputs);
|
|
}
|
|
|
|
|
|
/* set global termination state to "terminate". Note that this is a
|
|
* "once in a lifetime" action which can not be undone. -- gerhards, 2009-07-20
|
|
*/
|
|
static void SetGlobalInputTermination(void)
|
|
{
|
|
ATOMIC_STORE_1_TO_INT(&bTerminateInputs, &mutTerminateInputs);
|
|
}
|
|
|
|
|
|
/* set the local host IP address to a specific string. Helper to
|
|
* small set of functions. No checks done, caller must ensure it is
|
|
* ok to call. Most importantly, the IP address must not already have
|
|
* been set. -- rgerhards, 2012-03-21
|
|
*/
|
|
static rsRetVal
|
|
storeLocalHostIPIF(uchar *myIP)
|
|
{
|
|
DEFiRet;
|
|
if(propLocalIPIF != NULL) {
|
|
CHKiRet(prop.Destruct(&propLocalIPIF));
|
|
}
|
|
CHKiRet(prop.Construct(&propLocalIPIF));
|
|
CHKiRet(prop.SetString(propLocalIPIF, myIP, ustrlen(myIP)));
|
|
CHKiRet(prop.ConstructFinalize(propLocalIPIF));
|
|
DBGPRINTF("rsyslog/glbl: using '%s' as localhost IP\n", myIP);
|
|
finalize_it:
|
|
RETiRet;
|
|
}
|
|
|
|
|
|
/* This function is used to set the IP address that is to be
|
|
* reported for the local host. Note that in order to ease things
|
|
* for the v6 config interface, we do not allow this to be set more
|
|
* than once.
|
|
* rgerhards, 2012-03-21
|
|
*/
|
|
static rsRetVal
|
|
setLocalHostIPIF(void __attribute__((unused)) *pVal, uchar *pNewVal)
|
|
{
|
|
uchar myIP[128];
|
|
rsRetVal localRet;
|
|
DEFiRet;
|
|
|
|
CHKiRet(objUse(net, CORE_COMPONENT));
|
|
|
|
if(propLocalIPIF_set) {
|
|
LogError(0, RS_RET_ERR, "$LocalHostIPIF is already set "
|
|
"and cannot be reset; place it at TOP OF rsyslog.conf!");
|
|
ABORT_FINALIZE(RS_RET_ERR);
|
|
}
|
|
|
|
localRet = net.GetIFIPAddr(pNewVal, AF_UNSPEC, myIP, (int) sizeof(myIP));
|
|
if(localRet != RS_RET_OK) {
|
|
LogError(0, RS_RET_ERR, "$LocalHostIPIF: IP address for interface "
|
|
"'%s' cannnot be obtained - ignoring directive", pNewVal);
|
|
} else {
|
|
storeLocalHostIPIF(myIP);
|
|
}
|
|
|
|
|
|
finalize_it:
|
|
free(pNewVal); /* no longer needed -> is in prop! */
|
|
RETiRet;
|
|
}
|
|
|
|
|
|
/* This function is used to set the global work directory name.
|
|
* It verifies that the provided directory actually exists and
|
|
* emits an error message if not.
|
|
* rgerhards, 2011-02-16
|
|
*/
|
|
static rsRetVal setWorkDir(void __attribute__((unused)) *pVal, uchar *pNewVal)
|
|
{
|
|
size_t lenDir;
|
|
int i;
|
|
struct stat sb;
|
|
DEFiRet;
|
|
|
|
/* remove trailing slashes */
|
|
lenDir = ustrlen(pNewVal);
|
|
i = lenDir - 1;
|
|
while(i > 0 && pNewVal[i] == '/') {
|
|
--i;
|
|
}
|
|
|
|
if(i < 0) {
|
|
LogError(0, RS_RET_ERR_WRKDIR, "$WorkDirectory: empty value "
|
|
"- directive ignored");
|
|
ABORT_FINALIZE(RS_RET_ERR_WRKDIR);
|
|
}
|
|
|
|
if(i != (int) lenDir - 1) {
|
|
pNewVal[i+1] = '\0';
|
|
LogError(0, RS_RET_WRN_WRKDIR, "$WorkDirectory: trailing slashes "
|
|
"removed, new value is '%s'", pNewVal);
|
|
}
|
|
|
|
if(stat((char*) pNewVal, &sb) != 0) {
|
|
LogError(0, RS_RET_ERR_WRKDIR, "$WorkDirectory: %s can not be "
|
|
"accessed, probably does not exist - directive ignored", pNewVal);
|
|
ABORT_FINALIZE(RS_RET_ERR_WRKDIR);
|
|
}
|
|
|
|
if(!S_ISDIR(sb.st_mode)) {
|
|
LogError(0, RS_RET_ERR_WRKDIR, "$WorkDirectory: %s not a directory - directive ignored",
|
|
pNewVal);
|
|
ABORT_FINALIZE(RS_RET_ERR_WRKDIR);
|
|
}
|
|
|
|
free(loadConf->globals.pszWorkDir);
|
|
loadConf->globals.pszWorkDir = pNewVal;
|
|
|
|
finalize_it:
|
|
RETiRet;
|
|
}
|
|
|
|
|
|
static rsRetVal
|
|
setDfltNetstrmDrvrCAF(void __attribute__((unused)) *pVal, uchar *pNewVal) {
|
|
DEFiRet;
|
|
FILE *fp;
|
|
free(loadConf->globals.pszDfltNetstrmDrvrCAF);
|
|
fp = fopen((const char*)pNewVal, "r");
|
|
if(fp == NULL) {
|
|
LogError(errno, RS_RET_NO_FILE_ACCESS,
|
|
"error: defaultnetstreamdrivercafile file '%s' "
|
|
"could not be accessed", pNewVal);
|
|
} else {
|
|
fclose(fp);
|
|
loadConf->globals.pszDfltNetstrmDrvrCAF = pNewVal;
|
|
}
|
|
|
|
RETiRet;
|
|
}
|
|
|
|
static rsRetVal
|
|
setNetstrmDrvrCAExtraFiles(void __attribute__((unused)) *pVal, uchar *pNewVal) {
|
|
DEFiRet;
|
|
FILE *fp;
|
|
char* token;
|
|
int error = 0;
|
|
free(loadConf->globals.pszNetstrmDrvrCAExtraFiles);
|
|
|
|
token = strtok((char*)pNewVal, ",");
|
|
// Here, fopen per strtok ...
|
|
while(token != NULL) {
|
|
fp = fopen((const char*)token, "r");
|
|
if(fp == NULL) {
|
|
LogError(errno, RS_RET_NO_FILE_ACCESS,
|
|
"error: netstreamdrivercaextrafiles file '%s' "
|
|
"could not be accessed", token);
|
|
error = 1;
|
|
} else {
|
|
fclose(fp);
|
|
}
|
|
token = strtok(NULL, ",");
|
|
}
|
|
if(!error) {
|
|
loadConf->globals.pszNetstrmDrvrCAExtraFiles = pNewVal;
|
|
} else {
|
|
loadConf->globals.pszNetstrmDrvrCAExtraFiles = NULL;
|
|
}
|
|
RETiRet;
|
|
}
|
|
|
|
static rsRetVal
|
|
setDfltNetstrmDrvrCertFile(void __attribute__((unused)) *pVal, uchar *pNewVal) {
|
|
DEFiRet;
|
|
FILE *fp;
|
|
|
|
free(loadConf->globals.pszDfltNetstrmDrvrCertFile);
|
|
fp = fopen((const char*)pNewVal, "r");
|
|
if(fp == NULL) {
|
|
LogError(errno, RS_RET_NO_FILE_ACCESS,
|
|
"error: defaultnetstreamdrivercertfile '%s' "
|
|
"could not be accessed", pNewVal);
|
|
} else {
|
|
fclose(fp);
|
|
loadConf->globals.pszDfltNetstrmDrvrCertFile = pNewVal;
|
|
}
|
|
|
|
RETiRet;
|
|
}
|
|
|
|
static rsRetVal
|
|
setDfltNetstrmDrvrKeyFile(void __attribute__((unused)) *pVal, uchar *pNewVal) {
|
|
DEFiRet;
|
|
FILE *fp;
|
|
|
|
free(loadConf->globals.pszDfltNetstrmDrvrKeyFile);
|
|
fp = fopen((const char*)pNewVal, "r");
|
|
if(fp == NULL) {
|
|
LogError(errno, RS_RET_NO_FILE_ACCESS,
|
|
"error: defaultnetstreamdriverkeyfile '%s' "
|
|
"could not be accessed", pNewVal);
|
|
} else {
|
|
fclose(fp);
|
|
loadConf->globals.pszDfltNetstrmDrvrKeyFile = pNewVal;
|
|
}
|
|
|
|
RETiRet;
|
|
}
|
|
|
|
static rsRetVal
|
|
setDfltNetstrmDrvr(void __attribute__((unused)) *pVal, uchar *pNewVal) {
|
|
DEFiRet;
|
|
free(loadConf->globals.pszDfltNetstrmDrvr);
|
|
loadConf->globals.pszDfltNetstrmDrvr = pNewVal;
|
|
RETiRet;
|
|
}
|
|
|
|
static rsRetVal
|
|
setParserControlCharacterEscapePrefix(void __attribute__((unused)) *pVal, uchar *pNewVal) {
|
|
DEFiRet;
|
|
loadConf->globals.parser.cCCEscapeChar = *pNewVal;
|
|
RETiRet;
|
|
}
|
|
|
|
static rsRetVal
|
|
setParserDropTrailingLFOnReception(void __attribute__((unused)) *pVal, int pNewVal) {
|
|
DEFiRet;
|
|
loadConf->globals.parser.bDropTrailingLF = pNewVal;
|
|
RETiRet;
|
|
}
|
|
|
|
static rsRetVal
|
|
setParserEscapeControlCharactersOnReceive(void __attribute__((unused)) *pVal, int pNewVal) {
|
|
DEFiRet;
|
|
loadConf->globals.parser.bEscapeCCOnRcv = pNewVal;
|
|
RETiRet;
|
|
}
|
|
|
|
static rsRetVal
|
|
setParserSpaceLFOnReceive(void __attribute__((unused)) *pVal, int pNewVal) {
|
|
DEFiRet;
|
|
loadConf->globals.parser.bSpaceLFOnRcv = pNewVal;
|
|
RETiRet;
|
|
}
|
|
|
|
static rsRetVal
|
|
setParserEscape8BitCharactersOnReceive(void __attribute__((unused)) *pVal, int pNewVal) {
|
|
DEFiRet;
|
|
loadConf->globals.parser.bEscape8BitChars = pNewVal;
|
|
RETiRet;
|
|
}
|
|
|
|
static rsRetVal
|
|
setParserEscapeControlCharacterTab(void __attribute__((unused)) *pVal, int pNewVal) {
|
|
DEFiRet;
|
|
loadConf->globals.parser.bEscapeTab = pNewVal;
|
|
RETiRet;
|
|
}
|
|
|
|
/* This function is used both by legacy and RainerScript conf. It is a real setter. */
|
|
static void
|
|
setMaxLine(const int64_t iNew)
|
|
{
|
|
if(iNew < 128) {
|
|
LogError(0, RS_RET_INVALID_VALUE, "maxMessageSize tried to set "
|
|
"to %lld, but cannot be less than 128 - set to 128 "
|
|
"instead", (long long) iNew);
|
|
loadConf->globals.iMaxLine = 128;
|
|
} else if(iNew > (int64_t) INT_MAX) {
|
|
LogError(0, RS_RET_INVALID_VALUE, "maxMessageSize larger than "
|
|
"INT_MAX (%d) - reduced to INT_MAX", INT_MAX);
|
|
loadConf->globals.iMaxLine = INT_MAX;
|
|
} else {
|
|
loadConf->globals.iMaxLine = (int) iNew;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static rsRetVal
|
|
legacySetMaxMessageSize(void __attribute__((unused)) *pVal, int64_t iNew)
|
|
{
|
|
setMaxLine(iNew);
|
|
return RS_RET_OK;
|
|
}
|
|
|
|
static rsRetVal
|
|
setDebugFile(void __attribute__((unused)) *pVal, uchar *pNewVal)
|
|
{
|
|
DEFiRet;
|
|
dbgSetDebugFile(pNewVal);
|
|
free(pNewVal);
|
|
RETiRet;
|
|
}
|
|
|
|
static rsRetVal
|
|
setDebugLevel(void __attribute__((unused)) *pVal, int level)
|
|
{
|
|
DEFiRet;
|
|
dbgSetDebugLevel(level);
|
|
dbgprintf("debug level %d set via config file\n", level);
|
|
dbgprintf("This is rsyslog version " VERSION "\n");
|
|
RETiRet;
|
|
}
|
|
|
|
static rsRetVal ATTR_NONNULL()
|
|
setOversizeMsgInputMode(const uchar *const mode)
|
|
{
|
|
DEFiRet;
|
|
if(!strcmp((char*)mode, "truncate")) {
|
|
loadConf->globals.oversizeMsgInputMode = glblOversizeMsgInputMode_Truncate;
|
|
} else if(!strcmp((char*)mode, "split")) {
|
|
loadConf->globals.oversizeMsgInputMode = glblOversizeMsgInputMode_Split;
|
|
} else if(!strcmp((char*)mode, "accept")) {
|
|
loadConf->globals.oversizeMsgInputMode = glblOversizeMsgInputMode_Accept;
|
|
} else {
|
|
loadConf->globals.oversizeMsgInputMode = glblOversizeMsgInputMode_Truncate;
|
|
}
|
|
RETiRet;
|
|
}
|
|
|
|
static rsRetVal ATTR_NONNULL()
|
|
setReportChildProcessExits(const uchar *const mode)
|
|
{
|
|
DEFiRet;
|
|
if(!strcmp((char*)mode, "none")) {
|
|
loadConf->globals.reportChildProcessExits = REPORT_CHILD_PROCESS_EXITS_NONE;
|
|
} else if(!strcmp((char*)mode, "errors")) {
|
|
loadConf->globals.reportChildProcessExits = REPORT_CHILD_PROCESS_EXITS_ERRORS;
|
|
} else if(!strcmp((char*)mode, "all")) {
|
|
loadConf->globals.reportChildProcessExits = REPORT_CHILD_PROCESS_EXITS_ALL;
|
|
} else {
|
|
LogError(0, RS_RET_CONF_PARAM_INVLD,
|
|
"invalid value '%s' for global parameter reportChildProcessExits -- ignored",
|
|
mode);
|
|
iRet = RS_RET_CONF_PARAM_INVLD;
|
|
}
|
|
RETiRet;
|
|
}
|
|
|
|
static int
|
|
getDefPFFamily(rsconf_t *cnf)
|
|
{
|
|
return cnf->globals.iDefPFFamily;
|
|
}
|
|
|
|
/* return our local IP.
|
|
* If no local IP is set, "127.0.0.1" is selected *and* set. This
|
|
* is an intensional side effect that we do in order to keep things
|
|
* consistent and avoid config errors (this will make us not accept
|
|
* setting the local IP address once a module has obtained it - so
|
|
* it forces the $LocalHostIPIF directive high up in rsyslog.conf)
|
|
* rgerhards, 2012-03-21
|
|
*/
|
|
static prop_t*
|
|
GetLocalHostIP(void)
|
|
{
|
|
assert(propLocalIPIF != NULL);
|
|
return(propLocalIPIF);
|
|
}
|
|
|
|
|
|
/* set our local hostname. Free previous hostname, if it was already set.
|
|
* Note that we do now do this in a thread. As such, the method here
|
|
* is NOT 100% clean. If we run into issues, we need to think about
|
|
* refactoring the whole way we handle the local host name processing.
|
|
* Possibly using a PROP might be the right solution then.
|
|
*/
|
|
static rsRetVal
|
|
SetLocalHostName(uchar *const newname)
|
|
{
|
|
uchar *toFree;
|
|
if(LocalHostName == NULL || strcmp((const char*)LocalHostName, (const char*) newname)) {
|
|
toFree = LocalHostName;
|
|
LocalHostName = newname;
|
|
} else {
|
|
toFree = newname;
|
|
}
|
|
free(toFree);
|
|
return RS_RET_OK;
|
|
}
|
|
|
|
|
|
/* return our local hostname. if it is not set, "[localhost]" is returned
|
|
*/
|
|
static uchar*
|
|
GetLocalHostName(void)
|
|
{
|
|
uchar *pszRet;
|
|
|
|
if(LocalHostNameOverride != NULL) {
|
|
pszRet = LocalHostNameOverride;
|
|
goto done;
|
|
}
|
|
|
|
if(LocalHostName == NULL)
|
|
pszRet = (uchar*) "[localhost]";
|
|
else {
|
|
if(GetPreserveFQDN() == 1)
|
|
pszRet = LocalFQDNName;
|
|
else
|
|
pszRet = LocalHostName;
|
|
}
|
|
done:
|
|
return(pszRet);
|
|
}
|
|
|
|
|
|
/* return the name of the file where oversize messages are written to
|
|
*/
|
|
uchar*
|
|
glblGetOversizeMsgErrorFile(rsconf_t *cnf)
|
|
{
|
|
return cnf->globals.oversizeMsgErrorFile;
|
|
}
|
|
|
|
const uchar*
|
|
glblGetOperatingStateFile(rsconf_t *cnf)
|
|
{
|
|
return cnf->globals.operatingStateFile;
|
|
}
|
|
|
|
/* return the mode with which oversize messages will be put forward
|
|
*/
|
|
int
|
|
glblGetOversizeMsgInputMode(rsconf_t *cnf)
|
|
{
|
|
return cnf->globals.oversizeMsgInputMode;
|
|
}
|
|
|
|
int
|
|
glblReportOversizeMessage(rsconf_t *cnf)
|
|
{
|
|
return cnf->globals.reportOversizeMsg;
|
|
}
|
|
|
|
|
|
/* logs a message indicating that a child process has terminated.
|
|
* If name != NULL, prints it as the program name.
|
|
*/
|
|
void
|
|
glblReportChildProcessExit(rsconf_t *cnf, const uchar *name, pid_t pid, int status)
|
|
{
|
|
DBGPRINTF("waitpid for child %ld returned status: %2.2x\n", (long) pid, status);
|
|
|
|
if(cnf->globals.reportChildProcessExits == REPORT_CHILD_PROCESS_EXITS_NONE
|
|
|| (cnf->globals.reportChildProcessExits == REPORT_CHILD_PROCESS_EXITS_ERRORS
|
|
&& WIFEXITED(status) && WEXITSTATUS(status) == 0)) {
|
|
return;
|
|
}
|
|
|
|
if(WIFEXITED(status)) {
|
|
int severity = WEXITSTATUS(status) == 0 ? LOG_INFO : LOG_WARNING;
|
|
if(name != NULL) {
|
|
LogMsg(0, NO_ERRCODE, severity, "program '%s' (pid %ld) exited with status %d",
|
|
name, (long) pid, WEXITSTATUS(status));
|
|
} else {
|
|
LogMsg(0, NO_ERRCODE, severity, "child process (pid %ld) exited with status %d",
|
|
(long) pid, WEXITSTATUS(status));
|
|
}
|
|
} else if(WIFSIGNALED(status)) {
|
|
if(name != NULL) {
|
|
LogMsg(0, NO_ERRCODE, LOG_WARNING, "program '%s' (pid %ld) terminated by signal %d",
|
|
name, (long) pid, WTERMSIG(status));
|
|
} else {
|
|
LogMsg(0, NO_ERRCODE, LOG_WARNING, "child process (pid %ld) terminated by signal %d",
|
|
(long) pid, WTERMSIG(status));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* set our local domain name. Free previous domain, if it was already set.
|
|
*/
|
|
static rsRetVal
|
|
SetLocalDomain(uchar *newname)
|
|
{
|
|
free(LocalDomain);
|
|
LocalDomain = newname;
|
|
return RS_RET_OK;
|
|
}
|
|
|
|
|
|
/* return our local hostname. if it is not set, "[localhost]" is returned
|
|
*/
|
|
static uchar*
|
|
GetLocalDomain(void)
|
|
{
|
|
return LocalDomain;
|
|
}
|
|
|
|
|
|
/* generate the local hostname property. This must be done after the hostname info
|
|
* has been set as well as PreserveFQDN.
|
|
* rgerhards, 2009-06-30
|
|
* NOTE: This function tries to avoid locking by not destructing the previous value
|
|
* immediately. This is so that current readers can continue to use the previous name.
|
|
* Otherwise, we would need to use read/write locks to protect the update process.
|
|
* In order to do so, we save the previous value and delete it when we are called again
|
|
* the next time. Note that this in theory is racy and can lead to a double-free.
|
|
* In practice, however, the window of exposure to trigger this is extremely short
|
|
* and as this functions is very infrequently being called (on HUP), the trigger
|
|
* condition for this bug is so highly unlikely that it never occurs in practice.
|
|
* Probably if you HUP rsyslog every few milliseconds, but who does that...
|
|
* To further reduce risk potential, we do only update the property when there
|
|
* actually is a hostname change, which makes it even less likely.
|
|
* rgerhards, 2013-10-28
|
|
*/
|
|
static rsRetVal
|
|
GenerateLocalHostNameProperty(void)
|
|
{
|
|
uchar *pszPrev;
|
|
int lenPrev;
|
|
prop_t *hostnameNew;
|
|
uchar *pszName;
|
|
DEFiRet;
|
|
|
|
if(propLocalHostNameToDelete != NULL)
|
|
prop.Destruct(&propLocalHostNameToDelete);
|
|
|
|
if(LocalHostNameOverride == NULL) {
|
|
if(LocalHostName == NULL)
|
|
pszName = (uchar*) "[localhost]";
|
|
else {
|
|
if(GetPreserveFQDN() == 1)
|
|
pszName = LocalFQDNName;
|
|
else
|
|
pszName = LocalHostName;
|
|
}
|
|
} else { /* local hostname is overriden via config */
|
|
pszName = LocalHostNameOverride;
|
|
}
|
|
DBGPRINTF("GenerateLocalHostName uses '%s'\n", pszName);
|
|
|
|
if(propLocalHostName == NULL)
|
|
pszPrev = (uchar*)""; /* make sure strcmp() below does not match */
|
|
else
|
|
prop.GetString(propLocalHostName, &pszPrev, &lenPrev);
|
|
|
|
if(ustrcmp(pszPrev, pszName)) {
|
|
/* we need to update */
|
|
CHKiRet(prop.Construct(&hostnameNew));
|
|
CHKiRet(prop.SetString(hostnameNew, pszName, ustrlen(pszName)));
|
|
CHKiRet(prop.ConstructFinalize(hostnameNew));
|
|
propLocalHostNameToDelete = propLocalHostName;
|
|
propLocalHostName = hostnameNew;
|
|
}
|
|
|
|
finalize_it:
|
|
RETiRet;
|
|
}
|
|
|
|
|
|
/* return our local hostname as a string property
|
|
*/
|
|
static prop_t*
|
|
GetLocalHostNameProp(void)
|
|
{
|
|
return(propLocalHostName);
|
|
}
|
|
|
|
|
|
static rsRetVal
|
|
SetLocalFQDNName(uchar *newname)
|
|
{
|
|
free(LocalFQDNName);
|
|
LocalFQDNName = newname;
|
|
return RS_RET_OK;
|
|
}
|
|
|
|
/* return the current localhost name as FQDN (requires FQDN to be set)
|
|
* TODO: we should set the FQDN ourselfs in here!
|
|
*/
|
|
static uchar*
|
|
GetLocalFQDNName(void)
|
|
{
|
|
return(LocalFQDNName == NULL ? (uchar*) "[localhost]" : LocalFQDNName);
|
|
}
|
|
|
|
|
|
/* return the current working directory */
|
|
static uchar*
|
|
GetWorkDir(rsconf_t *cnf)
|
|
{
|
|
return(cnf->globals.pszWorkDir == NULL ? (uchar*) "" : cnf->globals.pszWorkDir);
|
|
}
|
|
|
|
/* return the "raw" working directory, which means
|
|
* NULL if unset.
|
|
*/
|
|
const uchar *
|
|
glblGetWorkDirRaw(rsconf_t *cnf)
|
|
{
|
|
return cnf->globals.pszWorkDir;
|
|
}
|
|
|
|
/* return the current default netstream driver */
|
|
static uchar*
|
|
GetDfltNetstrmDrvr(rsconf_t *cnf)
|
|
{
|
|
return(cnf->globals.pszDfltNetstrmDrvr == NULL ? DFLT_NETSTRM_DRVR : cnf->globals.pszDfltNetstrmDrvr);
|
|
}
|
|
|
|
/* [ar] Source IP for local client to be used on multihomed host */
|
|
static rsRetVal
|
|
SetSourceIPofLocalClient(uchar *newname)
|
|
{
|
|
if(SourceIPofLocalClient != NULL) {
|
|
free(SourceIPofLocalClient); }
|
|
SourceIPofLocalClient = newname;
|
|
return RS_RET_OK;
|
|
}
|
|
|
|
static uchar*
|
|
GetSourceIPofLocalClient(void)
|
|
{
|
|
return(SourceIPofLocalClient);
|
|
}
|
|
|
|
|
|
/* queryInterface function
|
|
* rgerhards, 2008-02-21
|
|
*/
|
|
BEGINobjQueryInterface(glbl)
|
|
CODESTARTobjQueryInterface(glbl)
|
|
if(pIf->ifVersion != glblCURR_IF_VERSION) { /* check for current version, increment on each change */
|
|
ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED);
|
|
}
|
|
|
|
/* ok, we have the right interface, so let's fill it
|
|
* Please note that we may also do some backwards-compatibility
|
|
* work here (if we can support an older interface version - that,
|
|
* of course, also affects the "if" above).
|
|
*/
|
|
pIf->GetWorkDir = GetWorkDir;
|
|
pIf->GenerateLocalHostNameProperty = GenerateLocalHostNameProperty;
|
|
pIf->GetLocalHostNameProp = GetLocalHostNameProp;
|
|
pIf->GetLocalHostIP = GetLocalHostIP;
|
|
pIf->SetGlobalInputTermination = SetGlobalInputTermination;
|
|
pIf->GetGlobalInputTermState = GetGlobalInputTermState;
|
|
pIf->GetSourceIPofLocalClient = GetSourceIPofLocalClient; /* [ar] */
|
|
pIf->SetSourceIPofLocalClient = SetSourceIPofLocalClient; /* [ar] */
|
|
pIf->GetDefPFFamily = getDefPFFamily;
|
|
pIf->GetDisableDNS = GetDisableDNS;
|
|
pIf->GetMaxLine = glblGetMaxLine;
|
|
pIf->GetOptionDisallowWarning = GetOptionDisallowWarning;
|
|
pIf->GetDfltNetstrmDrvrCAF = GetDfltNetstrmDrvrCAF;
|
|
pIf->GetDfltNetstrmDrvrCertFile = GetDfltNetstrmDrvrCertFile;
|
|
pIf->GetDfltNetstrmDrvrKeyFile = GetDfltNetstrmDrvrKeyFile;
|
|
pIf->GetDfltNetstrmDrvr = GetDfltNetstrmDrvr;
|
|
pIf->GetNetstrmDrvrCAExtraFiles = GetNetstrmDrvrCAExtraFiles;
|
|
pIf->GetParserControlCharacterEscapePrefix = GetParserControlCharacterEscapePrefix;
|
|
pIf->GetParserDropTrailingLFOnReception = GetParserDropTrailingLFOnReception;
|
|
pIf->GetParserEscapeControlCharactersOnReceive = GetParserEscapeControlCharactersOnReceive;
|
|
pIf->GetParserSpaceLFOnReceive = GetParserSpaceLFOnReceive;
|
|
pIf->GetParserEscape8BitCharactersOnReceive = GetParserEscape8BitCharactersOnReceive;
|
|
pIf->GetParserEscapeControlCharacterTab = GetParserEscapeControlCharacterTab;
|
|
#define SIMP_PROP(name) \
|
|
pIf->Get##name = Get##name; \
|
|
pIf->Set##name = Set##name;
|
|
SIMP_PROP(PreserveFQDN);
|
|
SIMP_PROP(DropMalPTRMsgs);
|
|
SIMP_PROP(mainqCnfObj);
|
|
SIMP_PROP(LocalFQDNName)
|
|
SIMP_PROP(LocalHostName)
|
|
SIMP_PROP(LocalDomain)
|
|
SIMP_PROP(ParserEscapeControlCharactersCStyle)
|
|
SIMP_PROP(ParseHOSTNAMEandTAG)
|
|
#ifdef USE_UNLIMITED_SELECT
|
|
SIMP_PROP(FdSetSize)
|
|
#endif
|
|
#undef SIMP_PROP
|
|
finalize_it:
|
|
ENDobjQueryInterface(glbl)
|
|
|
|
/* Reset config variables to default values.
|
|
* rgerhards, 2008-04-17
|
|
*/
|
|
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
|
|
{
|
|
free(loadConf->globals.pszDfltNetstrmDrvr);
|
|
loadConf->globals.pszDfltNetstrmDrvr = NULL;
|
|
free(loadConf->globals.pszDfltNetstrmDrvrCAF);
|
|
loadConf->globals.pszDfltNetstrmDrvrCAF = NULL;
|
|
free(loadConf->globals.pszDfltNetstrmDrvrKeyFile);
|
|
loadConf->globals.pszDfltNetstrmDrvrKeyFile = NULL;
|
|
free(loadConf->globals.pszDfltNetstrmDrvrCertFile);
|
|
loadConf->globals.pszDfltNetstrmDrvrCertFile = NULL;
|
|
free(LocalHostNameOverride);
|
|
LocalHostNameOverride = NULL;
|
|
free(loadConf->globals.oversizeMsgErrorFile);
|
|
loadConf->globals.oversizeMsgErrorFile = NULL;
|
|
loadConf->globals.oversizeMsgInputMode = glblOversizeMsgInputMode_Accept;
|
|
loadConf->globals.reportChildProcessExits = REPORT_CHILD_PROCESS_EXITS_ERRORS;
|
|
free(loadConf->globals.pszWorkDir);
|
|
loadConf->globals.pszWorkDir = NULL;
|
|
free((void*)loadConf->globals.operatingStateFile);
|
|
loadConf->globals.operatingStateFile = NULL;
|
|
loadConf->globals.bDropMalPTRMsgs = 0;
|
|
bPreserveFQDN = 0;
|
|
loadConf->globals.iMaxLine = 8192;
|
|
loadConf->globals.reportOversizeMsg = 1;
|
|
loadConf->globals.parser.cCCEscapeChar = '#';
|
|
loadConf->globals.parser.bDropTrailingLF = 1;
|
|
loadConf->globals.parser.bEscapeCCOnRcv = 1; /* default is to escape control characters */
|
|
loadConf->globals.parser.bSpaceLFOnRcv = 0;
|
|
loadConf->globals.parser.bEscape8BitChars = 0; /* default is not to escape control characters */
|
|
loadConf->globals.parser.bEscapeTab = 1; /* default is to escape tab characters */
|
|
loadConf->globals.parser.bParserEscapeCCCStyle = 0;
|
|
#ifdef USE_UNLIMITED_SELECT
|
|
iFdSetSize = howmany(FD_SETSIZE, __NFDBITS) * sizeof (fd_mask);
|
|
#endif
|
|
return RS_RET_OK;
|
|
}
|
|
|
|
|
|
/* Prepare for new config
|
|
*/
|
|
void
|
|
glblPrepCnf(void)
|
|
{
|
|
free(mainqCnfObj);
|
|
mainqCnfObj = NULL;
|
|
free(cnfparamvals);
|
|
cnfparamvals = NULL;
|
|
}
|
|
|
|
/* handle the timezone() object. Each incarnation adds one additional
|
|
* zone info to the global table of time zones.
|
|
*/
|
|
|
|
int
|
|
bs_arrcmp_glblDbgFiles(const void *s1, const void *s2)
|
|
{
|
|
return strcmp((char*)s1, *(char**)s2);
|
|
}
|
|
|
|
|
|
|
|
/* handle a global config object. Note that multiple global config statements
|
|
* are permitted (because of plugin support), so once we got a param block,
|
|
* we need to hold to it.
|
|
* rgerhards, 2011-07-19
|
|
*/
|
|
void
|
|
glblProcessCnf(struct cnfobj *o)
|
|
{
|
|
int i;
|
|
|
|
cnfparamvals = nvlstGetParams(o->nvlst, ¶mblk, cnfparamvals);
|
|
if(cnfparamvals == NULL) {
|
|
LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing global "
|
|
"config parameters [global(...)]");
|
|
goto done;
|
|
}
|
|
if(Debug) {
|
|
dbgprintf("glbl param blk after glblProcessCnf:\n");
|
|
cnfparamsPrint(¶mblk, cnfparamvals);
|
|
}
|
|
|
|
/* The next thing is a bit hackish and should be changed in higher
|
|
* versions. There are a select few parameters which we need to
|
|
* act on immediately. These are processed here.
|
|
*/
|
|
for(i = 0 ; i < paramblk.nParams ; ++i) {
|
|
if(!cnfparamvals[i].bUsed)
|
|
continue;
|
|
if(!strcmp(paramblk.descr[i].name, "processinternalmessages")) {
|
|
loadConf->globals.bProcessInternalMessages = (int) cnfparamvals[i].val.d.n;
|
|
cnfparamvals[i].bUsed = TRUE;
|
|
} else if(!strcmp(paramblk.descr[i].name, "internal.developeronly.options")) {
|
|
loadConf->globals.glblDevOptions = (uint64_t) cnfparamvals[i].val.d.n;
|
|
cnfparamvals[i].bUsed = TRUE;
|
|
} else if(!strcmp(paramblk.descr[i].name, "stdlog.channelspec")) {
|
|
#ifndef ENABLE_LIBLOGGING_STDLOG
|
|
LogError(0, RS_RET_ERR, "rsyslog wasn't "
|
|
"compiled with liblogging-stdlog support. "
|
|
"The 'stdlog.channelspec' parameter "
|
|
"is ignored. Note: the syslog API is used instead.\n");
|
|
#else
|
|
loadConf->globals.stdlog_chanspec = (uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
|
|
/* we need to re-open with the new channel */
|
|
stdlog_close(loadConf->globals.stdlog_hdl);
|
|
loadConf->globals.stdlog_hdl = stdlog_open("rsyslogd", 0, STDLOG_SYSLOG,
|
|
(char*) loadConf->globals.stdlog_chanspec);
|
|
cnfparamvals[i].bUsed = TRUE;
|
|
#endif
|
|
} else if(!strcmp(paramblk.descr[i].name, "operatingstatefile")) {
|
|
if(loadConf->globals.operatingStateFile != NULL) {
|
|
LogError(errno, RS_RET_PARAM_ERROR,
|
|
"error: operatingStateFile already set to '%s' - "
|
|
"new value ignored", loadConf->globals.operatingStateFile);
|
|
} else {
|
|
loadConf->globals.operatingStateFile =
|
|
(uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
|
|
osf_open();
|
|
}
|
|
} else if(!strcmp(paramblk.descr[i].name, "security.abortonidresolutionfail")) {
|
|
loadConf->globals.abortOnIDResolutionFail = (int) cnfparamvals[i].val.d.n;
|
|
cnfparamvals[i].bUsed = TRUE;
|
|
}
|
|
}
|
|
done: return;
|
|
}
|
|
|
|
/* Set mainq parameters. Note that when this is not called, we'll use the
|
|
* legacy parameter config. mainq parameters can only be set once.
|
|
*/
|
|
void
|
|
glblProcessMainQCnf(struct cnfobj *o)
|
|
{
|
|
if(mainqCnfObj == NULL) {
|
|
mainqCnfObj = o;
|
|
} else {
|
|
LogError(0, RS_RET_ERR, "main_queue() object can only be specified "
|
|
"once - all but first ignored\n");
|
|
}
|
|
}
|
|
|
|
/* destruct the main q cnf object after it is no longer needed. This is
|
|
* also used to do some final checks.
|
|
*/
|
|
void
|
|
glblDestructMainqCnfObj(void)
|
|
{
|
|
/* Only destruct if not NULL! */
|
|
if (mainqCnfObj != NULL) {
|
|
nvlstChkUnused(mainqCnfObj->nvlst);
|
|
cnfobjDestruct(mainqCnfObj);
|
|
mainqCnfObj = NULL;
|
|
}
|
|
}
|
|
|
|
static int
|
|
qs_arrcmp_glblDbgFiles(const void *s1, const void *s2)
|
|
{
|
|
return strcmp(*((char**)s1), *((char**)s2));
|
|
}
|
|
|
|
/* set an environment variable */
|
|
static rsRetVal
|
|
do_setenv(const char *const var)
|
|
{
|
|
char varname[128];
|
|
const char *val = var;
|
|
size_t i;
|
|
DEFiRet;
|
|
|
|
for(i = 0 ; *val != '=' ; ++i, ++val) {
|
|
if(i == sizeof(varname)-i) {
|
|
parser_errmsg("environment variable name too long "
|
|
"[max %zu chars] or malformed entry: '%s'",
|
|
sizeof(varname)-1, var);
|
|
ABORT_FINALIZE(RS_RET_ERR_SETENV);
|
|
}
|
|
if(*val == '\0') {
|
|
parser_errmsg("environment variable entry is missing "
|
|
"equal sign (for value): '%s'", var);
|
|
ABORT_FINALIZE(RS_RET_ERR_SETENV);
|
|
}
|
|
varname[i] = *val;
|
|
}
|
|
varname[i] = '\0';
|
|
++val;
|
|
DBGPRINTF("do_setenv, var '%s', val '%s'\n", varname, val);
|
|
|
|
if(setenv(varname, val, 1) != 0) {
|
|
char errStr[1024];
|
|
rs_strerror_r(errno, errStr, sizeof(errStr));
|
|
parser_errmsg("error setting environment variable "
|
|
"'%s' to '%s': %s", varname, val, errStr);
|
|
ABORT_FINALIZE(RS_RET_ERR_SETENV);
|
|
}
|
|
|
|
|
|
finalize_it:
|
|
RETiRet;
|
|
}
|
|
|
|
|
|
/* This processes the "regular" parameters which are to be set after the
|
|
* config has been fully loaded.
|
|
*/
|
|
rsRetVal
|
|
glblDoneLoadCnf(void)
|
|
{
|
|
int i;
|
|
unsigned char *cstr;
|
|
DEFiRet;
|
|
CHKiRet(objUse(net, CORE_COMPONENT));
|
|
|
|
sortTimezones(loadConf);
|
|
DBGPRINTF("Timezone information table (%d entries):\n", loadConf->timezones.ntzinfos);
|
|
displayTimezones(loadConf);
|
|
|
|
if(cnfparamvals == NULL)
|
|
goto finalize_it;
|
|
|
|
for(i = 0 ; i < paramblk.nParams ; ++i) {
|
|
if(!cnfparamvals[i].bUsed)
|
|
continue;
|
|
if(!strcmp(paramblk.descr[i].name, "workdirectory")) {
|
|
cstr = (uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
|
|
setWorkDir(NULL, cstr);
|
|
} else if(!strcmp(paramblk.descr[i].name, "variables.casesensitive")) {
|
|
const int val = (int) cnfparamvals[i].val.d.n;
|
|
fjson_global_do_case_sensitive_comparison(val);
|
|
DBGPRINTF("global/config: set case sensitive variables to %d\n",
|
|
val);
|
|
} else if(!strcmp(paramblk.descr[i].name, "localhostname")) {
|
|
free(LocalHostNameOverride);
|
|
LocalHostNameOverride = (uchar*)
|
|
es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
|
|
} else if(!strcmp(paramblk.descr[i].name, "defaultnetstreamdriverkeyfile")) {
|
|
cstr = (uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
|
|
setDfltNetstrmDrvrKeyFile(NULL, cstr);
|
|
} else if(!strcmp(paramblk.descr[i].name, "defaultnetstreamdrivercertfile")) {
|
|
cstr = (uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
|
|
setDfltNetstrmDrvrCertFile(NULL, cstr);
|
|
} else if(!strcmp(paramblk.descr[i].name, "defaultnetstreamdrivercafile")) {
|
|
cstr = (uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
|
|
setDfltNetstrmDrvrCAF(NULL, cstr);
|
|
} else if(!strcmp(paramblk.descr[i].name, "defaultnetstreamdriver")) {
|
|
cstr = (uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
|
|
setDfltNetstrmDrvr(NULL, cstr);
|
|
} else if(!strcmp(paramblk.descr[i].name, "netstreamdrivercaextrafiles")) {
|
|
cstr = (uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
|
|
setNetstrmDrvrCAExtraFiles(NULL, cstr);
|
|
} else if(!strcmp(paramblk.descr[i].name, "preservefqdn")) {
|
|
bPreserveFQDN = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name,
|
|
"dropmsgswithmaliciousdnsptrrecords")) {
|
|
loadConf->globals.bDropMalPTRMsgs = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "action.reportsuspension")) {
|
|
loadConf->globals.bActionReportSuspension = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "action.reportsuspensioncontinuation")) {
|
|
loadConf->globals.bActionReportSuspensionCont = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "maxmessagesize")) {
|
|
setMaxLine(cnfparamvals[i].val.d.n);
|
|
} else if(!strcmp(paramblk.descr[i].name, "oversizemsg.errorfile")) {
|
|
free(loadConf->globals.oversizeMsgErrorFile);
|
|
loadConf->globals.oversizeMsgErrorFile = (uchar*)es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
|
|
} else if(!strcmp(paramblk.descr[i].name, "oversizemsg.report")) {
|
|
loadConf->globals.reportOversizeMsg = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "oversizemsg.input.mode")) {
|
|
const char *const tmp = es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
|
|
setOversizeMsgInputMode((uchar*) tmp);
|
|
free((void*)tmp);
|
|
} else if(!strcmp(paramblk.descr[i].name, "reportchildprocessexits")) {
|
|
const char *const tmp = es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
|
|
setReportChildProcessExits((uchar*) tmp);
|
|
free((void*)tmp);
|
|
} else if(!strcmp(paramblk.descr[i].name, "debug.onshutdown")) {
|
|
loadConf->globals.debugOnShutdown = (int) cnfparamvals[i].val.d.n;
|
|
LogError(0, RS_RET_OK, "debug: onShutdown set to %d", loadConf->globals.debugOnShutdown);
|
|
} else if(!strcmp(paramblk.descr[i].name, "debug.gnutls")) {
|
|
loadConf->globals.iGnuTLSLoglevel = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "debug.unloadmodules")) {
|
|
glblUnloadModules = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "parser.controlcharacterescapeprefix")) {
|
|
uchar* tmp = (uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
|
|
setParserControlCharacterEscapePrefix(NULL, tmp);
|
|
free(tmp);
|
|
} else if(!strcmp(paramblk.descr[i].name, "parser.droptrailinglfonreception")) {
|
|
const int tmp = (int) cnfparamvals[i].val.d.n;
|
|
setParserDropTrailingLFOnReception(NULL, tmp);
|
|
} else if(!strcmp(paramblk.descr[i].name, "parser.escapecontrolcharactersonreceive")) {
|
|
const int tmp = (int) cnfparamvals[i].val.d.n;
|
|
setParserEscapeControlCharactersOnReceive(NULL, tmp);
|
|
} else if(!strcmp(paramblk.descr[i].name, "parser.spacelfonreceive")) {
|
|
const int tmp = (int) cnfparamvals[i].val.d.n;
|
|
setParserSpaceLFOnReceive(NULL, tmp);
|
|
} else if(!strcmp(paramblk.descr[i].name, "parser.escape8bitcharactersonreceive")) {
|
|
const int tmp = (int) cnfparamvals[i].val.d.n;
|
|
setParserEscape8BitCharactersOnReceive(NULL, tmp);
|
|
} else if(!strcmp(paramblk.descr[i].name, "parser.escapecontrolcharactertab")) {
|
|
const int tmp = (int) cnfparamvals[i].val.d.n;
|
|
setParserEscapeControlCharacterTab(NULL, tmp);
|
|
} else if(!strcmp(paramblk.descr[i].name, "parser.escapecontrolcharacterscstyle")) {
|
|
const int tmp = (int) cnfparamvals[i].val.d.n;
|
|
SetParserEscapeControlCharactersCStyle(tmp);
|
|
} else if(!strcmp(paramblk.descr[i].name, "parser.parsehostnameandtag")) {
|
|
const int tmp = (int) cnfparamvals[i].val.d.n;
|
|
SetParseHOSTNAMEandTAG(tmp);
|
|
} else if(!strcmp(paramblk.descr[i].name, "parser.permitslashinprogramname")) {
|
|
loadConf->globals.parser.bPermitSlashInProgramname = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "debug.logfile")) {
|
|
if(pszAltDbgFileName == NULL) {
|
|
pszAltDbgFileName = es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
|
|
/* can actually happen if debug system also opened altdbg */
|
|
if(altdbg != -1) {
|
|
close(altdbg);
|
|
}
|
|
if((altdbg = open(pszAltDbgFileName, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY
|
|
|O_CLOEXEC, S_IRUSR|S_IWUSR)) == -1) {
|
|
LogError(0, RS_RET_ERR, "debug log file '%s' could not be opened",
|
|
pszAltDbgFileName);
|
|
}
|
|
}
|
|
LogError(0, RS_RET_OK, "debug log file is '%s', fd %d", pszAltDbgFileName, altdbg);
|
|
} else if(!strcmp(paramblk.descr[i].name, "janitor.interval")) {
|
|
loadConf->globals.janitorInterval = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "net.ipprotocol")) {
|
|
char *proto = es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
|
|
if(!strcmp(proto, "unspecified")) {
|
|
loadConf->globals.iDefPFFamily = PF_UNSPEC;
|
|
} else if(!strcmp(proto, "ipv4-only")) {
|
|
loadConf->globals.iDefPFFamily = PF_INET;
|
|
} else if(!strcmp(proto, "ipv6-only")) {
|
|
loadConf->globals.iDefPFFamily = PF_INET6;
|
|
} else{
|
|
LogError(0, RS_RET_ERR, "invalid net.ipprotocol "
|
|
"parameter '%s' -- ignored", proto);
|
|
}
|
|
free(proto);
|
|
} else if(!strcmp(paramblk.descr[i].name, "senders.reportnew")) {
|
|
loadConf->globals.reportNewSenders = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "senders.reportgoneaway")) {
|
|
loadConf->globals.reportGoneAwaySenders = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "senders.timeoutafter")) {
|
|
loadConf->globals.senderStatsTimeout = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "senders.keeptrack")) {
|
|
loadConf->globals.senderKeepTrack = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "inputs.timeout.shutdown")) {
|
|
loadConf->globals.inputTimeoutShutdown = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "privdrop.group.keepsupplemental")) {
|
|
loadConf->globals.gidDropPrivKeepSupplemental = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "privdrop.group.id")) {
|
|
loadConf->globals.gidDropPriv = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "privdrop.group.name")) {
|
|
loadConf->globals.gidDropPriv = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "privdrop.user.id")) {
|
|
loadConf->globals.uidDropPriv = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "privdrop.user.name")) {
|
|
loadConf->globals.uidDropPriv = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "security.abortonidresolutionfail")) {
|
|
loadConf->globals.abortOnIDResolutionFail = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "net.acladdhostnameonfail")) {
|
|
loadConf->globals.ACLAddHostnameOnFail = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "net.aclresolvehostname")) {
|
|
loadConf->globals.ACLDontResolve = !((int) cnfparamvals[i].val.d.n);
|
|
} else if(!strcmp(paramblk.descr[i].name, "net.enabledns")) {
|
|
SetDisableDNS(!((int) cnfparamvals[i].val.d.n));
|
|
} else if(!strcmp(paramblk.descr[i].name, "net.permitwarning")) {
|
|
SetOptionDisallowWarning(!((int) cnfparamvals[i].val.d.n));
|
|
} else if(!strcmp(paramblk.descr[i].name, "abortonuncleanconfig")) {
|
|
loadConf->globals.bAbortOnUncleanConfig = cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "internalmsg.ratelimit.burst")) {
|
|
loadConf->globals.intMsgRateLimitBurst = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "internalmsg.ratelimit.interval")) {
|
|
loadConf->globals.intMsgRateLimitItv = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "internalmsg.severity")) {
|
|
loadConf->globals.intMsgsSeverityFilter = (int) cnfparamvals[i].val.d.n;
|
|
if((loadConf->globals.intMsgsSeverityFilter < 0) ||
|
|
(loadConf->globals.intMsgsSeverityFilter > 7)) {
|
|
parser_errmsg("invalid internalmsg.severity value");
|
|
loadConf->globals.intMsgsSeverityFilter = DFLT_INT_MSGS_SEV_FILTER;
|
|
}
|
|
} else if(!strcmp(paramblk.descr[i].name, "environment")) {
|
|
for(int j = 0 ; j < cnfparamvals[i].val.d.ar->nmemb ; ++j) {
|
|
char *const var = es_str2cstr(cnfparamvals[i].val.d.ar->arr[j], NULL);
|
|
do_setenv(var);
|
|
free(var);
|
|
}
|
|
} else if(!strcmp(paramblk.descr[i].name, "errormessagestostderr.maxnumber")) {
|
|
loadConf->globals.maxErrMsgToStderr = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "debug.files")) {
|
|
free(glblDbgFiles); /* "fix" Coverity false positive */
|
|
glblDbgFilesNum = cnfparamvals[i].val.d.ar->nmemb;
|
|
glblDbgFiles = (char**) malloc(cnfparamvals[i].val.d.ar->nmemb * sizeof(char*));
|
|
for(int j = 0 ; j < cnfparamvals[i].val.d.ar->nmemb ; ++j) {
|
|
glblDbgFiles[j] = es_str2cstr(cnfparamvals[i].val.d.ar->arr[j], NULL);
|
|
}
|
|
qsort(glblDbgFiles, glblDbgFilesNum, sizeof(char*), qs_arrcmp_glblDbgFiles);
|
|
} else if(!strcmp(paramblk.descr[i].name, "debug.whitelist")) {
|
|
glblDbgWhitelist = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "shutdown.queue.doublesize")) {
|
|
loadConf->globals.shutdownQueueDoubleSize = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "umask")) {
|
|
loadConf->globals.umask = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "shutdown.enable.ctlc")) {
|
|
loadConf->globals.permitCtlC = (int) cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "default.action.queue.timeoutshutdown")) {
|
|
loadConf->globals.actq_dflt_toQShutdown = cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "default.action.queue.timeoutactioncompletion")) {
|
|
loadConf->globals.actq_dflt_toActShutdown = cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "default.action.queue.timeoutenqueue")) {
|
|
loadConf->globals.actq_dflt_toEnq = cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "default.action.queue.timeoutworkerthreadshutdown")) {
|
|
loadConf->globals.actq_dflt_toWrkShutdown = cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "default.ruleset.queue.timeoutshutdown")) {
|
|
loadConf->globals.ruleset_dflt_toQShutdown = cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "default.ruleset.queue.timeoutactioncompletion")) {
|
|
loadConf->globals.ruleset_dflt_toActShutdown = cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "default.ruleset.queue.timeoutenqueue")) {
|
|
loadConf->globals.ruleset_dflt_toEnq = cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "default.ruleset.queue.timeoutworkerthreadshutdown")) {
|
|
loadConf->globals.ruleset_dflt_toWrkShutdown = cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "reverselookup.cache.ttl.default")) {
|
|
loadConf->globals.dnscacheDefaultTTL = cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "reverselookup.cache.ttl.enable")) {
|
|
loadConf->globals.dnscacheEnableTTL = cnfparamvals[i].val.d.n;
|
|
} else if(!strcmp(paramblk.descr[i].name, "parser.supportcompressionextension")) {
|
|
loadConf->globals.bSupportCompressionExtension = cnfparamvals[i].val.d.n;
|
|
} else {
|
|
dbgprintf("glblDoneLoadCnf: program error, non-handled "
|
|
"param '%s'\n", paramblk.descr[i].name);
|
|
}
|
|
}
|
|
|
|
if(loadConf->globals.debugOnShutdown && Debug != DEBUG_FULL) {
|
|
Debug = DEBUG_ONDEMAND;
|
|
stddbg = -1;
|
|
}
|
|
|
|
finalize_it: RETiRet;
|
|
}
|
|
|
|
|
|
/* Initialize the glbl class. Must be called as the very first method
|
|
* before anything else is called inside this class.
|
|
* rgerhards, 2008-02-19
|
|
*/
|
|
BEGINAbstractObjClassInit(glbl, 1, OBJ_IS_CORE_MODULE) /* class, version */
|
|
/* request objects we use */
|
|
CHKiRet(objUse(prop, CORE_COMPONENT));
|
|
|
|
/* intialize properties */
|
|
storeLocalHostIPIF((uchar*)"127.0.0.1");
|
|
|
|
/* config handlers are never unregistered and need not be - we are always loaded ;) */
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"debugfile", 0, eCmdHdlrGetWord, setDebugFile, NULL, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"debuglevel", 0, eCmdHdlrInt, setDebugLevel, NULL, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"workdirectory", 0, eCmdHdlrGetWord, setWorkDir, NULL, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"dropmsgswithmaliciousdnsptrrecords", 0, eCmdHdlrBinary, SetDropMalPTRMsgs,
|
|
NULL, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdriver", 0, eCmdHdlrGetWord, setDfltNetstrmDrvr, NULL,
|
|
NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdrivercafile", 0, eCmdHdlrGetWord,
|
|
setDfltNetstrmDrvrCAF, NULL, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdriverkeyfile", 0, eCmdHdlrGetWord,
|
|
setDfltNetstrmDrvrKeyFile, NULL, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdrivercertfile", 0, eCmdHdlrGetWord,
|
|
setDfltNetstrmDrvrCertFile, NULL, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"localhostname", 0, eCmdHdlrGetWord, NULL, &LocalHostNameOverride, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"localhostipif", 0, eCmdHdlrGetWord, setLocalHostIPIF, NULL, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"netstreamdrivercaextrafiles", 0, eCmdHdlrGetWord, setNetstrmDrvrCAExtraFiles,
|
|
NULL, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"optimizeforuniprocessor", 0, eCmdHdlrGoneAway, NULL, NULL, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"preservefqdn", 0, eCmdHdlrBinary, NULL, &bPreserveFQDN, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"maxmessagesize", 0, eCmdHdlrSize, legacySetMaxMessageSize, NULL, NULL));
|
|
|
|
/* Deprecated parser config options */
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"controlcharacterescapeprefix", 0, eCmdHdlrGetChar,
|
|
setParserControlCharacterEscapePrefix, NULL, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"droptrailinglfonreception", 0, eCmdHdlrBinary,
|
|
setParserDropTrailingLFOnReception, NULL, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactersonreceive", 0, eCmdHdlrBinary,
|
|
setParserEscapeControlCharactersOnReceive, NULL, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"spacelfonreceive", 0, eCmdHdlrBinary,
|
|
setParserSpaceLFOnReceive, NULL, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"escape8bitcharactersonreceive", 0, eCmdHdlrBinary,
|
|
setParserEscape8BitCharactersOnReceive, NULL, NULL));
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactertab", 0, eCmdHdlrBinary,
|
|
setParserEscapeControlCharacterTab, NULL, NULL));
|
|
|
|
CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
|
|
resetConfigVariables, NULL, NULL));
|
|
|
|
INIT_ATOMIC_HELPER_MUT(mutTerminateInputs);
|
|
ENDObjClassInit(glbl)
|
|
|
|
|
|
/* Exit the glbl class.
|
|
* rgerhards, 2008-04-17
|
|
*/
|
|
BEGINObjClassExit(glbl, OBJ_IS_CORE_MODULE) /* class, version */
|
|
free(LocalDomain);
|
|
free(LocalHostName);
|
|
free(LocalHostNameOverride);
|
|
free(LocalFQDNName);
|
|
objRelease(prop, CORE_COMPONENT);
|
|
if(propLocalHostNameToDelete != NULL)
|
|
prop.Destruct(&propLocalHostNameToDelete);
|
|
DESTROY_ATOMIC_HELPER_MUT(mutTerminateInputs);
|
|
ENDObjClassExit(glbl)
|