1 /* glbl.c - this module holds global defintions and data items.
2 * These are shared among the runtime library. Their use should be
3 * limited to cases where it is actually needed. The main intension for
4 * implementing them was support for the transistion from v2 to v4
5 * (with fully modular design), but it turned out that there may also
6 * be some other good use cases besides backwards-compatibility.
7 *
8 * Module begun 2008-04-16 by Rainer Gerhards
9 *
10 * Copyright 2008-2021 Rainer Gerhards and Adiscon GmbH.
11 *
12 * This file is part of the rsyslog runtime library.
13 *
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
17 *
18 * http://www.apache.org/licenses/LICENSE-2.0
19 * -or-
20 * see COPYING.ASL20 in the source distribution
21 *
22 * Unless required by applicable law or agreed to in writing, software
23 * distributed under the License is distributed on an "AS IS" BASIS,
24 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 * See the License for the specific language governing permissions and
26 * limitations under the License.
27 */
28
29 #include "config.h"
30 #include <stdlib.h>
31 #include <sys/socket.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <sys/wait.h>
35 #include <fcntl.h>
36 #include <unistd.h>
37 #include <pthread.h>
38 #include <ctype.h>
39 #include <assert.h>
40 #include <stdint.h>
41 #include <errno.h>
42
43 #include "rsyslog.h"
44 #include "obj.h"
45 #include "unicode-helper.h"
46 #include "cfsysline.h"
47 #include "glbl.h"
48 #include "prop.h"
49 #include "atomic.h"
50 #include "errmsg.h"
51 #include "action.h"
52 #include "parserif.h"
53 #include "rainerscript.h"
54 #include "srUtils.h"
55 #include "operatingstate.h"
56 #include "net.h"
57 #include "rsconf.h"
58 #include "queue.h"
59 #include "dnscache.h"
60 #include "parser.h"
61
62 #define REPORT_CHILD_PROCESS_EXITS_NONE 0
63 #define REPORT_CHILD_PROCESS_EXITS_ERRORS 1
64 #define REPORT_CHILD_PROCESS_EXITS_ALL 2
65
66 /* some defaults */
67 #ifndef DFLT_NETSTRM_DRVR
68 # define DFLT_NETSTRM_DRVR ((uchar*)"ptcp")
69 #endif
70
71 /* static data */
72 DEFobjStaticHelpers
73 DEFobjCurrIf(prop)
74 DEFobjCurrIf(net)
75
76 /* static data
77 * For this object, these variables are obviously what makes the "meat" of the
78 * class...
79 */
80 int glblDebugOnShutdown = 0; /* start debug log when we are shut down */
81 #ifdef ENABLE_LIBLOGGING_STDLOG
82 stdlog_channel_t stdlog_hdl = NULL; /* handle to be used for stdlog */
83 #endif
84
85 static struct cnfobj *mainqCnfObj = NULL;/* main queue object, to be used later in startup sequence */
86 #ifndef DFLT_INT_MSGS_SEV_FILTER
87 #define DFLT_INT_MSGS_SEV_FILTER 6 /* Warning level and more important */
88 #endif
89 int glblIntMsgsSeverityFilter = DFLT_INT_MSGS_SEV_FILTER;/* filter for logging internal messages by syslog sev. */
90 int bProcessInternalMessages = 0; /* Should rsyslog itself process internal messages?
91 * 1 - yes
92 * 0 - send them to libstdlog (e.g. to push to journal) or syslog()
93 */
94 static uchar *pszWorkDir = NULL;
95 #ifdef ENABLE_LIBLOGGING_STDLOG
96 static uchar *stdlog_chanspec = NULL;
97 #endif
98 static int bParseHOSTNAMEandTAG = 1; /* parser modification (based on startup params!) */
99 static int bPreserveFQDN = 0; /* should FQDNs always be preserved? */
100 static int iMaxLine = 8096; /* maximum length of a syslog message */
101 static uchar * oversizeMsgErrorFile = NULL; /* File where oversize messages are written to */
102 static int oversizeMsgInputMode = 0; /* Mode which oversize messages will be forwarded */
103 static int reportOversizeMsg = 1; /* shall error messages be generated for oversize messages? */
104 static int reportChildProcessExits = REPORT_CHILD_PROCESS_EXITS_ERRORS;
105 static int iGnuTLSLoglevel = 0; /* Sets GNUTLS Debug Level */
106 static int iDefPFFamily = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both) */
107 static int bDropMalPTRMsgs = 0;/* Drop messages which have malicious PTR records during DNS lookup */
108 static int option_DisallowWarning = 1; /* complain if message from disallowed sender is received */
109 static int bDisableDNS = 0; /* don't look up IP addresses of remote messages */
110 static prop_t *propLocalIPIF = NULL;/* IP address to report for the local host (default is 127.0.0.1) */
111 static int propLocalIPIF_set = 0; /* is propLocalIPIF already set? */
112 static prop_t *propLocalHostName = NULL;/* our hostname as FQDN - read-only after startup */
113 static prop_t *propLocalHostNameToDelete = NULL;/* see GenerateLocalHostName function hdr comment! */
114 static uchar *LocalHostName = NULL;/* our hostname - read-only after startup, except HUP */
115 static uchar *LocalHostNameOverride = NULL;/* user-overridden hostname - read-only after startup */
116 static uchar *LocalFQDNName = NULL;/* our hostname as FQDN - read-only after startup, except HUP */
117 static uchar *LocalDomain = NULL;/* our local domain name - read-only after startup, except HUP */
118 static char **StripDomains = NULL;
119 /* these domains may be stripped before writing logs - r/o after s.u., never touched by init */
120 static char **LocalHosts = NULL;
121 /* these hosts are logged with their hostname - read-only after startup, never touched by init */
122 static uchar *pszDfltNetstrmDrvr = NULL; /* module name of default netstream driver */
123 static uchar *pszDfltNetstrmDrvrCAF = NULL; /* default CA file for the netstrm driver */
124 static uchar *pszDfltNetstrmDrvrKeyFile = NULL; /* default key file for the netstrm driver (server) */
125 static uchar *pszDfltNetstrmDrvrCertFile = NULL; /* default cert file for the netstrm driver (server) */
126 int bTerminateInputs = 0; /* global switch that inputs shall terminate ASAP (1=> terminate) */
127 static uchar cCCEscapeChar = '#'; /* character to be used to start an escape sequence for control chars */
128 static int bDropTrailingLF = 1; /* drop trailing LF's on reception? */
129 static int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - no, 1 - yes */
130 static int bSpaceLFOnRcv = 0; /* replace newlines with spaces on reception: 0 - no, 1 - yes */
131 static int bEscape8BitChars = 0; /* escape characters > 127 on reception: 0 - no, 1 - yes */
132 static int bEscapeTab = 1; /* escape tab control character when doing CC escapes: 0 - no, 1 - yes */
133 static int bParserEscapeCCCStyle = 0; /* escape control characters in c style: 0 - no, 1 - yes */
134 short janitorInterval = 10; /* interval (in minutes) at which the janitor runs */
135 int glblReportNewSenders = 0;
136 int glblReportGoneAwaySenders = 0;
137 int glblSenderStatsTimeout = 12 * 60 * 60; /* 12 hr timeout for senders */
138 int glblSenderKeepTrack = 0; /* keep track of known senders? */
139 int glblUnloadModules = 1;
140 int bPermitSlashInProgramname = 0;
141 int glblIntMsgRateLimitItv = 5;
142 int glblIntMsgRateLimitBurst = 500;
143 char** glblDbgFiles = NULL;
144 size_t glblDbgFilesNum = 0;
145 int glblDbgWhitelist = 1;
146 int glblPermitCtlC = 0;
147 int glblInputTimeoutShutdown = 1000; /* input shutdown timeout in ms */
148 int glblShutdownQueueDoubleSize = 0;
149 static const uchar * operatingStateFile = NULL;
150
151 uint64_t glblDevOptions = 0; /* to be used by developers only */
152
153 pid_t glbl_ourpid;
154 #ifndef HAVE_ATOMIC_BUILTINS
155 DEF_ATOMIC_HELPER_MUT(mutTerminateInputs);
156 #endif
157 #ifdef USE_UNLIMITED_SELECT
158 static int iFdSetSize = howmany(FD_SETSIZE, __NFDBITS) * sizeof (fd_mask); /* size of select() bitmask in bytes */
159 #endif
160 static uchar *SourceIPofLocalClient = NULL; /* [ar] Source IP for local client to be used on multihomed host */
161
162 tzinfo_t *tzinfos = NULL;
163 static int ntzinfos;
164
165 /* tables for interfacing with the v6 config system */
166 static struct cnfparamdescr cnfparamdescr[] = {
167 { "workdirectory", eCmdHdlrString, 0 },
168 { "operatingstatefile", eCmdHdlrString, 0 },
169 { "dropmsgswithmaliciousdnsptrrecords", eCmdHdlrBinary, 0 },
170 { "localhostname", eCmdHdlrGetWord, 0 },
171 { "preservefqdn", eCmdHdlrBinary, 0 },
172 { "debug.onshutdown", eCmdHdlrBinary, 0 },
173 { "debug.logfile", eCmdHdlrString, 0 },
174 { "debug.gnutls", eCmdHdlrNonNegInt, 0 },
175 { "debug.unloadmodules", eCmdHdlrBinary, 0 },
176 { "defaultnetstreamdrivercafile", eCmdHdlrString, 0 },
177 { "defaultnetstreamdriverkeyfile", eCmdHdlrString, 0 },
178 { "defaultnetstreamdrivercertfile", eCmdHdlrString, 0 },
179 { "defaultnetstreamdriver", eCmdHdlrString, 0 },
180 { "maxmessagesize", eCmdHdlrSize, 0 },
181 { "oversizemsg.errorfile", eCmdHdlrGetWord, 0 },
182 { "oversizemsg.report", eCmdHdlrBinary, 0 },
183 { "oversizemsg.input.mode", eCmdHdlrGetWord, 0 },
184 { "reportchildprocessexits", eCmdHdlrGetWord, 0 },
185 { "action.reportsuspension", eCmdHdlrBinary, 0 },
186 { "action.reportsuspensioncontinuation", eCmdHdlrBinary, 0 },
187 { "parser.controlcharacterescapeprefix", eCmdHdlrGetChar, 0 },
188 { "parser.droptrailinglfonreception", eCmdHdlrBinary, 0 },
189 { "parser.escapecontrolcharactersonreceive", eCmdHdlrBinary, 0 },
190 { "parser.spacelfonreceive", eCmdHdlrBinary, 0 },
191 { "parser.escape8bitcharactersonreceive", eCmdHdlrBinary, 0},
192 { "parser.escapecontrolcharactertab", eCmdHdlrBinary, 0},
193 { "parser.escapecontrolcharacterscstyle", eCmdHdlrBinary, 0 },
194 { "parser.parsehostnameandtag", eCmdHdlrBinary, 0 },
195 { "parser.permitslashinprogramname", eCmdHdlrBinary, 0 },
196 { "stdlog.channelspec", eCmdHdlrString, 0 },
197 { "janitor.interval", eCmdHdlrPositiveInt, 0 },
198 { "senders.reportnew", eCmdHdlrBinary, 0 },
199 { "senders.reportgoneaway", eCmdHdlrBinary, 0 },
200 { "senders.timeoutafter", eCmdHdlrPositiveInt, 0 },
201 { "senders.keeptrack", eCmdHdlrBinary, 0 },
202 { "inputs.timeout.shutdown", eCmdHdlrPositiveInt, 0 },
203 { "privdrop.group.keepsupplemental", eCmdHdlrBinary, 0 },
204 { "privdrop.group.id", eCmdHdlrPositiveInt, 0 },
205 { "privdrop.group.name", eCmdHdlrGID, 0 },
206 { "privdrop.user.id", eCmdHdlrPositiveInt, 0 },
207 { "privdrop.user.name", eCmdHdlrUID, 0 },
208 { "net.ipprotocol", eCmdHdlrGetWord, 0 },
209 { "net.acladdhostnameonfail", eCmdHdlrBinary, 0 },
210 { "net.aclresolvehostname", eCmdHdlrBinary, 0 },
211 { "net.enabledns", eCmdHdlrBinary, 0 },
212 { "net.permitACLwarning", eCmdHdlrBinary, 0 },
213 { "abortonuncleanconfig", eCmdHdlrBinary, 0 },
214 { "variables.casesensitive", eCmdHdlrBinary, 0 },
215 { "environment", eCmdHdlrArray, 0 },
216 { "processinternalmessages", eCmdHdlrBinary, 0 },
217 { "umask", eCmdHdlrFileCreateMode, 0 },
218 { "security.abortonidresolutionfail", eCmdHdlrBinary, 0 },
219 { "internal.developeronly.options", eCmdHdlrInt, 0 },
220 { "internalmsg.ratelimit.interval", eCmdHdlrPositiveInt, 0 },
221 { "internalmsg.ratelimit.burst", eCmdHdlrPositiveInt, 0 },
222 { "internalmsg.severity", eCmdHdlrSeverity, 0 },
223 { "errormessagestostderr.maxnumber", eCmdHdlrPositiveInt, 0 },
224 { "shutdown.enable.ctlc", eCmdHdlrBinary, 0 },
225 { "default.action.queue.timeoutshutdown", eCmdHdlrInt, 0 },
226 { "default.action.queue.timeoutactioncompletion", eCmdHdlrInt, 0 },
227 { "default.action.queue.timeoutenqueue", eCmdHdlrInt, 0 },
228 { "default.action.queue.timeoutworkerthreadshutdown", eCmdHdlrInt, 0 },
229 { "default.ruleset.queue.timeoutshutdown", eCmdHdlrInt, 0 },
230 { "default.ruleset.queue.timeoutactioncompletion", eCmdHdlrInt, 0 },
231 { "default.ruleset.queue.timeoutenqueue", eCmdHdlrInt, 0 },
232 { "default.ruleset.queue.timeoutworkerthreadshutdown", eCmdHdlrInt, 0 },
233 { "reverselookup.cache.ttl.default", eCmdHdlrNonNegInt, 0 },
234 { "reverselookup.cache.ttl.enable", eCmdHdlrBinary, 0 },
235 { "parser.supportcompressionextension", eCmdHdlrBinary, 0 },
236 { "shutdown.queue.doublesize", eCmdHdlrBinary, 0 },
237 { "debug.files", eCmdHdlrArray, 0 },
238 { "debug.whitelist", eCmdHdlrBinary, 0 }
239 };
240 static struct cnfparamblk paramblk =
241 { CNFPARAMBLK_VERSION,
242 sizeof(cnfparamdescr)/sizeof(struct cnfparamdescr),
243 cnfparamdescr
244 };
245
246 static struct cnfparamdescr timezonecnfparamdescr[] = {
247 { "id", eCmdHdlrString, CNFPARAM_REQUIRED},
248 { "offset", eCmdHdlrGetWord, CNFPARAM_REQUIRED }
249 };
250 static struct cnfparamblk timezonepblk =
251 { CNFPARAMBLK_VERSION,
252 sizeof(timezonecnfparamdescr)/sizeof(struct cnfparamdescr),
253 timezonecnfparamdescr
254 };
255
256 static struct cnfparamvals *cnfparamvals = NULL;
257 /* we need to support multiple calls into our param block, so we need
258 * to persist the current settings. Note that this must be re-set
259 * each time a new config load begins (TODO: create interface?)
260 */
261
262 int
glblGetMaxLine(void)263 glblGetMaxLine(void)
264 {
265 return(iMaxLine);
266 }
267
268
269 int
GetGnuTLSLoglevel(void)270 GetGnuTLSLoglevel(void)
271 {
272 return(iGnuTLSLoglevel);
273 }
274
275 /* define a macro for the simple properties' set and get functions
276 * (which are always the same). This is only suitable for pretty
277 * simple cases which require neither checks nor memory allocation.
278 */
279 #define SIMP_PROP(nameFunc, nameVar, dataType) \
280 SIMP_PROP_GET(nameFunc, nameVar, dataType) \
281 SIMP_PROP_SET(nameFunc, nameVar, dataType)
282 #define SIMP_PROP_SET(nameFunc, nameVar, dataType) \
283 static rsRetVal Set##nameFunc(dataType newVal) \
284 { \
285 nameVar = newVal; \
286 return RS_RET_OK; \
287 }
288 #define SIMP_PROP_GET(nameFunc, nameVar, dataType) \
289 static dataType Get##nameFunc(void) \
290 { \
291 return(nameVar); \
292 }
293
SIMP_PROP(PreserveFQDN,bPreserveFQDN,int)294 SIMP_PROP(PreserveFQDN, bPreserveFQDN, int)
295 SIMP_PROP(mainqCnfObj, mainqCnfObj, struct cnfobj *)
296 SIMP_PROP(DropMalPTRMsgs, bDropMalPTRMsgs, int)
297 SIMP_PROP(StripDomains, StripDomains, char**)
298 SIMP_PROP(LocalHosts, LocalHosts, char**)
299 SIMP_PROP(ParserControlCharacterEscapePrefix, cCCEscapeChar, uchar)
300 SIMP_PROP(ParserDropTrailingLFOnReception, bDropTrailingLF, int)
301 SIMP_PROP(ParserEscapeControlCharactersOnReceive, bEscapeCCOnRcv, int)
302 SIMP_PROP(ParserSpaceLFOnReceive, bSpaceLFOnRcv, int)
303 SIMP_PROP(ParserEscape8BitCharactersOnReceive, bEscape8BitChars, int)
304 SIMP_PROP(ParserEscapeControlCharacterTab, bEscapeTab, int)
305 SIMP_PROP(ParserEscapeControlCharactersCStyle, bParserEscapeCCCStyle, int)
306 #ifdef USE_UNLIMITED_SELECT
307 SIMP_PROP(FdSetSize, iFdSetSize, int)
308 #endif
309
310 SIMP_PROP_SET(DfltNetstrmDrvr, pszDfltNetstrmDrvr, uchar*) /* TODO: use custom function which frees existing value */
311 SIMP_PROP_SET(DfltNetstrmDrvrCAF, pszDfltNetstrmDrvrCAF, uchar*)
312 /* TODO: use custom function which frees existing value */
313 SIMP_PROP_SET(DfltNetstrmDrvrKeyFile, pszDfltNetstrmDrvrKeyFile, uchar*)
314 /* TODO: use custom function which frees existing value */
315 SIMP_PROP_SET(DfltNetstrmDrvrCertFile, pszDfltNetstrmDrvrCertFile, uchar*)
316 /* TODO: use custom function which frees existing value */
317
318 #undef SIMP_PROP
319 #undef SIMP_PROP_SET
320 #undef SIMP_PROP_GET
321
322
323 /* return global input termination status
324 * rgerhards, 2009-07-20
325 */
326 static int GetGlobalInputTermState(void)
327 {
328 return ATOMIC_FETCH_32BIT(&bTerminateInputs, &mutTerminateInputs);
329 }
330
331
332 /* set global termination state to "terminate". Note that this is a
333 * "once in a lifetime" action which can not be undone. -- gerhards, 2009-07-20
334 */
SetGlobalInputTermination(void)335 static void SetGlobalInputTermination(void)
336 {
337 ATOMIC_STORE_1_TO_INT(&bTerminateInputs, &mutTerminateInputs);
338 }
339
340
341 /* set the local host IP address to a specific string. Helper to
342 * small set of functions. No checks done, caller must ensure it is
343 * ok to call. Most importantly, the IP address must not already have
344 * been set. -- rgerhards, 2012-03-21
345 */
346 static rsRetVal
storeLocalHostIPIF(uchar * myIP)347 storeLocalHostIPIF(uchar *myIP)
348 {
349 DEFiRet;
350 if(propLocalIPIF != NULL) {
351 CHKiRet(prop.Destruct(&propLocalIPIF));
352 }
353 CHKiRet(prop.Construct(&propLocalIPIF));
354 CHKiRet(prop.SetString(propLocalIPIF, myIP, ustrlen(myIP)));
355 CHKiRet(prop.ConstructFinalize(propLocalIPIF));
356 DBGPRINTF("rsyslog/glbl: using '%s' as localhost IP\n", myIP);
357 finalize_it:
358 RETiRet;
359 }
360
361
362 /* This function is used to set the IP address that is to be
363 * reported for the local host. Note that in order to ease things
364 * for the v6 config interface, we do not allow to set this more
365 * than once.
366 * rgerhards, 2012-03-21
367 */
368 static rsRetVal
setLocalHostIPIF(void * pVal,uchar * pNewVal)369 setLocalHostIPIF(void __attribute__((unused)) *pVal, uchar *pNewVal)
370 {
371 uchar myIP[128];
372 rsRetVal localRet;
373 DEFiRet;
374
375 CHKiRet(objUse(net, CORE_COMPONENT));
376
377 if(propLocalIPIF_set) {
378 LogError(0, RS_RET_ERR, "$LocalHostIPIF is already set "
379 "and cannot be reset; place it at TOP OF rsyslog.conf!");
380 ABORT_FINALIZE(RS_RET_ERR);
381 }
382
383 localRet = net.GetIFIPAddr(pNewVal, AF_UNSPEC, myIP, (int) sizeof(myIP));
384 if(localRet != RS_RET_OK) {
385 LogError(0, RS_RET_ERR, "$LocalHostIPIF: IP address for interface "
386 "'%s' cannnot be obtained - ignoring directive", pNewVal);
387 } else {
388 storeLocalHostIPIF(myIP);
389 }
390
391
392 finalize_it:
393 free(pNewVal); /* no longer needed -> is in prop! */
394 RETiRet;
395 }
396
397
398 /* This function is used to set the global work directory name.
399 * It verifies that the provided directory actually exists and
400 * emits an error message if not.
401 * rgerhards, 2011-02-16
402 */
setWorkDir(void * pVal,uchar * pNewVal)403 static rsRetVal setWorkDir(void __attribute__((unused)) *pVal, uchar *pNewVal)
404 {
405 size_t lenDir;
406 int i;
407 struct stat sb;
408 DEFiRet;
409
410 /* remove trailing slashes */
411 lenDir = ustrlen(pNewVal);
412 i = lenDir - 1;
413 while(i > 0 && pNewVal[i] == '/') {
414 --i;
415 }
416
417 if(i < 0) {
418 LogError(0, RS_RET_ERR_WRKDIR, "$WorkDirectory: empty value "
419 "- directive ignored");
420 ABORT_FINALIZE(RS_RET_ERR_WRKDIR);
421 }
422
423 if(i != (int) lenDir - 1) {
424 pNewVal[i+1] = '\0';
425 LogError(0, RS_RET_WRN_WRKDIR, "$WorkDirectory: trailing slashes "
426 "removed, new value is '%s'", pNewVal);
427 }
428
429 if(stat((char*) pNewVal, &sb) != 0) {
430 LogError(0, RS_RET_ERR_WRKDIR, "$WorkDirectory: %s can not be "
431 "accessed, probably does not exist - directive ignored", pNewVal);
432 ABORT_FINALIZE(RS_RET_ERR_WRKDIR);
433 }
434
435 if(!S_ISDIR(sb.st_mode)) {
436 LogError(0, RS_RET_ERR_WRKDIR, "$WorkDirectory: %s not a directory - directive ignored",
437 pNewVal);
438 ABORT_FINALIZE(RS_RET_ERR_WRKDIR);
439 }
440
441 free(pszWorkDir);
442 pszWorkDir = pNewVal;
443
444 finalize_it:
445 RETiRet;
446 }
447
448
449 /* This function is used both by legacy and RainerScript conf. It is a real setter. */
450 static void
setMaxLine(const int64_t iNew)451 setMaxLine(const int64_t iNew)
452 {
453 if(iNew < 128) {
454 LogError(0, RS_RET_INVALID_VALUE, "maxMessageSize tried to set "
455 "to %lld, but cannot be less than 128 - set to 128 "
456 "instead", (long long) iNew);
457 iMaxLine = 128;
458 } else if(iNew > (int64_t) INT_MAX) {
459 LogError(0, RS_RET_INVALID_VALUE, "maxMessageSize larger than "
460 "INT_MAX (%d) - reduced to INT_MAX", INT_MAX);
461 iMaxLine = INT_MAX;
462 } else {
463 iMaxLine = (int) iNew;
464 }
465 }
466
467
468
469 static rsRetVal
legacySetMaxMessageSize(void * pVal,int64_t iNew)470 legacySetMaxMessageSize(void __attribute__((unused)) *pVal, int64_t iNew)
471 {
472 setMaxLine(iNew);
473 return RS_RET_OK;
474 }
475
476 static rsRetVal
setDebugFile(void * pVal,uchar * pNewVal)477 setDebugFile(void __attribute__((unused)) *pVal, uchar *pNewVal)
478 {
479 DEFiRet;
480 dbgSetDebugFile(pNewVal);
481 free(pNewVal);
482 RETiRet;
483 }
484
485 static rsRetVal
setDebugLevel(void * pVal,int level)486 setDebugLevel(void __attribute__((unused)) *pVal, int level)
487 {
488 DEFiRet;
489 dbgSetDebugLevel(level);
490 dbgprintf("debug level %d set via config file\n", level);
491 dbgprintf("This is rsyslog version " VERSION "\n");
492 RETiRet;
493 }
494
ATTR_NONNULL()495 static rsRetVal ATTR_NONNULL()
496 setOversizeMsgInputMode(const uchar *const mode)
497 {
498 DEFiRet;
499 if(!strcmp((char*)mode, "truncate")) {
500 oversizeMsgInputMode = glblOversizeMsgInputMode_Truncate;
501 } else if(!strcmp((char*)mode, "split")) {
502 oversizeMsgInputMode = glblOversizeMsgInputMode_Split;
503 } else if(!strcmp((char*)mode, "accept")) {
504 oversizeMsgInputMode = glblOversizeMsgInputMode_Accept;
505 } else {
506 oversizeMsgInputMode = glblOversizeMsgInputMode_Truncate;
507 }
508 RETiRet;
509 }
510
ATTR_NONNULL()511 static rsRetVal ATTR_NONNULL()
512 setReportChildProcessExits(const uchar *const mode)
513 {
514 DEFiRet;
515 if(!strcmp((char*)mode, "none")) {
516 reportChildProcessExits = REPORT_CHILD_PROCESS_EXITS_NONE;
517 } else if(!strcmp((char*)mode, "errors")) {
518 reportChildProcessExits = REPORT_CHILD_PROCESS_EXITS_ERRORS;
519 } else if(!strcmp((char*)mode, "all")) {
520 reportChildProcessExits = REPORT_CHILD_PROCESS_EXITS_ALL;
521 } else {
522 LogError(0, RS_RET_CONF_PARAM_INVLD,
523 "invalid value '%s' for global parameter reportChildProcessExits -- ignored",
524 mode);
525 iRet = RS_RET_CONF_PARAM_INVLD;
526 }
527 RETiRet;
528 }
529
530 static rsRetVal
setDisableDNS(int val)531 setDisableDNS(int val)
532 {
533 bDisableDNS = val;
534 return RS_RET_OK;
535 }
536
537 static int
getDisableDNS(void)538 getDisableDNS(void)
539 {
540 return bDisableDNS;
541 }
542
543 static rsRetVal
setOption_DisallowWarning(int val)544 setOption_DisallowWarning(int val)
545 {
546 option_DisallowWarning = val;
547 return RS_RET_OK;
548 }
549
550 static int
getOption_DisallowWarning(void)551 getOption_DisallowWarning(void)
552 {
553 return option_DisallowWarning;
554 }
555
556 static rsRetVal
setParseHOSTNAMEandTAG(int val)557 setParseHOSTNAMEandTAG(int val)
558 {
559 bParseHOSTNAMEandTAG = val;
560 return RS_RET_OK;
561 }
562
563 static int
getParseHOSTNAMEandTAG(void)564 getParseHOSTNAMEandTAG(void)
565 {
566 return bParseHOSTNAMEandTAG;
567 }
568
569 static rsRetVal
setDefPFFamily(int level)570 setDefPFFamily(int level)
571 {
572 DEFiRet;
573 iDefPFFamily = level;
574 RETiRet;
575 }
576
577 static int
getDefPFFamily(void)578 getDefPFFamily(void)
579 {
580 return iDefPFFamily;
581 }
582
583 /* return our local IP.
584 * If no local IP is set, "127.0.0.1" is selected *and* set. This
585 * is an intensional side effect that we do in order to keep things
586 * consistent and avoid config errors (this will make us not accept
587 * setting the local IP address once a module has obtained it - so
588 * it forces the $LocalHostIPIF directive high up in rsyslog.conf)
589 * rgerhards, 2012-03-21
590 */
591 static prop_t*
GetLocalHostIP(void)592 GetLocalHostIP(void)
593 {
594 assert(propLocalIPIF != NULL);
595 return(propLocalIPIF);
596 }
597
598
599 /* set our local hostname. Free previous hostname, if it was already set.
600 * Note that we do now do this in a thread. As such, the method here
601 * is NOT 100% clean. If we run into issues, we need to think about
602 * refactoring the whole way we handle the local host name processing.
603 * Possibly using a PROP might be the right solution then.
604 */
605 static rsRetVal
SetLocalHostName(uchar * const newname)606 SetLocalHostName(uchar *const newname)
607 {
608 uchar *toFree;
609 if(LocalHostName == NULL || strcmp((const char*)LocalHostName, (const char*) newname)) {
610 toFree = LocalHostName;
611 LocalHostName = newname;
612 } else {
613 toFree = newname;
614 }
615 free(toFree);
616 return RS_RET_OK;
617 }
618
619
620 /* return our local hostname. if it is not set, "[localhost]" is returned
621 */
622 static uchar*
GetLocalHostName(void)623 GetLocalHostName(void)
624 {
625 uchar *pszRet;
626
627 if(LocalHostNameOverride != NULL) {
628 pszRet = LocalHostNameOverride;
629 goto done;
630 }
631
632 if(LocalHostName == NULL)
633 pszRet = (uchar*) "[localhost]";
634 else {
635 if(GetPreserveFQDN() == 1)
636 pszRet = LocalFQDNName;
637 else
638 pszRet = LocalHostName;
639 }
640 done:
641 return(pszRet);
642 }
643
644
645 /* return the name of the file where oversize messages are written to
646 */
647 uchar*
glblGetOversizeMsgErrorFile(void)648 glblGetOversizeMsgErrorFile(void)
649 {
650 return oversizeMsgErrorFile;
651 }
652
653 const uchar*
glblGetOperatingStateFile(void)654 glblGetOperatingStateFile(void)
655 {
656 return operatingStateFile;
657 }
658
659 /* return the mode with which oversize messages will be put forward
660 */
661 int
glblGetOversizeMsgInputMode(void)662 glblGetOversizeMsgInputMode(void)
663 {
664 return oversizeMsgInputMode;
665 }
666
667 int
glblReportOversizeMessage(void)668 glblReportOversizeMessage(void)
669 {
670 return reportOversizeMsg;
671 }
672
673
674 /* logs a message indicating that a child process has terminated.
675 * If name != NULL, prints it as the program name.
676 */
677 void
glblReportChildProcessExit(const uchar * name,pid_t pid,int status)678 glblReportChildProcessExit(const uchar *name, pid_t pid, int status)
679 {
680 DBGPRINTF("waitpid for child %ld returned status: %2.2x\n", (long) pid, status);
681
682 if(reportChildProcessExits == REPORT_CHILD_PROCESS_EXITS_NONE
683 || (reportChildProcessExits == REPORT_CHILD_PROCESS_EXITS_ERRORS
684 && WIFEXITED(status) && WEXITSTATUS(status) == 0)) {
685 return;
686 }
687
688 if(WIFEXITED(status)) {
689 int severity = WEXITSTATUS(status) == 0 ? LOG_INFO : LOG_WARNING;
690 if(name != NULL) {
691 LogMsg(0, NO_ERRCODE, severity, "program '%s' (pid %ld) exited with status %d",
692 name, (long) pid, WEXITSTATUS(status));
693 } else {
694 LogMsg(0, NO_ERRCODE, severity, "child process (pid %ld) exited with status %d",
695 (long) pid, WEXITSTATUS(status));
696 }
697 } else if(WIFSIGNALED(status)) {
698 if(name != NULL) {
699 LogMsg(0, NO_ERRCODE, LOG_WARNING, "program '%s' (pid %ld) terminated by signal %d",
700 name, (long) pid, WTERMSIG(status));
701 } else {
702 LogMsg(0, NO_ERRCODE, LOG_WARNING, "child process (pid %ld) terminated by signal %d",
703 (long) pid, WTERMSIG(status));
704 }
705 }
706 }
707
708
709 /* set our local domain name. Free previous domain, if it was already set.
710 */
711 static rsRetVal
SetLocalDomain(uchar * newname)712 SetLocalDomain(uchar *newname)
713 {
714 free(LocalDomain);
715 LocalDomain = newname;
716 return RS_RET_OK;
717 }
718
719
720 /* return our local hostname. if it is not set, "[localhost]" is returned
721 */
722 static uchar*
GetLocalDomain(void)723 GetLocalDomain(void)
724 {
725 return LocalDomain;
726 }
727
728
729 /* generate the local hostname property. This must be done after the hostname info
730 * has been set as well as PreserveFQDN.
731 * rgerhards, 2009-06-30
732 * NOTE: This function tries to avoid locking by not destructing the previous value
733 * immediately. This is so that current readers can continue to use the previous name.
734 * Otherwise, we would need to use read/write locks to protect the update process.
735 * In order to do so, we save the previous value and delete it when we are called again
736 * the next time. Note that this in theory is racy and can lead to a double-free.
737 * In practice, however, the window of exposure to trigger this is extremely short
738 * and as this functions is very infrequently being called (on HUP), the trigger
739 * condition for this bug is so highly unlikely that it never occurs in practice.
740 * Probably if you HUP rsyslog every few milliseconds, but who does that...
741 * To further reduce risk potential, we do only update the property when there
742 * actually is a hostname change, which makes it even less likely.
743 * rgerhards, 2013-10-28
744 */
745 static rsRetVal
GenerateLocalHostNameProperty(void)746 GenerateLocalHostNameProperty(void)
747 {
748 uchar *pszPrev;
749 int lenPrev;
750 prop_t *hostnameNew;
751 uchar *pszName;
752 DEFiRet;
753
754 if(propLocalHostNameToDelete != NULL)
755 prop.Destruct(&propLocalHostNameToDelete);
756
757 if(LocalHostNameOverride == NULL) {
758 if(LocalHostName == NULL)
759 pszName = (uchar*) "[localhost]";
760 else {
761 if(GetPreserveFQDN() == 1)
762 pszName = LocalFQDNName;
763 else
764 pszName = LocalHostName;
765 }
766 } else { /* local hostname is overriden via config */
767 pszName = LocalHostNameOverride;
768 }
769 DBGPRINTF("GenerateLocalHostName uses '%s'\n", pszName);
770
771 if(propLocalHostName == NULL)
772 pszPrev = (uchar*)""; /* make sure strcmp() below does not match */
773 else
774 prop.GetString(propLocalHostName, &pszPrev, &lenPrev);
775
776 if(ustrcmp(pszPrev, pszName)) {
777 /* we need to update */
778 CHKiRet(prop.Construct(&hostnameNew));
779 CHKiRet(prop.SetString(hostnameNew, pszName, ustrlen(pszName)));
780 CHKiRet(prop.ConstructFinalize(hostnameNew));
781 propLocalHostNameToDelete = propLocalHostName;
782 propLocalHostName = hostnameNew;
783 }
784
785 finalize_it:
786 RETiRet;
787 }
788
789
790 /* return our local hostname as a string property
791 */
792 static prop_t*
GetLocalHostNameProp(void)793 GetLocalHostNameProp(void)
794 {
795 return(propLocalHostName);
796 }
797
798
799 static rsRetVal
SetLocalFQDNName(uchar * newname)800 SetLocalFQDNName(uchar *newname)
801 {
802 free(LocalFQDNName);
803 LocalFQDNName = newname;
804 return RS_RET_OK;
805 }
806
807 /* return the current localhost name as FQDN (requires FQDN to be set)
808 * TODO: we should set the FQDN ourselfs in here!
809 */
810 static uchar*
GetLocalFQDNName(void)811 GetLocalFQDNName(void)
812 {
813 return(LocalFQDNName == NULL ? (uchar*) "[localhost]" : LocalFQDNName);
814 }
815
816
817 /* return the current working directory */
818 static uchar*
GetWorkDir(void)819 GetWorkDir(void)
820 {
821 return(pszWorkDir == NULL ? (uchar*) "" : pszWorkDir);
822 }
823
824 /* return the "raw" working directory, which means
825 * NULL if unset.
826 */
827 const uchar *
glblGetWorkDirRaw(void)828 glblGetWorkDirRaw(void)
829 {
830 return pszWorkDir;
831 }
832
833 /* return the current default netstream driver */
834 static uchar*
GetDfltNetstrmDrvr(void)835 GetDfltNetstrmDrvr(void)
836 {
837 return(pszDfltNetstrmDrvr == NULL ? DFLT_NETSTRM_DRVR : pszDfltNetstrmDrvr);
838 }
839
840
841 /* return the current default netstream driver CA File */
842 static uchar*
GetDfltNetstrmDrvrCAF(void)843 GetDfltNetstrmDrvrCAF(void)
844 {
845 return(pszDfltNetstrmDrvrCAF);
846 }
847
848
849 /* return the current default netstream driver key File */
850 static uchar*
GetDfltNetstrmDrvrKeyFile(void)851 GetDfltNetstrmDrvrKeyFile(void)
852 {
853 return(pszDfltNetstrmDrvrKeyFile);
854 }
855
856
857 /* return the current default netstream driver certificate File */
858 static uchar*
GetDfltNetstrmDrvrCertFile(void)859 GetDfltNetstrmDrvrCertFile(void)
860 {
861 return(pszDfltNetstrmDrvrCertFile);
862 }
863
864
865 /* [ar] Source IP for local client to be used on multihomed host */
866 static rsRetVal
SetSourceIPofLocalClient(uchar * newname)867 SetSourceIPofLocalClient(uchar *newname)
868 {
869 if(SourceIPofLocalClient != NULL) {
870 free(SourceIPofLocalClient); }
871 SourceIPofLocalClient = newname;
872 return RS_RET_OK;
873 }
874
875 static uchar*
GetSourceIPofLocalClient(void)876 GetSourceIPofLocalClient(void)
877 {
878 return(SourceIPofLocalClient);
879 }
880
881
882 /* queryInterface function
883 * rgerhards, 2008-02-21
884 */
885 BEGINobjQueryInterface(glbl)
886 CODESTARTobjQueryInterface(glbl)
887 if(pIf->ifVersion != glblCURR_IF_VERSION) { /* check for current version, increment on each change */
888 ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED);
889 }
890
891 /* ok, we have the right interface, so let's fill it
892 * Please note that we may also do some backwards-compatibility
893 * work here (if we can support an older interface version - that,
894 * of course, also affects the "if" above).
895 */
896 pIf->GetWorkDir = GetWorkDir;
897 pIf->GenerateLocalHostNameProperty = GenerateLocalHostNameProperty;
898 pIf->GetLocalHostNameProp = GetLocalHostNameProp;
899 pIf->GetLocalHostIP = GetLocalHostIP;
900 pIf->SetGlobalInputTermination = SetGlobalInputTermination;
901 pIf->GetGlobalInputTermState = GetGlobalInputTermState;
902 pIf->GetSourceIPofLocalClient = GetSourceIPofLocalClient; /* [ar] */
903 pIf->SetSourceIPofLocalClient = SetSourceIPofLocalClient; /* [ar] */
904 pIf->SetDefPFFamily = setDefPFFamily;
905 pIf->GetDefPFFamily = getDefPFFamily;
906 pIf->SetDisableDNS = setDisableDNS;
907 pIf->GetDisableDNS = getDisableDNS;
908 pIf->GetMaxLine = glblGetMaxLine;
909 pIf->SetOption_DisallowWarning = setOption_DisallowWarning;
910 pIf->GetOption_DisallowWarning = getOption_DisallowWarning;
911 pIf->SetParseHOSTNAMEandTAG = setParseHOSTNAMEandTAG;
912 pIf->GetParseHOSTNAMEandTAG = getParseHOSTNAMEandTAG;
913 #define SIMP_PROP(name) \
914 pIf->Get##name = Get##name; \
915 pIf->Set##name = Set##name;
916 SIMP_PROP(PreserveFQDN);
917 SIMP_PROP(DropMalPTRMsgs);
918 SIMP_PROP(mainqCnfObj);
919 SIMP_PROP(LocalFQDNName)
SIMP_PROP(LocalHostName)920 SIMP_PROP(LocalHostName)
921 SIMP_PROP(LocalDomain)
922 SIMP_PROP(StripDomains)
923 SIMP_PROP(LocalHosts)
924 SIMP_PROP(ParserControlCharacterEscapePrefix)
925 SIMP_PROP(ParserDropTrailingLFOnReception)
926 SIMP_PROP(ParserEscapeControlCharactersOnReceive)
927 SIMP_PROP(ParserSpaceLFOnReceive)
928 SIMP_PROP(ParserEscape8BitCharactersOnReceive)
929 SIMP_PROP(ParserEscapeControlCharacterTab)
930 SIMP_PROP(ParserEscapeControlCharactersCStyle)
931 SIMP_PROP(DfltNetstrmDrvr)
932 SIMP_PROP(DfltNetstrmDrvrCAF)
933 SIMP_PROP(DfltNetstrmDrvrKeyFile)
934 SIMP_PROP(DfltNetstrmDrvrCertFile)
935 #ifdef USE_UNLIMITED_SELECT
936 SIMP_PROP(FdSetSize)
937 #endif
938 #undef SIMP_PROP
939 finalize_it:
940 ENDobjQueryInterface(glbl)
941
942 /* Reset config variables to default values.
943 * rgerhards, 2008-04-17
944 */
945 static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
946 {
947 free(pszDfltNetstrmDrvr);
948 pszDfltNetstrmDrvr = NULL;
949 free(pszDfltNetstrmDrvrCAF);
950 pszDfltNetstrmDrvrCAF = NULL;
951 free(pszDfltNetstrmDrvrKeyFile);
952 pszDfltNetstrmDrvrKeyFile = NULL;
953 free(pszDfltNetstrmDrvrCertFile);
954 pszDfltNetstrmDrvrCertFile = NULL;
955 free(LocalHostNameOverride);
956 LocalHostNameOverride = NULL;
957 free(oversizeMsgErrorFile);
958 oversizeMsgErrorFile = NULL;
959 oversizeMsgInputMode = glblOversizeMsgInputMode_Accept;
960 reportChildProcessExits = REPORT_CHILD_PROCESS_EXITS_ERRORS;
961 free(pszWorkDir);
962 pszWorkDir = NULL;
963 free((void*)operatingStateFile);
964 operatingStateFile = NULL;
965 bDropMalPTRMsgs = 0;
966 bPreserveFQDN = 0;
967 iMaxLine = 8192;
968 cCCEscapeChar = '#';
969 bDropTrailingLF = 1;
970 reportOversizeMsg = 1;
971 bEscapeCCOnRcv = 1; /* default is to escape control characters */
972 bSpaceLFOnRcv = 0;
973 bEscape8BitChars = 0; /* default is not to escape control characters */
974 bEscapeTab = 1; /* default is to escape tab characters */
975 bParserEscapeCCCStyle = 0;
976 #ifdef USE_UNLIMITED_SELECT
977 iFdSetSize = howmany(FD_SETSIZE, __NFDBITS) * sizeof (fd_mask);
978 #endif
979 return RS_RET_OK;
980 }
981
982
983 /* Prepare for new config
984 */
985 void
glblPrepCnf(void)986 glblPrepCnf(void)
987 {
988 free(mainqCnfObj);
989 mainqCnfObj = NULL;
990 free(cnfparamvals);
991 cnfparamvals = NULL;
992 }
993
994
995 static void
freeTimezoneInfo(void)996 freeTimezoneInfo(void)
997 {
998 int i;
999 for(i = 0 ; i < ntzinfos ; ++i)
1000 free(tzinfos[i].id);
1001 free(tzinfos);
1002 tzinfos = NULL;
1003 }
1004
1005 static void
displayTzinfos(void)1006 displayTzinfos(void)
1007 {
1008 int i;
1009 if(!Debug)
1010 return;
1011 for(i = 0 ; i < ntzinfos ; ++i)
1012 dbgprintf("tzinfo: '%s':%c%2.2d:%2.2d\n",
1013 tzinfos[i].id, tzinfos[i].offsMode,
1014 tzinfos[i].offsHour, tzinfos[i].offsMin);
1015 }
1016
1017
1018 /* Note: this function is NOT thread-safe!
1019 * This is currently not needed as used only during
1020 * initialization.
1021 */
1022 static rsRetVal
addTimezoneInfo(uchar * tzid,char offsMode,int8_t offsHour,int8_t offsMin)1023 addTimezoneInfo(uchar *tzid, char offsMode, int8_t offsHour, int8_t offsMin)
1024 {
1025 DEFiRet;
1026 tzinfo_t *newti;
1027 CHKmalloc(newti = realloc(tzinfos, (ntzinfos+1)*sizeof(tzinfo_t)));
1028 if((newti[ntzinfos].id = strdup((char*)tzid)) == NULL) {
1029 free(newti);
1030 DBGPRINTF("addTimezoneInfo: strdup failed with OOM\n");
1031 ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
1032 }
1033 newti[ntzinfos].offsMode = offsMode;
1034 newti[ntzinfos].offsHour = offsHour;
1035 newti[ntzinfos].offsMin = offsMin;
1036 ++ntzinfos, tzinfos = newti;
1037 finalize_it:
1038 RETiRet;
1039 }
1040
1041
1042 static int
bs_arrcmp_tzinfo(const void * s1,const void * s2)1043 bs_arrcmp_tzinfo(const void *s1, const void *s2)
1044 {
1045 return strcmp((char*)s1, (char*)((tzinfo_t*)s2)->id);
1046 }
1047 /* returns matching timezone info or NULL if no entry exists */
1048 tzinfo_t*
glblFindTimezoneInfo(char * id)1049 glblFindTimezoneInfo(char *id)
1050 {
1051 return (tzinfo_t*) bsearch(id, tzinfos, ntzinfos, sizeof(tzinfo_t), bs_arrcmp_tzinfo);
1052 }
1053
1054 /* handle the timezone() object. Each incarnation adds one additional
1055 * zone info to the global table of time zones.
1056 */
1057
1058 int
bs_arrcmp_glblDbgFiles(const void * s1,const void * s2)1059 bs_arrcmp_glblDbgFiles(const void *s1, const void *s2)
1060 {
1061 return strcmp((char*)s1, *(char**)s2);
1062 }
1063
1064 void
glblProcessTimezone(struct cnfobj * o)1065 glblProcessTimezone(struct cnfobj *o)
1066 {
1067 struct cnfparamvals *pvals;
1068 uchar *id = NULL;
1069 uchar *offset = NULL;
1070 char offsMode;
1071 int8_t offsHour;
1072 int8_t offsMin;
1073 int i;
1074
1075 pvals = nvlstGetParams(o->nvlst, &timezonepblk, NULL);
1076 if(pvals == NULL) {
1077 LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing timezone "
1078 "config parameters");
1079 goto done;
1080 }
1081 if(Debug) {
1082 dbgprintf("timezone param blk after glblProcessTimezone:\n");
1083 cnfparamsPrint(&timezonepblk, pvals);
1084 }
1085
1086 for(i = 0 ; i < timezonepblk.nParams ; ++i) {
1087 if(!pvals[i].bUsed)
1088 continue;
1089 if(!strcmp(timezonepblk.descr[i].name, "id")) {
1090 id = (uchar*) es_str2cstr(pvals[i].val.d.estr, NULL);
1091 } else if(!strcmp(timezonepblk.descr[i].name, "offset")) {
1092 offset = (uchar*) es_str2cstr(pvals[i].val.d.estr, NULL);
1093 } else {
1094 dbgprintf("glblProcessTimezone: program error, non-handled "
1095 "param '%s'\n", timezonepblk.descr[i].name);
1096 }
1097 }
1098
1099 /* note: the following two checks for NULL are not strictly necessary
1100 * as these are required parameters for the config block. But we keep
1101 * them to make the clang static analyzer happy, which also helps
1102 * guard against logic errors.
1103 */
1104 if(offset == NULL) {
1105 parser_errmsg("offset parameter missing (logic error?), timezone config ignored");
1106 goto done;
1107 }
1108 if(id == NULL) {
1109 parser_errmsg("id parameter missing (logic error?), timezone config ignored");
1110 goto done;
1111 }
1112
1113 if( strlen((char*)offset) != 6
1114 || !(offset[0] == '-' || offset[0] == '+')
1115 || !(isdigit(offset[1]) && isdigit(offset[2]))
1116 || offset[3] != ':'
1117 || !(isdigit(offset[4]) && isdigit(offset[5]))
1118 ) {
1119 parser_errmsg("timezone offset has invalid format. Must be +/-hh:mm, e.g. \"-07:00\".");
1120 goto done;
1121 }
1122
1123 offsHour = (offset[1] - '0') * 10 + offset[2] - '0';
1124 offsMin = (offset[4] - '0') * 10 + offset[5] - '0';
1125 offsMode = offset[0];
1126
1127 if(offsHour > 12 || offsMin > 59) {
1128 parser_errmsg("timezone offset outside of supported range (hours 0..12, minutes 0..59)");
1129 goto done;
1130 }
1131
1132 addTimezoneInfo(id, offsMode, offsHour, offsMin);
1133
1134 done:
1135 cnfparamvalsDestruct(pvals, &timezonepblk);
1136 free(id);
1137 free(offset);
1138 }
1139
1140 /* handle a global config object. Note that multiple global config statements
1141 * are permitted (because of plugin support), so once we got a param block,
1142 * we need to hold to it.
1143 * rgerhards, 2011-07-19
1144 */
1145 void
glblProcessCnf(struct cnfobj * o)1146 glblProcessCnf(struct cnfobj *o)
1147 {
1148 int i;
1149
1150 cnfparamvals = nvlstGetParams(o->nvlst, ¶mblk, cnfparamvals);
1151 if(cnfparamvals == NULL) {
1152 LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing global "
1153 "config parameters [global(...)]");
1154 goto done;
1155 }
1156 if(Debug) {
1157 dbgprintf("glbl param blk after glblProcessCnf:\n");
1158 cnfparamsPrint(¶mblk, cnfparamvals);
1159 }
1160
1161 /* The next thing is a bit hackish and should be changed in higher
1162 * versions. There are a select few parameters which we need to
1163 * act on immediately. These are processed here.
1164 */
1165 for(i = 0 ; i < paramblk.nParams ; ++i) {
1166 if(!cnfparamvals[i].bUsed)
1167 continue;
1168 if(!strcmp(paramblk.descr[i].name, "processinternalmessages")) {
1169 bProcessInternalMessages = (int) cnfparamvals[i].val.d.n;
1170 cnfparamvals[i].bUsed = TRUE;
1171 } else if(!strcmp(paramblk.descr[i].name, "internal.developeronly.options")) {
1172 glblDevOptions = (uint64_t) cnfparamvals[i].val.d.n;
1173 cnfparamvals[i].bUsed = TRUE;
1174 } else if(!strcmp(paramblk.descr[i].name, "stdlog.channelspec")) {
1175 #ifndef ENABLE_LIBLOGGING_STDLOG
1176 LogError(0, RS_RET_ERR, "rsyslog wasn't "
1177 "compiled with liblogging-stdlog support. "
1178 "The 'stdlog.channelspec' parameter "
1179 "is ignored. Note: the syslog API is used instead.\n");
1180 #else
1181 stdlog_chanspec = (uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
1182 /* we need to re-open with the new channel */
1183 stdlog_close(stdlog_hdl);
1184 stdlog_hdl = stdlog_open("rsyslogd", 0, STDLOG_SYSLOG,
1185 (char*) stdlog_chanspec);
1186 cnfparamvals[i].bUsed = TRUE;
1187 #endif
1188 } else if(!strcmp(paramblk.descr[i].name, "operatingstatefile")) {
1189 if(operatingStateFile != NULL) {
1190 LogError(errno, RS_RET_PARAM_ERROR,
1191 "error: operatingStateFile already set to '%s' - "
1192 "new value ignored", operatingStateFile);
1193 } else {
1194 operatingStateFile = (uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
1195 osf_open();
1196 }
1197 } else if(!strcmp(paramblk.descr[i].name, "security.abortonidresolutionfail")) {
1198 loadConf->globals.abortOnIDResolutionFail = (int) cnfparamvals[i].val.d.n;
1199 cnfparamvals[i].bUsed = TRUE;
1200 }
1201 }
1202 done: return;
1203 }
1204
1205 /* Set mainq parameters. Note that when this is not called, we'll use the
1206 * legacy parameter config. mainq parameters can only be set once.
1207 */
1208 void
glblProcessMainQCnf(struct cnfobj * o)1209 glblProcessMainQCnf(struct cnfobj *o)
1210 {
1211 if(mainqCnfObj == NULL) {
1212 mainqCnfObj = o;
1213 } else {
1214 LogError(0, RS_RET_ERR, "main_queue() object can only be specified "
1215 "once - all but first ignored\n");
1216 }
1217 }
1218
1219 /* destruct the main q cnf object after it is no longer needed. This is
1220 * also used to do some final checks.
1221 */
1222 void
glblDestructMainqCnfObj(void)1223 glblDestructMainqCnfObj(void)
1224 {
1225 /* Only destruct if not NULL! */
1226 if (mainqCnfObj != NULL) {
1227 nvlstChkUnused(mainqCnfObj->nvlst);
1228 cnfobjDestruct(mainqCnfObj);
1229 mainqCnfObj = NULL;
1230 }
1231 }
1232
1233 /* comparison function for qsort() and string array compare
1234 * this is for the string lookup table type
1235 */
1236 static int
qs_arrcmp_tzinfo(const void * s1,const void * s2)1237 qs_arrcmp_tzinfo(const void *s1, const void *s2)
1238 {
1239 return strcmp(((tzinfo_t*)s1)->id, ((tzinfo_t*)s2)->id);
1240 }
1241
1242 static int
qs_arrcmp_glblDbgFiles(const void * s1,const void * s2)1243 qs_arrcmp_glblDbgFiles(const void *s1, const void *s2)
1244 {
1245 return strcmp(*((char**)s1), *((char**)s2));
1246 }
1247
1248 /* set an environment variable */
1249 static rsRetVal
do_setenv(const char * const var)1250 do_setenv(const char *const var)
1251 {
1252 char varname[128];
1253 const char *val = var;
1254 size_t i;
1255 DEFiRet;
1256
1257 for(i = 0 ; *val != '=' ; ++i, ++val) {
1258 if(i == sizeof(varname)-i) {
1259 parser_errmsg("environment variable name too long "
1260 "[max %zu chars] or malformed entry: '%s'",
1261 sizeof(varname)-1, var);
1262 ABORT_FINALIZE(RS_RET_ERR_SETENV);
1263 }
1264 if(*val == '\0') {
1265 parser_errmsg("environment variable entry is missing "
1266 "equal sign (for value): '%s'", var);
1267 ABORT_FINALIZE(RS_RET_ERR_SETENV);
1268 }
1269 varname[i] = *val;
1270 }
1271 varname[i] = '\0';
1272 ++val;
1273 DBGPRINTF("do_setenv, var '%s', val '%s'\n", varname, val);
1274
1275 if(setenv(varname, val, 1) != 0) {
1276 char errStr[1024];
1277 rs_strerror_r(errno, errStr, sizeof(errStr));
1278 parser_errmsg("error setting environment variable "
1279 "'%s' to '%s': %s", varname, val, errStr);
1280 ABORT_FINALIZE(RS_RET_ERR_SETENV);
1281 }
1282
1283
1284 finalize_it:
1285 RETiRet;
1286 }
1287
1288
1289 /* This processes the "regular" parameters which are to be set after the
1290 * config has been fully loaded.
1291 */
1292 rsRetVal
glblDoneLoadCnf(void)1293 glblDoneLoadCnf(void)
1294 {
1295 int i;
1296 unsigned char *cstr;
1297 FILE *fp;
1298 DEFiRet;
1299 CHKiRet(objUse(net, CORE_COMPONENT));
1300
1301 if(ntzinfos > 0) {
1302 qsort(tzinfos, ntzinfos, sizeof(tzinfo_t), qs_arrcmp_tzinfo);
1303 }
1304 DBGPRINTF("Timezone information table (%d entries):\n", ntzinfos);
1305 displayTzinfos();
1306
1307 if(cnfparamvals == NULL)
1308 goto finalize_it;
1309
1310 for(i = 0 ; i < paramblk.nParams ; ++i) {
1311 if(!cnfparamvals[i].bUsed)
1312 continue;
1313 if(!strcmp(paramblk.descr[i].name, "workdirectory")) {
1314 cstr = (uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
1315 setWorkDir(NULL, cstr);
1316 } else if(!strcmp(paramblk.descr[i].name, "variables.casesensitive")) {
1317 const int val = (int) cnfparamvals[i].val.d.n;
1318 fjson_global_do_case_sensitive_comparison(val);
1319 DBGPRINTF("global/config: set case sensitive variables to %d\n",
1320 val);
1321 } else if(!strcmp(paramblk.descr[i].name, "localhostname")) {
1322 free(LocalHostNameOverride);
1323 LocalHostNameOverride = (uchar*)
1324 es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
1325 } else if(!strcmp(paramblk.descr[i].name, "defaultnetstreamdriverkeyfile")) {
1326 free(pszDfltNetstrmDrvrKeyFile);
1327 uchar *const fn = (uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
1328 fp = fopen((const char*)fn, "r");
1329 if(fp == NULL) {
1330 LogError(errno, RS_RET_NO_FILE_ACCESS,
1331 "error: defaultnetstreamdriverkeyfile '%s' "
1332 "could not be accessed", fn);
1333 } else {
1334 fclose(fp);
1335 pszDfltNetstrmDrvrKeyFile = fn;
1336 }
1337 } else if(!strcmp(paramblk.descr[i].name, "defaultnetstreamdrivercertfile")) {
1338 free(pszDfltNetstrmDrvrCertFile);
1339 uchar *const fn = (uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
1340 fp = fopen((const char*)fn, "r");
1341 if(fp == NULL) {
1342 LogError(errno, RS_RET_NO_FILE_ACCESS,
1343 "error: defaultnetstreamdrivercertfile '%s' "
1344 "could not be accessed", fn);
1345 } else {
1346 fclose(fp);
1347 pszDfltNetstrmDrvrCertFile = fn;
1348 }
1349 } else if(!strcmp(paramblk.descr[i].name, "defaultnetstreamdrivercafile")) {
1350 free(pszDfltNetstrmDrvrCAF);
1351 uchar *const fn = (uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
1352 fp = fopen((const char*)fn, "r");
1353 if(fp == NULL) {
1354 LogError(errno, RS_RET_NO_FILE_ACCESS,
1355 "error: defaultnetstreamdrivercafile file '%s' "
1356 "could not be accessed", fn);
1357 } else {
1358 fclose(fp);
1359 pszDfltNetstrmDrvrCAF = fn;
1360 }
1361 } else if(!strcmp(paramblk.descr[i].name, "defaultnetstreamdriver")) {
1362 free(pszDfltNetstrmDrvr);
1363 pszDfltNetstrmDrvr = (uchar*)
1364 es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
1365 } else if(!strcmp(paramblk.descr[i].name, "preservefqdn")) {
1366 bPreserveFQDN = (int) cnfparamvals[i].val.d.n;
1367 } else if(!strcmp(paramblk.descr[i].name,
1368 "dropmsgswithmaliciousdnsptrrecords")) {
1369 bDropMalPTRMsgs = (int) cnfparamvals[i].val.d.n;
1370 } else if(!strcmp(paramblk.descr[i].name, "action.reportsuspension")) {
1371 bActionReportSuspension = (int) cnfparamvals[i].val.d.n;
1372 } else if(!strcmp(paramblk.descr[i].name, "action.reportsuspensioncontinuation")) {
1373 bActionReportSuspensionCont = (int) cnfparamvals[i].val.d.n;
1374 } else if(!strcmp(paramblk.descr[i].name, "maxmessagesize")) {
1375 setMaxLine(cnfparamvals[i].val.d.n);
1376 } else if(!strcmp(paramblk.descr[i].name, "oversizemsg.errorfile")) {
1377 free(oversizeMsgErrorFile);
1378 oversizeMsgErrorFile = (uchar*)es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
1379 } else if(!strcmp(paramblk.descr[i].name, "oversizemsg.report")) {
1380 reportOversizeMsg = (int) cnfparamvals[i].val.d.n;
1381 } else if(!strcmp(paramblk.descr[i].name, "oversizemsg.input.mode")) {
1382 const char *const tmp = es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
1383 setOversizeMsgInputMode((uchar*) tmp);
1384 free((void*)tmp);
1385 } else if(!strcmp(paramblk.descr[i].name, "reportchildprocessexits")) {
1386 const char *const tmp = es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
1387 setReportChildProcessExits((uchar*) tmp);
1388 free((void*)tmp);
1389 } else if(!strcmp(paramblk.descr[i].name, "debug.onshutdown")) {
1390 glblDebugOnShutdown = (int) cnfparamvals[i].val.d.n;
1391 LogError(0, RS_RET_OK, "debug: onShutdown set to %d", glblDebugOnShutdown);
1392 } else if(!strcmp(paramblk.descr[i].name, "debug.gnutls")) {
1393 iGnuTLSLoglevel = (int) cnfparamvals[i].val.d.n;
1394 } else if(!strcmp(paramblk.descr[i].name, "debug.unloadmodules")) {
1395 glblUnloadModules = (int) cnfparamvals[i].val.d.n;
1396 } else if(!strcmp(paramblk.descr[i].name, "parser.controlcharacterescapeprefix")) {
1397 uchar* tmp = (uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
1398 cCCEscapeChar = tmp[0];
1399 free(tmp);
1400 } else if(!strcmp(paramblk.descr[i].name, "parser.droptrailinglfonreception")) {
1401 bDropTrailingLF = (int) cnfparamvals[i].val.d.n;
1402 } else if(!strcmp(paramblk.descr[i].name, "parser.escapecontrolcharactersonreceive")) {
1403 bEscapeCCOnRcv = (int) cnfparamvals[i].val.d.n;
1404 } else if(!strcmp(paramblk.descr[i].name, "parser.spacelfonreceive")) {
1405 bSpaceLFOnRcv = (int) cnfparamvals[i].val.d.n;
1406 } else if(!strcmp(paramblk.descr[i].name, "parser.escape8bitcharactersonreceive")) {
1407 bEscape8BitChars = (int) cnfparamvals[i].val.d.n;
1408 } else if(!strcmp(paramblk.descr[i].name, "parser.escapecontrolcharactertab")) {
1409 bEscapeTab = (int) cnfparamvals[i].val.d.n;
1410 } else if(!strcmp(paramblk.descr[i].name, "parser.escapecontrolcharacterscstyle")) {
1411 bParserEscapeCCCStyle = (int) cnfparamvals[i].val.d.n;
1412 } else if(!strcmp(paramblk.descr[i].name, "parser.parsehostnameandtag")) {
1413 bParseHOSTNAMEandTAG = (int) cnfparamvals[i].val.d.n;
1414 } else if(!strcmp(paramblk.descr[i].name, "parser.permitslashinprogramname")) {
1415 bPermitSlashInProgramname = (int) cnfparamvals[i].val.d.n;
1416 } else if(!strcmp(paramblk.descr[i].name, "debug.logfile")) {
1417 if(pszAltDbgFileName == NULL) {
1418 pszAltDbgFileName = es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
1419 /* can actually happen if debug system also opened altdbg */
1420 if(altdbg != -1) {
1421 close(altdbg);
1422 }
1423 if((altdbg = open(pszAltDbgFileName, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY
1424 |O_CLOEXEC, S_IRUSR|S_IWUSR)) == -1) {
1425 LogError(0, RS_RET_ERR, "debug log file '%s' could not be opened",
1426 pszAltDbgFileName);
1427 }
1428 }
1429 LogError(0, RS_RET_OK, "debug log file is '%s', fd %d", pszAltDbgFileName, altdbg);
1430 } else if(!strcmp(paramblk.descr[i].name, "janitor.interval")) {
1431 janitorInterval = (int) cnfparamvals[i].val.d.n;
1432 } else if(!strcmp(paramblk.descr[i].name, "net.ipprotocol")) {
1433 char *proto = es_str2cstr(cnfparamvals[i].val.d.estr, NULL);
1434 if(!strcmp(proto, "unspecified")) {
1435 iDefPFFamily = PF_UNSPEC;
1436 } else if(!strcmp(proto, "ipv4-only")) {
1437 iDefPFFamily = PF_INET;
1438 } else if(!strcmp(proto, "ipv6-only")) {
1439 iDefPFFamily = PF_INET6;
1440 } else{
1441 LogError(0, RS_RET_ERR, "invalid net.ipprotocol "
1442 "parameter '%s' -- ignored", proto);
1443 }
1444 free(proto);
1445 } else if(!strcmp(paramblk.descr[i].name, "senders.reportnew")) {
1446 glblReportNewSenders = (int) cnfparamvals[i].val.d.n;
1447 } else if(!strcmp(paramblk.descr[i].name, "senders.reportgoneaway")) {
1448 glblReportGoneAwaySenders = (int) cnfparamvals[i].val.d.n;
1449 } else if(!strcmp(paramblk.descr[i].name, "senders.timeoutafter")) {
1450 glblSenderStatsTimeout = (int) cnfparamvals[i].val.d.n;
1451 } else if(!strcmp(paramblk.descr[i].name, "senders.keeptrack")) {
1452 glblSenderKeepTrack = (int) cnfparamvals[i].val.d.n;
1453 } else if(!strcmp(paramblk.descr[i].name, "inputs.timeout.shutdown")) {
1454 glblInputTimeoutShutdown = (int) cnfparamvals[i].val.d.n;
1455 } else if(!strcmp(paramblk.descr[i].name, "privdrop.group.keepsupplemental")) {
1456 loadConf->globals.gidDropPrivKeepSupplemental = (int) cnfparamvals[i].val.d.n;
1457 } else if(!strcmp(paramblk.descr[i].name, "privdrop.group.id")) {
1458 loadConf->globals.gidDropPriv = (int) cnfparamvals[i].val.d.n;
1459 } else if(!strcmp(paramblk.descr[i].name, "privdrop.group.name")) {
1460 loadConf->globals.gidDropPriv = (int) cnfparamvals[i].val.d.n;
1461 } else if(!strcmp(paramblk.descr[i].name, "privdrop.user.id")) {
1462 loadConf->globals.uidDropPriv = (int) cnfparamvals[i].val.d.n;
1463 } else if(!strcmp(paramblk.descr[i].name, "privdrop.user.name")) {
1464 loadConf->globals.uidDropPriv = (int) cnfparamvals[i].val.d.n;
1465 } else if(!strcmp(paramblk.descr[i].name, "security.abortonidresolutionfail")) {
1466 loadConf->globals.abortOnIDResolutionFail = (int) cnfparamvals[i].val.d.n;
1467 } else if(!strcmp(paramblk.descr[i].name, "net.acladdhostnameonfail")) {
1468 *(net.pACLAddHostnameOnFail) = (int) cnfparamvals[i].val.d.n;
1469 } else if(!strcmp(paramblk.descr[i].name, "net.aclresolvehostname")) {
1470 *(net.pACLDontResolve) = !((int) cnfparamvals[i].val.d.n);
1471 } else if(!strcmp(paramblk.descr[i].name, "net.enabledns")) {
1472 setDisableDNS(!((int) cnfparamvals[i].val.d.n));
1473 } else if(!strcmp(paramblk.descr[i].name, "net.permitwarning")) {
1474 setOption_DisallowWarning(!((int) cnfparamvals[i].val.d.n));
1475 } else if(!strcmp(paramblk.descr[i].name, "abortonuncleanconfig")) {
1476 loadConf->globals.bAbortOnUncleanConfig = cnfparamvals[i].val.d.n;
1477 } else if(!strcmp(paramblk.descr[i].name, "internalmsg.ratelimit.burst")) {
1478 glblIntMsgRateLimitBurst = (int) cnfparamvals[i].val.d.n;
1479 } else if(!strcmp(paramblk.descr[i].name, "internalmsg.ratelimit.interval")) {
1480 glblIntMsgRateLimitItv = (int) cnfparamvals[i].val.d.n;
1481 } else if(!strcmp(paramblk.descr[i].name, "internalmsg.severity")) {
1482 glblIntMsgsSeverityFilter = (int) cnfparamvals[i].val.d.n;
1483 if((glblIntMsgsSeverityFilter < 0) || (glblIntMsgsSeverityFilter > 7)) {
1484 parser_errmsg("invalid internalmsg.severity value");
1485 glblIntMsgsSeverityFilter = DFLT_INT_MSGS_SEV_FILTER;
1486 }
1487 } else if(!strcmp(paramblk.descr[i].name, "environment")) {
1488 for(int j = 0 ; j < cnfparamvals[i].val.d.ar->nmemb ; ++j) {
1489 char *const var = es_str2cstr(cnfparamvals[i].val.d.ar->arr[j], NULL);
1490 do_setenv(var);
1491 free(var);
1492 }
1493 } else if(!strcmp(paramblk.descr[i].name, "errormessagestostderr.maxnumber")) {
1494 loadConf->globals.maxErrMsgToStderr = (int) cnfparamvals[i].val.d.n;
1495 } else if(!strcmp(paramblk.descr[i].name, "debug.files")) {
1496 free(glblDbgFiles); /* "fix" Coverity false positive */
1497 glblDbgFilesNum = cnfparamvals[i].val.d.ar->nmemb;
1498 glblDbgFiles = (char**) malloc(cnfparamvals[i].val.d.ar->nmemb * sizeof(char*));
1499 for(int j = 0 ; j < cnfparamvals[i].val.d.ar->nmemb ; ++j) {
1500 glblDbgFiles[j] = es_str2cstr(cnfparamvals[i].val.d.ar->arr[j], NULL);
1501 }
1502 qsort(glblDbgFiles, glblDbgFilesNum, sizeof(char*), qs_arrcmp_glblDbgFiles);
1503 } else if(!strcmp(paramblk.descr[i].name, "debug.whitelist")) {
1504 glblDbgWhitelist = (int) cnfparamvals[i].val.d.n;
1505 } else if(!strcmp(paramblk.descr[i].name, "shutdown.queue.doublesize")) {
1506 glblShutdownQueueDoubleSize = (int) cnfparamvals[i].val.d.n;
1507 } else if(!strcmp(paramblk.descr[i].name, "umask")) {
1508 loadConf->globals.umask = (int) cnfparamvals[i].val.d.n;
1509 } else if(!strcmp(paramblk.descr[i].name, "shutdown.enable.ctlc")) {
1510 glblPermitCtlC = (int) cnfparamvals[i].val.d.n;
1511 } else if(!strcmp(paramblk.descr[i].name, "default.action.queue.timeoutshutdown")) {
1512 actq_dflt_toQShutdown = cnfparamvals[i].val.d.n;
1513 } else if(!strcmp(paramblk.descr[i].name, "default.action.queue.timeoutactioncompletion")) {
1514 actq_dflt_toActShutdown = cnfparamvals[i].val.d.n;
1515 } else if(!strcmp(paramblk.descr[i].name, "default.action.queue.timeoutenqueue")) {
1516 actq_dflt_toEnq = cnfparamvals[i].val.d.n;
1517 } else if(!strcmp(paramblk.descr[i].name, "default.action.queue.timeoutworkerthreadshutdown")) {
1518 actq_dflt_toWrkShutdown = cnfparamvals[i].val.d.n;
1519 } else if(!strcmp(paramblk.descr[i].name, "default.ruleset.queue.timeoutshutdown")) {
1520 ruleset_dflt_toQShutdown = cnfparamvals[i].val.d.n;
1521 } else if(!strcmp(paramblk.descr[i].name, "default.ruleset.queue.timeoutactioncompletion")) {
1522 ruleset_dflt_toActShutdown = cnfparamvals[i].val.d.n;
1523 } else if(!strcmp(paramblk.descr[i].name, "default.ruleset.queue.timeoutenqueue")) {
1524 ruleset_dflt_toEnq = cnfparamvals[i].val.d.n;
1525 } else if(!strcmp(paramblk.descr[i].name, "default.ruleset.queue.timeoutworkerthreadshutdown")) {
1526 ruleset_dflt_toWrkShutdown = cnfparamvals[i].val.d.n;
1527 } else if(!strcmp(paramblk.descr[i].name, "reverselookup.cache.ttl.default")) {
1528 dnscacheDefaultTTL = cnfparamvals[i].val.d.n;
1529 } else if(!strcmp(paramblk.descr[i].name, "reverselookup.cache.ttl.enable")) {
1530 dnscacheEnableTTL = cnfparamvals[i].val.d.n;
1531 } else if(!strcmp(paramblk.descr[i].name, "parser.supportcompressionextension")) {
1532 bSupportCompressionExtension = cnfparamvals[i].val.d.n;
1533 } else {
1534 dbgprintf("glblDoneLoadCnf: program error, non-handled "
1535 "param '%s'\n", paramblk.descr[i].name);
1536 }
1537 }
1538
1539 if(glblDebugOnShutdown && Debug != DEBUG_FULL) {
1540 Debug = DEBUG_ONDEMAND;
1541 stddbg = -1;
1542 }
1543
1544 finalize_it: RETiRet;
1545 }
1546
1547
1548 /* Initialize the glbl class. Must be called as the very first method
1549 * before anything else is called inside this class.
1550 * rgerhards, 2008-02-19
1551 */
1552 BEGINAbstractObjClassInit(glbl, 1, OBJ_IS_CORE_MODULE) /* class, version */
1553 /* request objects we use */
1554 CHKiRet(objUse(prop, CORE_COMPONENT));
1555
1556 /* intialize properties */
1557 storeLocalHostIPIF((uchar*)"127.0.0.1");
1558
1559 /* config handlers are never unregistered and need not be - we are always loaded ;) */
1560 CHKiRet(regCfSysLineHdlr((uchar *)"debugfile", 0, eCmdHdlrGetWord, setDebugFile, NULL, NULL));
1561 CHKiRet(regCfSysLineHdlr((uchar *)"debuglevel", 0, eCmdHdlrInt, setDebugLevel, NULL, NULL));
1562 CHKiRet(regCfSysLineHdlr((uchar *)"workdirectory", 0, eCmdHdlrGetWord, setWorkDir, NULL, NULL));
1563 CHKiRet(regCfSysLineHdlr((uchar *)"dropmsgswithmaliciousdnsptrrecords", 0, eCmdHdlrBinary, NULL,
1564 &bDropMalPTRMsgs, NULL));
1565 CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdriver", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvr,
1566 NULL));
1567 CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdrivercafile", 0, eCmdHdlrGetWord, NULL,
1568 &pszDfltNetstrmDrvrCAF, NULL));
1569 CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdriverkeyfile", 0, eCmdHdlrGetWord, NULL,
1570 &pszDfltNetstrmDrvrKeyFile, NULL));
1571 CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdrivercertfile", 0, eCmdHdlrGetWord, NULL,
1572 &pszDfltNetstrmDrvrCertFile, NULL));
1573 CHKiRet(regCfSysLineHdlr((uchar *)"localhostname", 0, eCmdHdlrGetWord, NULL, &LocalHostNameOverride, NULL));
1574 CHKiRet(regCfSysLineHdlr((uchar *)"localhostipif", 0, eCmdHdlrGetWord, setLocalHostIPIF, NULL, NULL));
1575 CHKiRet(regCfSysLineHdlr((uchar *)"optimizeforuniprocessor", 0, eCmdHdlrGoneAway, NULL, NULL, NULL));
1576 CHKiRet(regCfSysLineHdlr((uchar *)"preservefqdn", 0, eCmdHdlrBinary, NULL, &bPreserveFQDN, NULL));
1577 CHKiRet(regCfSysLineHdlr((uchar *)"maxmessagesize", 0, eCmdHdlrSize, legacySetMaxMessageSize, NULL, NULL));
1578
1579 /* Deprecated parser config options */
1580 CHKiRet(regCfSysLineHdlr((uchar *)"controlcharacterescapeprefix", 0, eCmdHdlrGetChar, NULL,
1581 &cCCEscapeChar, NULL));
1582 CHKiRet(regCfSysLineHdlr((uchar *)"droptrailinglfonreception", 0, eCmdHdlrBinary, NULL,
1583 &bDropTrailingLF, NULL));
1584 CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactersonreceive", 0, eCmdHdlrBinary, NULL,
1585 &bEscapeCCOnRcv, NULL));
1586 CHKiRet(regCfSysLineHdlr((uchar *)"spacelfonreceive", 0, eCmdHdlrBinary, NULL, &bSpaceLFOnRcv, NULL));
1587 CHKiRet(regCfSysLineHdlr((uchar *)"escape8bitcharactersonreceive", 0, eCmdHdlrBinary, NULL,
1588 &bEscape8BitChars, NULL));
1589 CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactertab", 0, eCmdHdlrBinary, NULL, &bEscapeTab, NULL));
1590
1591 CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
1592 resetConfigVariables, NULL, NULL));
1593
1594 INIT_ATOMIC_HELPER_MUT(mutTerminateInputs);
1595 ENDObjClassInit(glbl)
1596
1597
1598 /* Exit the glbl class.
1599 * rgerhards, 2008-04-17
1600 */
1601 BEGINObjClassExit(glbl, OBJ_IS_CORE_MODULE) /* class, version */
1602 free(pszDfltNetstrmDrvr);
1603 free(pszDfltNetstrmDrvrCAF);
1604 free(pszDfltNetstrmDrvrKeyFile);
1605 free(pszDfltNetstrmDrvrCertFile);
1606 free(pszWorkDir);
1607 free(LocalDomain);
1608 free(LocalHostName);
1609 free(LocalHostNameOverride);
1610 free(oversizeMsgErrorFile);
1611 free(LocalFQDNName);
1612 freeTimezoneInfo();
1613 objRelease(prop, CORE_COMPONENT);
1614 if(propLocalHostNameToDelete != NULL)
1615 prop.Destruct(&propLocalHostNameToDelete);
1616 DESTROY_ATOMIC_HELPER_MUT(mutTerminateInputs);
1617 ENDObjClassExit(glbl)
1618