438
* Intervals at which we flush out "message repeated" messages,
272
/* Intervals at which we flush out "message repeated" messages,
439
273
* in seconds after previous message is logged. After each flush,
440
274
* we move to the next interval until we reach the largest.
275
* TODO: this shall go into action object! -- rgerhards, 2008-01-29
442
int repeatinterval[] = { 30, 60 }; /* # of secs before flush */
443
#define MAXREPEAT ((int)((sizeof(repeatinterval) / sizeof(repeatinterval[0])) - 1))
444
#define REPEATTIME(f) ((f)->f_time + repeatinterval[(f)->f_repeatcount])
445
#define BACKOFF(f) { if (++(f)->f_repeatcount > MAXREPEAT) \
446
(f)->f_repeatcount = MAXREPEAT; \
454
struct sockaddr_in su_sin;
455
struct sockaddr_in6 su_sin6;
277
int repeatinterval[2] = { 30, 60 }; /* # of secs before flush */
459
279
#define LIST_DELIMITER ':' /* delimiter between two hosts */
461
281
struct filed *Files = NULL; /* read-only after init() (but beware of sigusr1!) */
468
static struct code PriNames[] = {
469
{"alert", LOG_ALERT},
471
{"debug", LOG_DEBUG},
472
{"emerg", LOG_EMERG},
474
{"error", LOG_ERR}, /* DEPRECATED */
476
{"none", INTERNAL_NOPRI}, /* INTERNAL */
477
{"notice", LOG_NOTICE},
478
{"panic", LOG_EMERG}, /* DEPRECATED */
479
{"warn", LOG_WARNING}, /* DEPRECATED */
480
{"warning", LOG_WARNING},
485
static struct code FacNames[] = {
487
{"authpriv", LOG_AUTHPRIV},
489
{"daemon", LOG_DAEMON},
493
{"mark", LOG_MARK}, /* INTERNAL */
495
{"security", LOG_AUTH}, /* DEPRECATED */
496
{"syslog", LOG_SYSLOG},
502
{"local0", LOG_LOCAL0},
503
{"local1", LOG_LOCAL1},
504
{"local2", LOG_LOCAL2},
505
{"local3", LOG_LOCAL3},
506
{"local4", LOG_LOCAL4},
507
{"local5", LOG_LOCAL5},
508
{"local6", LOG_LOCAL6},
509
{"local7", LOG_LOCAL7},
513
283
static pid_t ppid; /* This is a quick and dirty hack used for spliting main/startup thread */
285
typedef struct legacyOptsLL_s {
287
struct legacyOptsLL_s *next;
289
legacyOptsLL_t *pLegacyOptsLL = NULL;
515
291
/* global variables for config file state */
516
292
static int bDropTrailingLF = 1; /* drop trailing LF's on reception? */
517
int Debug; /* debug flag - read-only after startup */
293
int iCompatibilityMode = 0; /* version we should be compatible with; 0 means sysklogd. It is
294
the default, so if no -c<n> option is given, we make ourselvs
295
as compatible to sysklogd as possible. */
518
296
static int bDebugPrintTemplateList = 1;/* output template list in debug mode? */
519
297
static int bDebugPrintCfSysLineHandlerList = 1;/* output cfsyslinehandler list in debug mode? */
520
298
static int bDebugPrintModuleList = 1;/* output module list in debug mode? */
521
299
int bDropMalPTRMsgs = 0;/* Drop messages which have malicious PTR records during DNS lookup */
522
300
static uchar cCCEscapeChar = '\\';/* character to be used to start an escape sequence for control chars */
523
static int bEscapeCCOnRcv; /* escape control characters on reception: 0 - no, 1 - yes */
524
static int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */
525
static int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */
526
static int logEveryMsg = 0;/* no repeat message processing - read-only after startup
527
* 0 - suppress duplicate messages
528
* 1 - do NOT suppress duplicate messages
301
static int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - no, 1 - yes */
302
int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */
303
int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */
304
uchar *pszWorkDir = NULL;/* name of rsyslog's spool directory (without trailing slash) */
530
305
/* end global config file state variables */
532
static unsigned int Forwarding = 0;
533
static int nfunix = 1; /* number of Unix sockets open / read-only after startup */
534
307
char LocalHostName[MAXHOSTNAMELEN+1];/* our hostname - read-only after startup */
535
308
char *LocalDomain; /* our local domain name - read-only after startup */
536
int *finet = NULL; /* Internet datagram sockets, first element is nbr of elements
537
* read-only after init(), but beware of restart! */
538
static char *LogPort = "514"; /* port number for INET connections */
539
static int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */
309
int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */
540
310
int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both), set via cmdline */
541
311
int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */
542
static int MarkSeq = 0; /* mark sequence number - modified in domark() only */
543
312
static int NoFork = 0; /* don't fork - don't run in daemon mode - read-only after startup */
544
static int AcceptRemote = 0;/* receive messages that come via UDP - read-only after startup */
545
313
int DisableDNS = 0; /* don't look up IP addresses of remote messages */
546
314
char **StripDomains = NULL;/* these domains may be stripped before writing logs - r/o after s.u., never touched by init */
547
315
char **LocalHosts = NULL;/* these hosts are logged with their hostname - read-only after startup, never touched by init */
548
int NoHops = 1; /* Can we bounce syslog messages through an
549
intermediate host. Read-only after startup */
550
static int Initialized = 0; /* set when we have initialized ourselves
551
* rgerhards 2004-11-09: and by initialized, we mean that
552
* the configuration file could be properly read AND the
553
* syslog/udp port could be obtained (the later is debatable).
554
* It is mainly a setting used for emergency logging: if
555
* something really goes wild, we can not do as indicated in
556
* the log file, but we still log messages to the system
557
* console. This is probably the best that can be done in
559
* read-only after startup, but modified during restart
316
static int bHaveMainQueue = 0;/* set to 1 if the main queue - in queueing mode - is available
317
* If the main queue is either not yet ready or not running in
318
* queueing mode (mode DIRECT!), then this is set to 0.
562
321
extern int errno;
565
/* This structure represents the files that will have log
567
* RGerhards 2004-11-08: Each instance of the filed structure
568
* describes what I call an "output channel". This is important
569
* to mention as we now allow database connections to be
570
* present in the filed structure. If helps immensely, if we
571
* think of it as the abstraction of an output channel.
572
* rgerhards, 2005-10-26: The structure below provides ample
573
* opportunity for non-thread-safety. Each of the variable
574
* accesses must be carefully evaluated, many of them probably
575
* be guarded by mutexes. But beware of deadlocks...
576
* rgerhards, 2007-08-01: as you can see, the structure has shrunk pretty much. I will
577
* remove some of the comments some time. It's still the structure that controls much
578
* of the processing that goes on in syslogd, but it now has lots of helpers.
581
struct filed *f_next; /* next in linked list */
582
/* filter properties */
584
FILTER_PRI = 0, /* traditional PRI based filer */
585
FILTER_PROP = 1 /* extended filter, property based */
587
EHostnameCmpMode eHostnameCmpMode;
588
rsCStrObj *pCSHostnameComp; /* hostname to check */
589
rsCStrObj *pCSProgNameComp; /* tag to check or NULL, if not to be checked */
591
u_char f_pmask[LOG_NFACILITIES+1]; /* priority mask */
593
rsCStrObj *pCSPropName;
595
FIOP_NOP = 0, /* do not use - No Operation */
596
FIOP_CONTAINS = 1, /* contains string? */
597
FIOP_ISEQUAL = 2, /* is (exactly) equal? */
598
FIOP_STARTSWITH = 3, /* starts with a string? */
599
FIOP_REGEX = 4 /* matches a regular expression? */
601
rsCStrObj *pCSCompValue; /* value to "compare" against */
602
char isNegated; /* actually a boolean ;) */
606
linkedList_t llActList; /* list of configured actions */
608
typedef struct filed selector_t; /* new type name */
323
/* main message queue and its configuration parameters */
324
static queue_t *pMsgQueue = NULL; /* the main message queue */
325
static int iMainMsgQueueSize = 10000; /* size of the main message queue above */
326
static int iMainMsgQHighWtrMark = 8000; /* high water mark for disk-assisted queues */
327
static int iMainMsgQLowWtrMark = 2000; /* low water mark for disk-assisted queues */
328
static int iMainMsgQDiscardMark = 9800; /* begin to discard messages */
329
static int iMainMsgQDiscardSeverity = 8; /* by default, discard nothing to prevent unintentional loss */
330
static int iMainMsgQueueNumWorkers = 1; /* number of worker threads for the mm queue above */
331
static queueType_t MainMsgQueType = QUEUETYPE_FIXED_ARRAY; /* type of the main message queue above */
332
static uchar *pszMainMsgQFName = NULL; /* prefix for the main message queue file */
333
static int64 iMainMsgQueMaxFileSize = 1024*1024;
334
static int iMainMsgQPersistUpdCnt = 0; /* persist queue info every n updates */
335
static int iMainMsgQtoQShutdown = 0; /* queue shutdown */
336
static int iMainMsgQtoActShutdown = 1000; /* action shutdown (in phase 2) */
337
static int iMainMsgQtoEnq = 2000; /* timeout for queue enque */
338
static int iMainMsgQtoWrkShutdown = 60000; /* timeout for worker thread shutdown */
339
static int iMainMsgQWrkMinMsgs = 100; /* minimum messages per worker needed to start a new one */
340
static int iMainMsgQDeqSlowdown = 0; /* dequeue slowdown (simple rate limiting) */
341
static int bMainMsgQSaveOnShutdown = 1; /* save queue on shutdown (when DA enabled)? */
342
static int64 iMainMsgQueMaxDiskSpace = 0; /* max disk space allocated 0 ==> unlimited */
611
345
/* support for simple textual representation of FIOP names
646
380
bDebugPrintCfSysLineHandlerList = 1;
647
381
bDebugPrintModuleList = 1;
648
382
bEscapeCCOnRcv = 1; /* default is to escape control characters */
649
bReduceRepeatMsgs = (logEveryMsg == 1) ? 0 : 1;
383
bReduceRepeatMsgs = 0;
650
384
bDropMalPTRMsgs = 0;
651
if(pModDir != NULL) {
385
if(pszWorkDir != NULL) {
389
if(pszMainMsgQFName != NULL) {
390
free(pszMainMsgQFName);
391
pszMainMsgQFName = NULL;
656
393
iMainMsgQueueSize = 10000;
394
iMainMsgQHighWtrMark = 8000;
395
iMainMsgQLowWtrMark = 2000;
396
iMainMsgQDiscardMark = 9800;
397
iMainMsgQDiscardSeverity = 4;
398
iMainMsgQueMaxFileSize = 1024 * 1024;
399
iMainMsgQueueNumWorkers = 1;
400
iMainMsgQPersistUpdCnt = 0;
401
iMainMsgQtoQShutdown = 0;
402
iMainMsgQtoActShutdown = 1000;
403
iMainMsgQtoEnq = 2000;
404
iMainMsgQtoWrkShutdown = 60000;
405
iMainMsgQWrkMinMsgs = 100;
406
iMainMsgQDeqSlowdown = 0;
407
bMainMsgQSaveOnShutdown = 1;
408
MainMsgQueType = QUEUETYPE_FIXED_ARRAY;
409
iMainMsgQueMaxDiskSpace = 0;
410
glbliActionResumeRetryCount = 0;
659
412
return RS_RET_OK;
663
/* support for defining allowed TCP and UDP senders. We use the same
664
* structure to implement this (a linked list), but we define two different
665
* list roots, one for UDP and one for TCP.
666
* rgerhards, 2005-09-26
669
/* All of the five below are read-only after startup */
670
static struct AllowedSenders *pAllowedSenders_UDP = NULL; /* the roots of the allowed sender */
671
struct AllowedSenders *pAllowedSenders_TCP = NULL; /* lists. If NULL, all senders are ok! */
672
static struct AllowedSenders *pLastAllowedSenders_UDP = NULL; /* and now the pointers to the last */
673
static struct AllowedSenders *pLastAllowedSenders_TCP = NULL; /* element in the respective list */
674
#endif /* #ifdef SYSLOG_INET */
676
417
int option_DisallowWarning = 1; /* complain if message from disallowed sender is received */
679
420
/* hardcoded standard templates (used for defaults) */
680
static uchar template_TraditionalFormat[] = "\"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n\"";
421
static uchar template_SyslogProtocol23Format[] = "\"<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg%\n\"";
422
static uchar template_TraditionalFileFormat[] = "\"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n\"";
423
static uchar template_FileFormat[] = "\"%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n\"";
681
424
static uchar template_WallFmt[] = "\"\r\n\7Message from syslogd@%HOSTNAME% at %timegenerated% ...\r\n %syslogtag%%msg%\n\r\"";
682
static uchar template_StdFwdFmt[] = "\"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag%%msg%\"";
425
static uchar template_ForwardFormat[] = "\"<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32%%msg%\"";
426
static uchar template_TraditionalForwardFormat[] = "\"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag:1:32%%msg%\"";
683
427
static uchar template_StdUsrMsgFmt[] = "\" %syslogtag%%msg%\n\r\"";
684
428
static uchar template_StdDBFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-mysql%', '%timegenerated:::date-mysql%', %iut%, '%syslogtag%')\",SQL";
429
static uchar template_StdPgSQLFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-pgsql%', '%timegenerated:::date-pgsql%', %iut%, '%syslogtag%')\",STDSQL";
685
430
/* end template */
688
433
/* up to the next comment, prototypes that should be removed by reordering */
690
static msgQueue *queueInit (void);
691
static void *singleWorker(); /* REMOVEME later 2005-10-24 */
693
434
/* Function prototypes. */
694
435
static char **crunch_list(char *list);
695
static void printline(char *hname, char *msg, int iSource);
696
static void logmsg(int pri, msg_t*, int flags);
697
static rsRetVal fprintlog(action_t *pAction);
698
436
static void reapchild();
699
437
static void debug_switch();
700
static rsRetVal cfline(uchar *line, selector_t **pfCurr);
701
static int decode(uchar *name, struct code *codetab);
702
438
static void sighup_handler();
703
static void die(int sig);
704
439
static void freeSelectors(void);
705
static rsRetVal processConfFile(uchar *pConfFile);
706
static rsRetVal selectorAddList(selector_t *f);
707
440
static void processImInternal(void);
709
/* Code for handling allowed/disallowed senders
712
static inline void MaskIP6 (struct in6_addr *addr, uint8_t bits) {
715
assert (addr != NULL);
716
assert (bits <= 128);
720
addr->s6_addr32[i++] &= htonl(0xffffffff << (32 - (bits % 32)));
721
for (; i < (sizeof addr->s6_addr32)/4; i++)
722
addr->s6_addr32[i] = 0;
725
static inline void MaskIP4 (struct in_addr *addr, uint8_t bits) {
727
assert (addr != NULL);
730
addr->s_addr &= htonl(0xffffffff << (32 - bits));
733
#define SIN(sa) ((struct sockaddr_in *)(sa))
734
#define SIN6(sa) ((struct sockaddr_in6 *)(sa))
736
/* This function adds an allowed sender entry to the ACL linked list.
737
* In any case, a single entry is added. If an error occurs, the
738
* function does its error reporting itself. All validity checks
739
* must already have been done by the caller.
740
* This is a helper to AddAllowedSender().
741
* rgerhards, 2007-07-17
743
static rsRetVal AddAllowedSenderEntry(struct AllowedSenders **ppRoot, struct AllowedSenders **ppLast,
744
struct NetAddr *iAllow, uint8_t iSignificantBits)
746
struct AllowedSenders *pEntry = NULL;
748
assert(ppRoot != NULL);
749
assert(ppLast != NULL);
750
assert(iAllow != NULL);
752
if((pEntry = (struct AllowedSenders*) calloc(1, sizeof(struct AllowedSenders))) == NULL) {
753
glblHadMemShortage = 1;
754
return RS_RET_OUT_OF_MEMORY; /* no options left :( */
757
memcpy(&(pEntry->allowedSender), iAllow, sizeof (struct NetAddr));
758
pEntry->pNext = NULL;
759
pEntry->SignificantBits = iSignificantBits;
762
if(*ppRoot == NULL) {
765
(*ppLast)->pNext = pEntry;
772
/* function to clear the allowed sender structure in cases where
773
* it must be freed (occurs most often when HUPed.
774
* TODO: reconsider recursive implementation
776
static void clearAllowedSenders (struct AllowedSenders *pAllow) {
777
if (pAllow != NULL) {
778
if (pAllow->pNext != NULL)
779
clearAllowedSenders (pAllow->pNext);
781
if (F_ISSET(pAllow->allowedSender.flags, ADDR_NAME))
782
free (pAllow->allowedSender.addr.HostWildcard);
784
free (pAllow->allowedSender.addr.NetAddr);
791
/* function to add an allowed sender to the allowed sender list. The
792
* root of the list is caller-provided, so it can be used for all
793
* supported lists. The caller must provide a pointer to the root,
794
* as it eventually needs to be updated. Also, a pointer to the
795
* pointer to the last element must be provided (to speed up adding
797
* rgerhards, 2005-09-26
798
* If a hostname is given there are possible multiple entries
799
* added (all addresses from that host).
801
static rsRetVal AddAllowedSender(struct AllowedSenders **ppRoot, struct AllowedSenders **ppLast,
802
struct NetAddr *iAllow, uint8_t iSignificantBits)
806
assert(ppRoot != NULL);
807
assert(ppLast != NULL);
808
assert(iAllow != NULL);
810
if (!F_ISSET(iAllow->flags, ADDR_NAME)) {
811
if(iSignificantBits == 0)
812
/* we handle this seperatly just to provide a better
815
logerror("You can not specify 0 bits of the netmask, this would "
816
"match ALL systems. If you really intend to do that, "
817
"remove all $AllowedSender directives.");
819
switch (iAllow->addr.NetAddr->sa_family) {
821
if((iSignificantBits < 1) || (iSignificantBits > 32)) {
822
logerrorInt("Invalid bit number in IPv4 address - adjusted to 32",
823
(int)iSignificantBits);
824
iSignificantBits = 32;
827
MaskIP4 (&(SIN(iAllow->addr.NetAddr)->sin_addr), iSignificantBits);
830
if((iSignificantBits < 1) || (iSignificantBits > 128)) {
831
logerrorInt("Invalid bit number in IPv6 address - adjusted to 128",
833
iSignificantBits = 128;
836
MaskIP6 (&(SIN6(iAllow->addr.NetAddr)->sin6_addr), iSignificantBits);
839
/* rgerhards, 2007-07-16: We have an internal program error in this
840
* case. However, there is not much we can do against it right now. Of
841
* course, we could abort, but that would probably cause more harm
842
* than good. So we continue to run. We simply do not add this line - the
843
* worst thing that happens is that one host will not be allowed to
846
logerrorInt("Internal error caused AllowedSender to be ignored, AF = %d",
847
iAllow->addr.NetAddr->sa_family);
850
/* OK, entry constructed, now lets add it to the ACL list */
851
iRet = AddAllowedSenderEntry(ppRoot, ppLast, iAllow, iSignificantBits);
853
/* we need to process a hostname ACL */
855
logerror ("Ignoring hostname based ACLs because DNS is disabled.");
859
if (!strchr (iAllow->addr.HostWildcard, '*') &&
860
!strchr (iAllow->addr.HostWildcard, '?')) {
861
/* single host - in this case, we pull its IP addresses from DNS
862
* and add IP-based ACLs.
864
struct addrinfo hints, *res, *restmp;
865
struct NetAddr allowIP;
867
memset (&hints, 0, sizeof (struct addrinfo));
868
hints.ai_family = AF_UNSPEC;
869
hints.ai_flags = AI_ADDRCONFIG;
870
hints.ai_socktype = SOCK_DGRAM;
872
if (getaddrinfo (iAllow->addr.HostWildcard, NULL, &hints, &res) != 0) {
873
logerrorSz("DNS error: Can't resolve \"%s\", not added as allowed sender", iAllow->addr.HostWildcard);
874
/* We could use the text name in this case - maybe this could become
875
* a user-defined option at some stage.
880
for (restmp = res ; res != NULL ; res = res->ai_next) {
881
switch (res->ai_family) {
882
case AF_INET: /* add IPv4 */
883
iSignificantBits = 32;
885
if((allowIP.addr.NetAddr = malloc(res->ai_addrlen)) == NULL) {
886
glblHadMemShortage = 1;
887
return RS_RET_OUT_OF_MEMORY;
889
memcpy(allowIP.addr.NetAddr, res->ai_addr, res->ai_addrlen);
891
if((iRet = AddAllowedSenderEntry(ppRoot, ppLast, &allowIP, iSignificantBits))
895
case AF_INET6: /* IPv6 - but need to check if it is a v6-mapped IPv4 */
896
if(IN6_IS_ADDR_V4MAPPED (&SIN6(res->ai_addr)->sin6_addr)) {
897
/* extract & add IPv4 */
899
iSignificantBits = 32;
901
if((allowIP.addr.NetAddr = malloc(sizeof(struct sockaddr_in)))
903
glblHadMemShortage = 1;
904
return RS_RET_OUT_OF_MEMORY;
906
SIN(allowIP.addr.NetAddr)->sin_family = AF_INET;
907
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
908
SIN(allowIP.addr.NetAddr)->sin_len = sizeof (struct sockaddr_in);
910
SIN(allowIP.addr.NetAddr)->sin_port = 0;
911
memcpy(&(SIN(allowIP.addr.NetAddr)->sin_addr.s_addr),
912
&(SIN6(res->ai_addr)->sin6_addr.s6_addr32[3]),
913
sizeof (struct sockaddr_in));
915
if((iRet = AddAllowedSenderEntry(ppRoot, ppLast, &allowIP,
920
/* finally add IPv6 */
922
iSignificantBits = 128;
924
if((allowIP.addr.NetAddr = malloc(res->ai_addrlen)) == NULL) {
925
glblHadMemShortage = 1;
926
return RS_RET_OUT_OF_MEMORY;
928
memcpy(allowIP.addr.NetAddr, res->ai_addr, res->ai_addrlen);
930
if((iRet = AddAllowedSenderEntry(ppRoot, ppLast, &allowIP,
938
freeaddrinfo (restmp);
940
/* wildcards in hostname - we need to add a text-based ACL.
941
* For this, we already have everything ready and just need
942
* to pass it along...
944
iRet = AddAllowedSenderEntry(ppRoot, ppLast, iAllow, iSignificantBits);
950
#endif /* #ifdef SYSLOG_INET */
954
/* Print an allowed sender list. The caller must tell us which one.
955
* iListToPrint = 1 means UDP, 2 means TCP
956
* rgerhards, 2005-09-27
958
static void PrintAllowedSenders(int iListToPrint)
960
struct AllowedSenders *pSender;
963
assert((iListToPrint == 1) || (iListToPrint == 2));
965
printf("\nAllowed %s Senders:\n",
966
(iListToPrint == 1) ? "UDP" : "TCP");
967
pSender = (iListToPrint == 1) ?
968
pAllowedSenders_UDP : pAllowedSenders_TCP;
969
if(pSender == NULL) {
970
printf("\tNo restrictions set.\n");
972
while(pSender != NULL) {
973
if (F_ISSET(pSender->allowedSender.flags, ADDR_NAME))
974
printf ("\t%s\n", pSender->allowedSender.addr.HostWildcard);
976
if(getnameinfo (pSender->allowedSender.addr.NetAddr,
977
SALEN(pSender->allowedSender.addr.NetAddr),
978
(char*)szIP, 64, NULL, 0, NI_NUMERICHOST) == 0) {
979
printf ("\t%s/%u\n", szIP, pSender->SignificantBits);
981
/* getnameinfo() failed - but as this is only a
982
* debug function, we simply spit out an error and do
983
* not care much about it.
985
dbgprintf("\tERROR in getnameinfo() - something may be wrong "
986
"- ignored for now\n");
989
pSender = pSender->pNext;
995
/* compares a host to an allowed sender list entry. Handles all subleties
996
* including IPv4/v6 as well as domain name wildcards.
997
* This is a helper to isAllowedSender. As it is only called once, it is
999
* Returns 0 if they do not match, something else otherwise.
1000
* contributed 1007-07-16 by mildew@gmail.com
1002
static inline int MaskCmp(struct NetAddr *pAllow, uint8_t bits, struct sockaddr *pFrom, const char *pszFromHost)
1004
assert(pAllow != NULL);
1005
assert(pFrom != NULL);
1007
if(F_ISSET(pAllow->flags, ADDR_NAME)) {
1008
dbgprintf("MaskCmp: host=\"%s\"; pattern=\"%s\"\n", pszFromHost, pAllow->addr.HostWildcard);
1010
return(fnmatch(pAllow->addr.HostWildcard, pszFromHost, FNM_NOESCAPE|FNM_CASEFOLD) == 0);
1011
} else {/* We need to compare an IP address */
1012
switch (pFrom->sa_family) {
1014
if (AF_INET == pAllow->addr.NetAddr->sa_family)
1015
return(( SIN(pFrom)->sin_addr.s_addr & htonl(0xffffffff << (32 - bits)) )
1016
== SIN(pAllow->addr.NetAddr)->sin_addr.s_addr);
1021
switch (pAllow->addr.NetAddr->sa_family) {
1023
struct in6_addr ip, net;
1026
memcpy (&ip, &(SIN6(pFrom))->sin6_addr, sizeof (struct in6_addr));
1027
memcpy (&net, &(SIN6(pAllow->addr.NetAddr))->sin6_addr, sizeof (struct in6_addr));
1031
ip.s6_addr32[i++] &= htonl(0xffffffff << (32 - (bits % 32)));
1032
for (; i < (sizeof ip.s6_addr32)/4; i++)
1033
ip.s6_addr32[i] = 0;
1035
return (memcmp (ip.s6_addr, net.s6_addr, sizeof ip.s6_addr) == 0 &&
1036
(SIN6(pAllow->addr.NetAddr)->sin6_scope_id != 0 ?
1037
SIN6(pFrom)->sin6_scope_id == SIN6(pAllow->addr.NetAddr)->sin6_scope_id : 1));
1040
struct in6_addr *ip6 = &(SIN6(pFrom))->sin6_addr;
1041
struct in_addr *net = &(SIN(pAllow->addr.NetAddr))->sin_addr;
1043
if ((ip6->s6_addr32[3] & (u_int32_t) htonl((0xffffffff << (32 - bits)))) == net->s_addr &&
1044
#if BYTE_ORDER == LITTLE_ENDIAN
1045
(ip6->s6_addr32[2] == (u_int32_t)0xffff0000) &&
1047
(ip6->s6_addr32[2] == (u_int32_t)0x0000ffff) &&
1049
(ip6->s6_addr32[1] == 0) && (ip6->s6_addr32[0] == 0))
1055
/* Unsupported AF */
1059
/* Unsupported AF */
1066
/* check if a sender is allowed. The root of the the allowed sender.
1067
* list must be proveded by the caller. As such, this function can be
1068
* used to check both UDP and TCP allowed sender lists.
1069
* returns 1, if the sender is allowed, 0 otherwise.
1070
* rgerhards, 2005-09-26
1072
int isAllowedSender(struct AllowedSenders *pAllowRoot, struct sockaddr *pFrom, const char *pszFromHost)
1074
struct AllowedSenders *pAllow;
1076
assert(pFrom != NULL);
1078
if(pAllowRoot == NULL)
1079
return 1; /* checking disabled, everything is valid! */
1081
/* now we loop through the list of allowed senders. As soon as
1082
* we find a match, we return back (indicating allowed). We loop
1083
* until we are out of allowed senders. If so, we fall through the
1084
* loop and the function's terminal return statement will indicate
1085
* that the sender is disallowed.
1087
for(pAllow = pAllowRoot ; pAllow != NULL ; pAllow = pAllow->pNext) {
1088
if (MaskCmp (&(pAllow->allowedSender), pAllow->SignificantBits, pFrom, pszFromHost))
1091
dbgprintf("%s is not an allowed sender\n", pszFromHost);
1094
#endif /* #ifdef SYSLOG_INET */
1097
/* code to free all sockets within a socket table.
1098
* A socket table is a descriptor table where the zero
1099
* element has the count of elements. This is used for
1100
* listening sockets. The socket table itself is also
1102
* A POINTER to this structure must be provided, thus
1103
* double indirection!
1104
* rgerhards, 2007-06-28
1106
void freeAllSockets(int **socks)
1108
assert(socks != NULL);
1109
assert(*socks != NULL);
1111
dbgprintf("Closing socket %d.\n", (*socks)[**socks]);
1112
close((*socks)[**socks]);
1122
/*******************************************************************
1123
* BEGIN CODE-LIBLOGGING *
1124
*******************************************************************
1125
* Code in this section is borrowed from liblogging. This is an
1126
* interim solution. Once liblogging is fully integrated, this is
1127
* to be removed (see http://www.monitorware.com/liblogging for
1128
* more details. 2004-11-16 rgerhards
1130
* Please note that the orginal liblogging code is modified so that
1131
* it fits into the context of the current version of syslogd.c.
1133
* DO NOT PUT ANY OTHER CODE IN THIS BEGIN ... END BLOCK!!!!
1137
* Parse a 32 bit integer number from a string.
1139
* \param ppsz Pointer to the Pointer to the string being parsed. It
1140
* must be positioned at the first digit. Will be updated
1141
* so that on return it points to the first character AFTER
1142
* the integer parsed.
1143
* \retval The number parsed.
1146
static int srSLMGParseInt32(char** ppsz)
1151
while(isdigit((int) **ppsz))
1153
i = i * 10 + **ppsz - '0';
1162
* Parse a TIMESTAMP-3339.
1163
* updates the parse pointer position.
1165
static int srSLMGParseTIMESTAMP3339(struct syslogTime *pTime, char** ppszTS)
1167
char *pszTS = *ppszTS;
1169
assert(pTime != NULL);
1170
assert(ppszTS != NULL);
1171
assert(pszTS != NULL);
1173
pTime->year = srSLMGParseInt32(&pszTS);
1175
/* We take the liberty to accept slightly malformed timestamps e.g. in
1176
* the format of 2003-9-1T1:0:0. This doesn't hurt on receiving. Of course,
1177
* with the current state of affairs, we would never run into this code
1178
* here because at postion 11, there is no "T" in such cases ;)
1182
pTime->month = srSLMGParseInt32(&pszTS);
1183
if(pTime->month < 1 || pTime->month > 12)
1188
pTime->day = srSLMGParseInt32(&pszTS);
1189
if(pTime->day < 1 || pTime->day > 31)
1195
pTime->hour = srSLMGParseInt32(&pszTS);
1196
if(pTime->hour < 0 || pTime->hour > 23)
1201
pTime->minute = srSLMGParseInt32(&pszTS);
1202
if(pTime->minute < 0 || pTime->minute > 59)
1207
pTime->second = srSLMGParseInt32(&pszTS);
1208
if(pTime->second < 0 || pTime->second > 60)
1211
/* Now let's see if we have secfrac */
1214
char *pszStart = ++pszTS;
1215
pTime->secfrac = srSLMGParseInt32(&pszTS);
1216
pTime->secfracPrecision = (int) (pszTS - pszStart);
1220
pTime->secfracPrecision = 0;
1224
/* check the timezone */
1227
pszTS++; /* eat Z */
1228
pTime->OffsetMode = 'Z';
1229
pTime->OffsetHour = 0;
1230
pTime->OffsetMinute = 0;
1232
else if((*pszTS == '+') || (*pszTS == '-'))
1234
pTime->OffsetMode = *pszTS;
1237
pTime->OffsetHour = srSLMGParseInt32(&pszTS);
1238
if(pTime->OffsetHour < 0 || pTime->OffsetHour > 23)
1243
pTime->OffsetMinute = srSLMGParseInt32(&pszTS);
1244
if(pTime->OffsetMinute < 0 || pTime->OffsetMinute > 59)
1248
/* there MUST be TZ information */
1251
/* OK, we actually have a 3339 timestamp, so let's indicated this */
1257
/* update parse pointer */
1265
* Parse a TIMESTAMP-3164.
1266
* Returns TRUE on parse OK, FALSE on parse error.
1268
static int srSLMGParseTIMESTAMP3164(struct syslogTime *pTime, char* pszTS)
1270
assert(pTime != NULL);
1271
assert(pszTS != NULL);
1273
getCurrTime(pTime); /* obtain the current year and UTC offsets! */
1275
/* If we look at the month (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec),
1276
* we may see the following character sequences occur:
1278
* J(an/u(n/l)), Feb, Ma(r/y), A(pr/ug), Sep, Oct, Nov, Dec
1280
* We will use this for parsing, as it probably is the
1281
* fastest way to parse it.
1283
* 2005-07-18, well sometimes it pays to be a bit more verbose, even in C...
1284
* Fixed a bug that lead to invalid detection of the data. The issue was that
1285
* we had an if(++pszTS == 'x') inside of some of the consturcts below. However,
1286
* there were also some elseifs (doing the same ++), which than obviously did not
1287
* check the orginal character but the next one. Now removed the ++ and put it
1288
* into the statements below. Was a really nasty bug... I didn't detect it before
1289
* june, when it first manifested. This also lead to invalid parsing of the rest
1290
* of the message, as the time stamp was not detected to be correct. - rgerhards
1302
} else if(*pszTS == 'u') {
1307
} else if(*pszTS == 'l') {
1332
} else if(*pszTS == 'y') {
1348
} else if(*pszTS == 'u') {
1411
/* we accept a slightly malformed timestamp when receiving. This is
1412
* we accept one-digit days
1417
pTime->day = srSLMGParseInt32(&pszTS);
1418
if(pTime->day < 1 || pTime->day > 31)
1423
pTime->hour = srSLMGParseInt32(&pszTS);
1424
if(pTime->hour < 0 || pTime->hour > 23)
1429
pTime->minute = srSLMGParseInt32(&pszTS);
1430
if(pTime->minute < 0 || pTime->minute > 59)
1435
pTime->second = srSLMGParseInt32(&pszTS);
1436
if(pTime->second < 0 || pTime->second > 60)
1440
/* OK, we actually have a 3164 timestamp, so let's indicate this
1441
* and fill the rest of the properties. */
1442
pTime->timeType = 1;
1443
pTime->secfracPrecision = 0;
1448
/*******************************************************************
1449
* END CODE-LIBLOGGING *
1450
*******************************************************************/
1453
* Format a syslogTimestamp into format required by MySQL.
1454
* We are using the 14 digits format. For example 20041111122600
1455
* is interpreted as '2004-11-11 12:26:00'.
1456
* The caller must provide the timestamp as well as a character
1457
* buffer that will receive the resulting string. The function
1458
* returns the size of the timestamp written in bytes (without
1459
* the string terminator). If 0 is returend, an error occured.
1461
int formatTimestampToMySQL(struct syslogTime *ts, char* pDst, size_t iLenDst)
1463
/* currently we do not consider localtime/utc. This may later be
1464
* added. If so, I recommend using a property replacer option
1465
* and/or a global configuration option. However, we should wait
1466
* on user requests for this feature before doing anything.
1467
* rgerhards, 2007-06-26
1470
assert(pDst != NULL);
1472
if (iLenDst < 15) /* we need at least 14 bytes
1473
14 digits for timestamp + '\n' */
1476
return(snprintf(pDst, iLenDst, "%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d",
1477
ts->year, ts->month, ts->day, ts->hour, ts->minute, ts->second));
1482
* Format a syslogTimestamp to a RFC3339 timestamp string (as
1483
* specified in syslog-protocol).
1484
* The caller must provide the timestamp as well as a character
1485
* buffer that will receive the resulting string. The function
1486
* returns the size of the timestamp written in bytes (without
1487
* the string terminator). If 0 is returend, an error occured.
1489
int formatTimestamp3339(struct syslogTime *ts, char* pBuf, size_t iLenBuf)
1492
char szTZ[7]; /* buffer for TZ information */
1495
assert(pBuf != NULL);
1498
return(0); /* we NEED at least 20 bytes */
1500
/* do TZ information first, this is easier to take care of "Z" zone in rfc3339 */
1501
if(ts->OffsetMode == 'Z') {
1505
snprintf(szTZ, sizeof(szTZ) / sizeof(char), "%c%2.2d:%2.2d",
1506
ts->OffsetMode, ts->OffsetHour, ts->OffsetMinute);
1509
if(ts->secfracPrecision > 0)
1510
{ /* we now need to include fractional seconds. While doing so, we must look at
1511
* the precision specified. For example, if we have millisec precision (3 digits), a
1512
* secFrac value of 12 is not equivalent to ".12" but ".012". Obviously, this
1513
* is a huge difference ;). To avoid this, we first create a format string with
1514
* the specific precision and *then* use that format string to do the actual
1515
* formating (mmmmhhh... kind of self-modifying code... ;)).
1518
/* be careful: there is ONE actual %d in the format string below ;) */
1519
snprintf(szFmtStr, sizeof(szFmtStr),
1520
"%%04d-%%02d-%%02dT%%02d:%%02d:%%02d.%%0%dd%%s",
1521
ts->secfracPrecision);
1522
iRet = snprintf(pBuf, iLenBuf, szFmtStr, ts->year, ts->month, ts->day,
1523
ts->hour, ts->minute, ts->second, ts->secfrac, szTZ);
1526
iRet = snprintf(pBuf, iLenBuf,
1527
"%4.4d-%2.2d-%2.2dT%2.2d:%2.2d:%2.2d%s",
1528
ts->year, ts->month, ts->day,
1529
ts->hour, ts->minute, ts->second, szTZ);
1534
* Format a syslogTimestamp to a RFC3164 timestamp sring.
1535
* The caller must provide the timestamp as well as a character
1536
* buffer that will receive the resulting string. The function
1537
* returns the size of the timestamp written in bytes (without
1538
* the string termnator). If 0 is returend, an error occured.
1540
int formatTimestamp3164(struct syslogTime *ts, char* pBuf, size_t iLenBuf)
1542
static char* monthNames[13] = {"ERR", "Jan", "Feb", "Mar",
1543
"Apr", "May", "Jun", "Jul",
1544
"Aug", "Sep", "Oct", "Nov", "Dec"};
1546
assert(pBuf != NULL);
1549
return(0); /* we NEED 16 bytes */
1550
return(snprintf(pBuf, iLenBuf, "%s %2d %2.2d:%2.2d:%2.2d",
1551
monthNames[ts->month], ts->day, ts->hour,
1552
ts->minute, ts->second
1557
* Format a syslogTimestamp to a text format.
1558
* The caller must provide the timestamp as well as a character
1559
* buffer that will receive the resulting string. The function
1560
* returns the size of the timestamp written in bytes (without
1561
* the string termnator). If 0 is returend, an error occured.
1563
#if 0 /* This method is currently not called, be we like to preserve it */
1564
static int formatTimestamp(struct syslogTime *ts, char* pBuf, size_t iLenBuf)
1567
assert(pBuf != NULL);
1569
if(ts->timeType == 1) {
1570
return(formatTimestamp3164(ts, pBuf, iLenBuf));
1573
if(ts->timeType == 2) {
1574
return(formatTimestamp3339(ts, pBuf, iLenBuf));
1583
* Get the current date/time in the best resolution the operating
1584
* system has to offer (well, actually at most down to the milli-
1587
* The date and time is returned in separate fields as this is
1588
* most portable and removes the need for additional structures
1589
* (but I have to admit it is somewhat "bulky";)).
1591
* Obviously, all caller-provided pointers must not be NULL...
1593
void getCurrTime(struct syslogTime *t)
1601
gettimeofday(&tp, NULL);
1602
tm = localtime_r((time_t*) &(tp.tv_sec), &tmBuf);
1604
t->year = tm->tm_year + 1900;
1605
t->month = tm->tm_mon + 1;
1606
t->day = tm->tm_mday;
1607
t->hour = tm->tm_hour;
1608
t->minute = tm->tm_min;
1609
t->second = tm->tm_sec;
1610
t->secfrac = tp.tv_usec;
1611
t->secfracPrecision = 6;
1614
/* Solaris uses a different method of exporting the time zone.
1615
* It is UTC - localtime, which is the opposite sign of mins east of GMT.
1617
lBias = -(daylight ? altzone : timezone);
1619
lBias = tm->tm_gmtoff;
1623
t->OffsetMode = '-';
1627
t->OffsetMode = '+';
1628
t->OffsetHour = lBias / 3600;
1629
t->OffsetMinute = lBias % 3600;
1631
/* rgerhards 2004-11-09: end of helper routines. On to the
1636
443
static int usage(void)
1638
fprintf(stderr, "usage: rsyslogd [-46Adhvw] [-l hostlist] [-m markinterval] [-n] [-p path]\n" \
1639
" [-s domainlist] [-r[port]] [-tport[,max-sessions]] [-f conffile] [-i pidfile] [-x]\n");
445
fprintf(stderr, "usage: rsyslogd [-cversion] [-46AdnqQvwx] [-lhostlist] [-sdomainlist]\n"
446
" [-fconffile] [-ipidfile]\n"
447
"To run rsyslogd in native mode, use \"rsyslogd -c3 <other options>\"\n\n"
448
"For further information see http://www.rsyslog.com/doc\n");
1640
449
exit(1); /* "good" exit - done to terminate usage() */
1643
#ifdef SYSLOG_UNIXAF
1644
static int create_unix_socket(const char *path)
1646
struct sockaddr_un sunx;
1648
char line[MAXLINE +1];
1650
if (path[0] == '\0')
1653
(void) unlink(path);
1655
memset(&sunx, 0, sizeof(sunx));
1656
sunx.sun_family = AF_UNIX;
1657
(void) strncpy(sunx.sun_path, path, sizeof(sunx.sun_path));
1658
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
1659
if (fd < 0 || bind(fd, (struct sockaddr *) &sunx,
1660
SUN_LEN(&sunx)) < 0 ||
1661
chmod(path, 0666) < 0) {
1662
snprintf(line, sizeof(line), "cannot create %s", path);
1664
dbgprintf("cannot create %s (%d).\n", path, errno);
1673
/* closes the UDP listen sockets (if they exist) and frees
1674
* all dynamically assigned memory.
1676
static void closeUDPListenSockets()
1681
for (i = 0; i < *finet; i++)
1689
/* creates the UDP listen sockets
1691
static int *create_udp_socket()
1693
struct addrinfo hints, *res, *r;
1694
int error, maxs, *s, *socks, on = 1;
1697
memset(&hints, 0, sizeof(hints));
1698
hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
1699
hints.ai_family = family;
1700
hints.ai_socktype = SOCK_DGRAM;
1701
error = getaddrinfo(NULL, LogPort, &hints, &res);
1703
logerror((char*) gai_strerror(error));
1704
logerror("UDP message reception disabled due to error logged in last message.\n");
1708
/* Count max number of sockets we may open */
1709
for (maxs = 0, r = res; r != NULL ; r = r->ai_next, maxs++)
1711
socks = malloc((maxs+1) * sizeof(int));
1712
if (socks == NULL) {
1713
logerror("couldn't allocate memory for UDP sockets, suspending UDP message reception");
1718
*socks = 0; /* num of sockets counter at start of array */
1720
for (r = res; r != NULL ; r = r->ai_next) {
1721
*s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
1723
if(!(r->ai_family == PF_INET6 && errno == EAFNOSUPPORT))
1724
logerror("create_udp_socket(), socket");
1725
/* it is debatable if PF_INET with EAFNOSUPPORT should
1726
* also be ignored...
1732
if (r->ai_family == AF_INET6) {
1734
if (setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY,
1735
(char *)&ion, sizeof (ion)) < 0) {
1736
logerror("setsockopt");
1744
/* if we have an error, we "just" suspend that socket. Eventually
1745
* other sockets will work. At the end of this function, we check
1746
* if we managed to open at least one socket. If not, we'll write
1747
* a "inet suspended" message and declare failure. Else we use
1748
* what we could obtain.
1749
* rgerhards, 2007-06-22
1751
if (setsockopt(*s, SOL_SOCKET, SO_REUSEADDR,
1752
(char *) &on, sizeof(on)) < 0 ) {
1753
logerror("setsockopt(REUSEADDR)");
1759
/* We need to enable BSD compatibility. Otherwise an attacker
1760
* could flood our log files by sending us tons of ICMP errors.
1763
if (should_use_so_bsdcompat()) {
1764
if (setsockopt(*s, SOL_SOCKET, SO_BSDCOMPAT,
1765
(char *) &on, sizeof(on)) < 0) {
1766
logerror("setsockopt(BSDCOMPAT)");
1773
/* We must not block on the network socket, in case a packet
1774
* gets lost between select and recv, otherwise the process
1775
* will stall until the timeout, and other processes trying to
1776
* log will also stall.
1777
* Patch vom Colin Phipps <cph@cph.demon.co.uk> to the original
1778
* sysklogd source. Applied to rsyslogd on 2005-10-19.
1780
if ((sockflags = fcntl(*s, F_GETFL)) != -1) {
1781
sockflags |= O_NONBLOCK;
1782
/* SETFL could fail too, so get it caught by the subsequent
1785
sockflags = fcntl(*s, F_SETFL, sockflags);
1787
if (sockflags == -1) {
1788
logerror("fcntl(O_NONBLOCK)");
1794
/* rgerhards, 2007-06-22: if we run on a kernel that does not support
1795
* the IPV6_V6ONLY socket option, we need to use a work-around. On such
1796
* systems the IPv6 socket does also accept IPv4 sockets. So an IPv4
1797
* socket can not listen on the same port as an IPv6 socket. The only
1798
* workaround is to ignore the "socket in use" error. This is what we
1801
if( (bind(*s, r->ai_addr, r->ai_addrlen) < 0)
1802
# ifndef IPV6_V6ONLY
1803
&& (errno != EADDRINUSE)
1819
if(Debug && *socks != maxs)
1820
dbgprintf("We could initialize %d UDP listen sockets out of %d we received "
1821
"- this may or may not be an error indication.\n", *socks, maxs);
1824
logerror("No UDP listen socket could successfully be initialized, "
1825
"message reception via UDP disabled.\n");
1826
/* we do NOT need to free any sockets, because there were none... */
1836
453
/* function to destruct a selector_t object
1837
454
* rgerhards, 2007-08-01
1839
static rsRetVal selectorDestruct(void *pVal)
457
selectorDestruct(void *pVal)
1841
459
selector_t *pThis = (selector_t *) pVal;
1843
461
assert(pThis != NULL);
1845
463
if(pThis->pCSHostnameComp != NULL)
1846
rsCStrDestruct(pThis->pCSHostnameComp);
464
rsCStrDestruct(&pThis->pCSHostnameComp);
1847
465
if(pThis->pCSProgNameComp != NULL)
1848
rsCStrDestruct(pThis->pCSProgNameComp);
466
rsCStrDestruct(&pThis->pCSProgNameComp);
1850
468
if(pThis->f_filter_type == FILTER_PROP) {
1851
469
if(pThis->f_filterData.prop.pCSPropName != NULL)
1852
rsCStrDestruct(pThis->f_filterData.prop.pCSPropName);
470
rsCStrDestruct(&pThis->f_filterData.prop.pCSPropName);
1853
471
if(pThis->f_filterData.prop.pCSCompValue != NULL)
1854
rsCStrDestruct(pThis->f_filterData.prop.pCSCompValue);
472
rsCStrDestruct(&pThis->f_filterData.prop.pCSCompValue);
473
} else if(pThis->f_filter_type == FILTER_EXPR) {
474
if(pThis->f_filterData.f_expr != NULL)
475
expr.Destruct(&pThis->f_filterData.f_expr);
1857
478
llDestroy(&pThis->llActList);
2592
1132
if(llExecFunc(&f->llActList, processMsgDoActions, (void*)&DoActData) == RS_RET_DISCARDMSG)
2599
/* This block contains code that is only present when USE_PTHREADS is
2600
* enabled. I plan to move it to some other file, but for the time
2601
* being, I include it here because that saves me from the need to
2602
* do so many external definitons.
2603
* rgerhards, 2005-10-24
2606
/* shuts down the worker process. The worker will first finish
2607
* with the message queue. Control returns, when done.
2608
* This function is intended to be called during syslogd shutdown
2609
* AND restart (init()!).
2610
* rgerhards, 2005-10-25
2612
static void stopWorker(void)
2614
if(bRunningMultithreaded) {
2615
/* we could run single-threaded if there was an error
2616
* during startup. Then, we obviously do not need to
2617
* do anything to stop the worker ;)
2619
dbgprintf("Initiating worker thread shutdown sequence...\n");
2620
/* We are now done with all messages, so we need to wake up the
2621
* worker thread and then wait for it to finish.
2624
/* It's actually not "not empty" below but awaking the worker. The worker
2625
* then finds out that it shall terminate and does so.
2627
pthread_cond_signal(pMsgQueue->notEmpty);
2628
pthread_join(thrdWorker, NULL);
2629
bRunningMultithreaded = 0;
2630
dbgprintf("Worker thread terminated.\n");
2635
/* starts the worker thread. It must be made sure that the queue is
2636
* already existing and the worker is NOT already running.
2637
* rgerhards 2005-10-25
2639
static void startWorker(void)
2642
if(pMsgQueue != NULL) {
2643
bGlblDone = 0; /* we are NOT done (else worker would immediately terminate) */
2644
i = pthread_create(&thrdWorker, NULL, singleWorker, NULL);
2645
dbgprintf("Worker thread started with state %d.\n", i);
2646
bRunningMultithreaded = 1;
2648
dbgprintf("message queue not existing, remaining single-threaded.\n");
2653
static msgQueue *queueInit (void)
2657
q = (msgQueue *)malloc(sizeof(msgQueue));
2658
if (q == NULL) return (NULL);
2659
if((q->pbuf = malloc(sizeof(void *) * iMainMsgQueueSize)) == NULL) {
2668
q->mut = (pthread_mutex_t *) malloc (sizeof (pthread_mutex_t));
2669
pthread_mutex_init (q->mut, NULL);
2670
q->notFull = (pthread_cond_t *) malloc (sizeof (pthread_cond_t));
2671
pthread_cond_init (q->notFull, NULL);
2672
q->notEmpty = (pthread_cond_t *) malloc (sizeof (pthread_cond_t));
2673
pthread_cond_init (q->notEmpty, NULL);
2678
static void queueDelete (msgQueue *q)
2680
pthread_mutex_destroy (q->mut);
2682
pthread_cond_destroy (q->notFull);
2684
pthread_cond_destroy (q->notEmpty);
2691
/* In queueAdd() and queueDel() we have a potential race condition. If a message
2692
* is dequeued and at the same time a message is enqueued and the queue is either
2693
* full or empty, the full (or empty) indicator may be invalidly updated. HOWEVER,
2694
* this does not cause any real problems. No queue pointers can be wrong. And even
2695
* if one of the flags is set invalidly, that does not pose a real problem. If
2696
* "full" is invalidly set, at mose one message might be lost, if we are already in
2697
* a timeout situation (this is quite acceptable). And if "empty" is accidently set,
2698
* the receiver will not continue the inner loop, but break out of the outer. So no
2699
* harm is done at all. For this reason, I do not yet use a mutex to guard the two
2700
* flags - there would be a notable performance hit with, IMHO, no gain in stability
2701
* or functionality. But anyhow, now it's documented...
2702
* rgerhards, 2007-09-20
2703
* NOTE: this comment does not really apply - the callers handle the mutex, so it
2706
static void queueAdd (msgQueue *q, void* in)
2708
q->pbuf[q->tail] = in;
2710
if (q->tail == iMainMsgQueueSize)
2712
if (q->tail == q->head)
2719
static void queueDel (msgQueue *q, msg_t **out)
2721
*out = (msg_t*) q->pbuf[q->head];
2724
if (q->head == iMainMsgQueueSize)
2726
if (q->head == q->tail)
2734
/* The worker thread (so far, we have dual-threading, so only one
2735
* worker thread. Having more than one worker requires considerable
2736
* additional code review in regard to thread-safety.
2738
static void *singleWorker()
2740
msgQueue *fifo = pMsgQueue;
2744
assert(fifo != NULL);
2746
sigfillset(&sigSet);
2747
pthread_sigmask(SIG_BLOCK, &sigSet, NULL);
2749
while(!bGlblDone || !fifo->empty) {
2750
pthread_mutex_lock(fifo->mut);
2751
while (fifo->empty && !bGlblDone) {
2752
dbgprintf("singleWorker: queue EMPTY, waiting for next message.\n");
2753
pthread_cond_wait (fifo->notEmpty, fifo->mut);
2756
/* dequeue element (still protected from mutex) */
2757
queueDel(fifo, &pMsg);
2758
assert(pMsg != NULL);
2759
pthread_mutex_unlock(fifo->mut);
2760
pthread_cond_signal (fifo->notFull);
2761
/* do actual processing (the lengthy part, runs in parallel) */
2762
dbgprintf("Lone worker is running...\n");
2765
/* If you need a delay for testing, here do a */
2767
} else { /* the mutex must be unlocked in any case (important for termination) */
2768
pthread_mutex_unlock(fifo->mut);
2771
if(debugging_on && bGlblDone && !fifo->empty)
2772
dbgprintf("Worker does not yet terminate because it still has messages to process.\n");
2775
dbgprintf("Worker thread terminates\n");
2779
/* END threads-related code */
2780
#endif /* #ifdef USE_PTHREADS */
2783
/* This method enqueues a message into the the message buffer. It also
2784
* the worker thread, so that the message will be processed. If we are
2785
* compiled without PTHREADS support, we simply use this method as
2786
* an alias for processMsg().
2787
* See comment dated 2005-10-13 in logmsg() on multithreading.
2788
* rgerhards, 2005-10-24
2790
#ifndef USE_PTHREADS
2791
#define enqueueMsg(x) processMsg((x))
2793
static void enqueueMsg(msg_t *pMsg)
2796
msgQueue *fifo = pMsgQueue;
1139
/* The consumer of dequeued messages. This function is called by the
1140
* queue engine on dequeueing of a message. It runs on a SEPARATE
1142
* NOTE: Having more than one worker requires guarding of some
1143
* message object structures and potentially others - need to be checked
1144
* before we support multiple worker threads on the message queue.
1145
* Please note: the message object is destructed by the queue itself!
1148
msgConsumer(void __attribute__((unused)) *notNeeded, void *pUsr)
1151
msg_t *pMsg = (msg_t*) pUsr;
2799
1153
assert(pMsg != NULL);
2801
if(bRunningMultithreaded == 0) {
2802
/* multi-threading is not yet initialized, happens e.g.
2803
* during startup and restart. rgerhards, 2005-10-25
2805
dbgprintf("enqueueMsg: not yet running on multiple threads\n");
2808
/* "normal" mode, threading initialized */
2809
pthread_mutex_lock(fifo->mut);
2811
while (fifo->full) {
2812
dbgprintf("enqueueMsg: queue FULL.\n");
2814
clock_gettime (CLOCK_REALTIME, &t);
2817
if(pthread_cond_timedwait (fifo->notFull,
2818
fifo->mut, &t) != 0) {
2819
dbgprintf("enqueueMsg: cond timeout, dropping message!\n");
2823
queueAdd(fifo, MsgAddRef(pMsg));
2825
/* now activate the worker thread */
2826
pthread_mutex_unlock(fifo->mut);
2827
iRet = pthread_cond_signal(fifo->notEmpty);
2828
dbgprintf("EnqueueMsg signaled condition (%d)\n", iRet);
2831
#endif /* #ifndef USE_PTHREADS */
2834
1162
/* Helper to parseRFCSyslogMsg. This function parses a field up to
3242
1598
if(msg[0] == '1' && msg[1] == ' ') {
3243
1599
dbgprintf("Message has syslog-protocol format.\n");
3244
1600
setProtocolVersion(pMsg, 1);
3245
if(parseRFCSyslogMsg(pMsg, flags) == 1)
1601
if(parseRFCSyslogMsg(pMsg, flags) == 1) {
3247
1605
} else { /* we have legacy syslog */
3248
1606
dbgprintf("Message has legacy syslog format.\n");
3249
1607
setProtocolVersion(pMsg, 0);
3250
if(parseLegacySyslogMsg(pMsg, flags) == 1)
1608
if(parseLegacySyslogMsg(pMsg, flags) == 1) {
3254
1614
/* ---------------------- END PARSING ---------------- */
3256
/* rgerhards, 2005-10-13: if we consider going multi-threaded, this
3257
* is probably the best point to split between a producer and a consumer
3258
* thread. In general, with the first multi-threaded approach, we should
3259
* NOT try to do more than have a single producer and consumer, at least
3260
* if both are from the current code base. The issue is that this code
3261
* was definitely not written with reentrancy in mind and uses a lot of
3262
* global variables. So it is very dangerous to simply go ahead and multi
3263
* thread it. However, I think there is a clear distinction between
3264
* producer (where data is received) and consumer (where the actions are).
3265
* It should be fairly safe to create a single thread for each and run them
3266
* concurrently, thightly coupled via an in-memory queue. Even with this
3267
* limited multithraeding, benefits are immediate: the lengthy actions
3268
* (database writes!) are de-coupled from the receivers, what should result
3269
* in less likely message loss (loss due to receiver overrun). It also allows
3270
* us to utilize 2-cpu systems, which will soon be common given the current
3271
* advances in multicore CPU hardware. So this is well worth trying.
3272
* Another plus of this two-thread-approach would be that it can easily be configured,
3273
* so if there are compatibility issues with the threading libs, we could simply
3274
* disable it (as a makefile feature).
3275
* There is one important thing to keep in mind when doing this basic
3276
* multithreading. The syslog/tcp message forwarder manipulates a structutre
3277
* that is used by the main thread, which actually sends the data. This
3278
* structure must be guarded by a mutex, else we will have race conditions and
3279
* some very bad things could happen.
3281
* Additional consumer threads might be added relatively easy for new receivers,
3282
* e.g. if we decide to move RFC 3195 via liblogging natively into rsyslogd.
3284
* To aid this functionality, I am moving the rest of the code (the actual
3285
* consumer) to its own method, now called "processMsg()".
3287
* rgerhards, 2005-10-25: as of now, the dual-threading code is now in place.
3288
* It is an optional feature and even when enabled, rsyslogd will run single-threaded
3289
* if it gets any errors during thread creation.
1616
/* now submit the message to the main queue - then we are done */
3292
1617
pMsg->msgFlags = flags;
3297
/* rgerhards 2004-11-09: fprintlog() is the actual driver for
3298
* the output channel. It receives the channel description (f) as
3299
* well as the message and outputs them according to the channel
3300
* semantics. The message is typically already contained in the
3301
* channel save buffer (f->f_prevline). This is not only the case
3302
* when a message was already repeated but also when a new message
3304
* rgerhards 2007-08-01: interface changed to use action_t
3306
rsRetVal fprintlog(action_t *pAction)
3308
msg_t *pMsgSave; /* to save current message pointer, necessary to restore
3309
it in case it needs to be updated (e.g. repeated msgs) */
3310
pMsgSave = NULL; /* indicate message poiner not saved */
3314
/* first check if this is a regular message or the repeation of
3315
* a previous message. If so, we need to change the message text
3316
* to "last message repeated n times" and then go ahead and write
3317
* it. Please note that we can not modify the message object, because
3318
* that would update it in other selectors as well. As such, we first
3319
* need to create a local copy of the message, which we than can update.
3320
* rgerhards, 2007-07-10
3322
if(pAction->f_prevcount > 1) {
3325
snprintf((char*)szRepMsg, sizeof(szRepMsg), "last message repeated %d times",
3326
pAction->f_prevcount);
3328
if((pMsg = MsgDup(pAction->f_pMsg)) == NULL) {
3329
/* it failed - nothing we can do against it... */
3330
dbgprintf("Message duplication failed, dropping repeat message.\n");
3332
/* This return is OK. The finalizer frees strings, which are not
3333
* yet allocated. So we can not use the finalizer.
3337
/* We now need to update the other message properties.
3338
* ... RAWMSG is a problem ... Please note that digital
3339
* signatures inside the message are also invalidated.
3341
getCurrTime(&(pMsg->tRcvdAt));
3342
getCurrTime(&(pMsg->tTIMESTAMP));
3343
MsgSetMSG(pMsg, (char*)szRepMsg);
3344
MsgSetRawMsg(pMsg, (char*)szRepMsg);
3346
pMsgSave = pAction->f_pMsg; /* save message pointer for later restoration */
3347
pAction->f_pMsg = pMsg; /* use the new msg (pointer will be restored below) */
3350
dbgprintf("Called fprintlog, logging to %s", modGetStateName(pAction->pMod));
3352
pAction->f_time = now; /* we need this for message repeation processing TODO: why must "now" be global? */
3354
/* When we reach this point, we have a valid, non-disabled action.
3355
* So let's execute it. -- rgerhards, 2007-07-24
3357
/* here we must loop to process all requested strings */
3359
for(i = 0 ; i < pAction->iNumTpls ; ++i) {
3360
CHKiRet(tplToString(pAction->ppTpl[i], pAction->f_pMsg, &pAction->ppMsgs[i]));
3362
/* call configured action */
3363
iRet = pAction->pMod->mod.om.doAction(pAction->ppMsgs, pAction->f_pMsg->msgFlags, pAction->pModData);
3365
if(iRet == RS_RET_DISABLE_ACTION) {
3366
dbgprintf("Action requested to be disabled, done that.\n");
3367
pAction->bEnabled = 0; /* that's it... */
3370
if(iRet == RS_RET_SUSPENDED) {
3371
dbgprintf("Action requested to be suspended, done that.\n");
3372
actionSuspend(pAction);
3375
if(iRet == RS_RET_OK)
3376
pAction->f_prevcount = 0; /* message process, so we start a new cycle */
3380
for(i = 0 ; i < pAction->iNumTpls ; ++i) {
3381
if(pAction->ppMsgs[i] != NULL) {
3382
free(pAction->ppMsgs[i]);
3383
pAction->ppMsgs[i] = NULL;
3387
if(pMsgSave != NULL) {
3388
/* we had saved the original message pointer. That was
3389
* done because we needed to create a temporary one
3390
* (most often for "message repeated n time" handling. If so,
3391
* we need to restore the original one now, so that procesing
3392
* can continue as normal. We also need to discard the temporary
3393
* one, as we do not like memory leaks ;) Please note that the original
3394
* message object will be discarded by our callers, so this is nothing
3395
* of our buisiness. rgerhards, 2007-07-10
3397
MsgDestruct(pAction->f_pMsg);
3398
pAction->f_pMsg = pMsgSave; /* restore it */
3405
static void reapchild()
1618
MsgPrepareEnqueue(pMsg);
1619
queueEnqObj(pMsgQueue, pMsg->flowCtlType, (void*) pMsg);
3407
1627
int saved_errno = errno;
3408
1628
struct sigaction sigAct;
3674
/* parse an allowed sender config line and add the allowed senders
3675
* (if the line is correct).
3676
* rgerhards, 2005-09-27
3678
static rsRetVal addAllowedSenderLine(char* pName, uchar** ppRestOfConfLine)
3681
struct AllowedSenders **ppRoot;
3682
struct AllowedSenders **ppLast;
3685
struct NetAddr *uIP = NULL;
3689
assert(pName != NULL);
3690
assert(ppRestOfConfLine != NULL);
3691
assert(*ppRestOfConfLine != NULL);
3695
logerror("config file contains allowed sender list, but rsyslogd "
3696
"compiled without Internet support - line ignored");
3699
if(!strcasecmp(pName, "udp")) {
3700
ppRoot = &pAllowedSenders_UDP;
3701
ppLast = &pLastAllowedSenders_UDP;
3702
} else if(!strcasecmp(pName, "tcp")) {
3703
ppRoot = &pAllowedSenders_TCP;
3704
ppLast = &pLastAllowedSenders_TCP;
3706
logerrorSz("Invalid protocol '%s' in allowed sender "
3707
"list, line ignored", pName);
3711
/* OK, we now know the protocol and have valid list pointers.
3712
* So let's process the entries. We are using the parse class
3715
/* create parser object starting with line string without leading colon */
3716
if((iRet = rsParsConstructFromSz(&pPars, (uchar*) *ppRestOfConfLine) != RS_RET_OK)) {
3717
logerrorInt("Error %d constructing parser object - ignoring allowed sender list", iRet);
3721
while(!parsIsAtEndOfParseString(pPars)) {
3722
if(parsPeekAtCharAtParsPtr(pPars) == '#')
3723
break; /* a comment-sign stops processing of line */
3724
/* now parse a single IP address */
3725
if((iRet = parsAddrWithBits(pPars, &uIP, &iBits)) != RS_RET_OK) {
3726
logerrorInt("Error %d parsing address in allowed sender"
3727
"list - ignoring.", iRet);
3728
rsParsDestruct(pPars);
3731
if((iRet = AddAllowedSender(ppRoot, ppLast, uIP, iBits))
3733
logerrorInt("Error %d adding allowed sender entry "
3734
"- ignoring.", iRet);
3735
rsParsDestruct(pPars);
3738
free (uIP); /* copy stored in AllowedSenders list */
3742
*ppRestOfConfLine += parsGetCurrentPosition(pPars);
3743
return rsParsDestruct(pPars);
3744
#endif /*#ifndef SYSLOG_INET */
3748
/* process a directory and include all of its files into
3749
* the current config file. There is no specific order of inclusion,
3750
* files are included in the order they are read from the directory.
3751
* The caller must have make sure that the provided parameter is
3752
* indeed a directory.
3753
* rgerhards, 2007-08-01
3755
static rsRetVal doIncludeDirectory(uchar *pDirName)
3758
int iEntriesDone = 0;
3762
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
3766
size_t iFileNameLen;
3767
uchar szFullFileName[MAXFNAME];
3769
assert(pDirName != NULL);
3771
if((pDir = opendir((char*) pDirName)) == NULL) {
3772
logerror("error opening include directory");
3773
ABORT_FINALIZE(RS_RET_FOPEN_FAILURE);
3776
/* prepare file name buffer */
3777
iDirNameLen = strlen((char*) pDirName);
3778
memcpy(szFullFileName, pDirName, iDirNameLen);
3780
/* now read the directory */
3782
while(readdir_r(pDir, &u.d, &res) == 0) {
3784
break; /* this also indicates end of directory */
3785
if(res->d_type != DT_REG)
3786
continue; /* we are not interested in special files */
3787
if(res->d_name[0] == '.')
3788
continue; /* these files we are also not interested in */
3790
/* construct filename */
3791
iFileNameLen = strnlen(res->d_name, NAME_MAX);
3792
memcpy(szFullFileName + iDirNameLen, res->d_name, iFileNameLen);
3793
*(szFullFileName + iDirNameLen + iFileNameLen) = '\0';
3794
dbgprintf("including file '%s'\n", szFullFileName);
3795
processConfFile(szFullFileName);
3796
/* we deliberately ignore the iRet of processConfFile() - this is because
3797
* failure to process one file does not mean all files will fail. By ignoring,
3798
* we retry with the next file, which is the best thing we can do. -- rgerhards, 2007-08-01
3802
if(iEntriesDone == 0) {
3803
/* I just make it a debug output, because I can think of a lot of cases where it
3804
* makes sense not to have any files. E.g. a system maintainer may place a $Include
3805
* into the config file just in case, when additional modules be installed. When none
3806
* are installed, the directory will be empty, which is fine. -- rgerhards 2007-08-01
3808
dbgprintf("warning: the include directory contained no files - this may be ok.\n");
3819
/* process a $include config line. That type of line requires
3820
* inclusion of another file.
3821
* rgerhards, 2007-08-01
3823
static rsRetVal doIncludeLine(uchar **pp, __attribute__((unused)) void* pVal)
3826
uchar cfgFile[MAXFNAME];
3829
assert(*pp != NULL);
3831
if(getSubString(pp, (char*) cfgFile, sizeof(cfgFile) / sizeof(uchar), ' ') != 0) {
3832
logerror("could not extract group name");
3833
ABORT_FINALIZE(RS_RET_NOT_FOUND);
3836
if(*(cfgFile+strlen((char*) cfgFile) - 1) == '/') {
3837
dbgprintf("requested to include directory '%s'\n", cfgFile);
3838
iRet = doIncludeDirectory(cfgFile);
3840
dbgprintf("Requested to include config file '%s'\n", cfgFile);
3841
iRet = processConfFile(cfgFile);
3849
/* process a $ModLoad config line.
3850
* As of now, it is a dummy, that will later evolve into the
3851
* loader for plug-ins.
3852
* rgerhards, 2007-07-21
3853
* varmojfekoj added support for dynamically loadable modules on 2007-08-13
3854
* rgerhards, 2007-09-25: please note that the non-threadsafe function dlerror() is
3855
* called below. This is ok because modules are currently only loaded during
3856
* configuration file processing, which is executed on a single thread. Should we
3857
* change that design at any stage (what is unlikely), we need to find a
3860
static rsRetVal doModLoad(uchar **pp, __attribute__((unused)) void* pVal)
3867
void *pModHdlr, *pModInit;
3870
assert(*pp != NULL);
3872
if(getSubString(pp, (char*) szName, sizeof(szName) / sizeof(uchar), ' ') != 0) {
3873
logerror("could not extract module name");
3874
ABORT_FINALIZE(RS_RET_NOT_FOUND);
3877
/* this below is a quick and dirty hack to provide compatibility with the
3878
* $ModLoad MySQL forward compatibility statement. TODO: clean this up
3879
* For the time being, it is clean enough, it just needs to be done
3880
* differently when we have a full design for loadable plug-ins. For the
3881
* time being, we just mangle the names a bit.
3882
* rgerhards, 2007-08-14
3884
if(!strcmp((char*) szName, "MySQL"))
3885
pModName = (uchar*) "ommysql.so";
3889
dbgprintf("Requested to load module '%s'\n", szName);
3891
if(*pModName == '/') {
3892
*szPath = '\0'; /* we do not need to append the path - its already in the module name */
3894
strncpy((char *) szPath, (pModDir == NULL) ? _PATH_MODDIR : (char*) pModDir, sizeof(szPath));
3896
strncat((char *) szPath, (char *) pModName, sizeof(szPath) - strlen((char*) szPath) - 1);
3897
if(!(pModHdlr = dlopen((char *) szPath, RTLD_NOW))) {
3898
snprintf((char *) errMsg, sizeof(errMsg), "could not load module '%s', dlopen: %s\n", szPath, dlerror());
3899
errMsg[sizeof(errMsg)/sizeof(uchar) - 1] = '\0';
3900
logerror((char *) errMsg);
3901
ABORT_FINALIZE(RS_RET_ERR);
3903
if(!(pModInit = dlsym(pModHdlr, "modInit"))) {
3904
snprintf((char *) errMsg, sizeof(errMsg), "could not load module '%s', dlsym: %s\n", szPath, dlerror());
3905
errMsg[sizeof(errMsg)/sizeof(uchar) - 1] = '\0';
3906
logerror((char *) errMsg);
3908
ABORT_FINALIZE(RS_RET_ERR);
3910
if((iRet = doModInit(pModInit, (uchar*) pModName, pModHdlr)) != RS_RET_OK)
3913
skipWhiteSpace(pp); /* skip over any whitespace */
3919
/* parse and interpret a $-config line that starts with
3920
* a name (this is common code). It is parsed to the name
3921
* and then the proper sub-function is called to handle
3922
* the actual directive.
3923
* rgerhards 2004-11-17
3924
* rgerhards 2005-06-21: previously only for templates, now
3927
static rsRetVal doNameLine(uchar **pp, void* pVal)
3931
enum eDirective eDir;
3938
eDir = (enum eDirective) pVal; /* this time, it actually is NOT a pointer! */
3940
if(getSubString(&p, szName, sizeof(szName) / sizeof(char), ',') != 0) {
3941
logerror("Invalid config line: could not extract name - line ignored");
3942
ABORT_FINALIZE(RS_RET_NOT_FOUND);
3945
++p; /* comma was eaten */
3947
/* we got the name - now we pass name & the rest of the string
3948
* to the subfunction. It makes no sense to do further
3949
* parsing here, as this is in close interaction with the
3950
* respective subsystem. rgerhards 2004-11-17
3955
tplAddLine(szName, &p);
3957
case DIR_OUTCHANNEL:
3958
ochAddLine(szName, &p);
3960
case DIR_ALLOWEDSENDER:
3961
addAllowedSenderLine(szName, &p);
3963
default:/* we do this to avoid compiler warning - not all
3964
* enum values call this function, so an incomplete list
3965
* is quite ok (but then we should not run into this code,
3966
* so at least we log a debug warning).
3968
dbgprintf("INTERNAL ERROR: doNameLine() called with invalid eDir %d.\n",
3980
1980
/* set the action resume interval
3982
1982
static rsRetVal setActionResumeInterval(void __attribute__((unused)) *pVal, int iNewVal)
4122
2070
int iSelNbr = 1;
4125
printf("\nActive selectors:\n");
2073
dbgprintf("\nActive selectors:\n");
4126
2074
for (f = Files; f != NULL ; f = f->f_next) {
4127
printf("Selector %d:\n", iSelNbr++);
2075
dbgprintf("Selector %d:\n", iSelNbr++);
4128
2076
if(f->pCSProgNameComp != NULL)
4129
printf("tag: '%s'\n", rsCStrGetSzStrNoNULL(f->pCSProgNameComp));
2077
dbgprintf("tag: '%s'\n", rsCStrGetSzStrNoNULL(f->pCSProgNameComp));
4130
2078
if(f->eHostnameCmpMode != HN_NO_COMP)
4131
printf("hostname: %s '%s'\n",
2079
dbgprintf("hostname: %s '%s'\n",
4132
2080
f->eHostnameCmpMode == HN_COMP_MATCH ?
4133
2081
"only" : "allbut",
4134
2082
rsCStrGetSzStrNoNULL(f->pCSHostnameComp));
4135
2083
if(f->f_filter_type == FILTER_PRI) {
4136
2084
for (i = 0; i <= LOG_NFACILITIES; i++)
4137
2085
if (f->f_filterData.f_pmask[i] == TABLE_NOPRI)
4140
printf("%2X ", f->f_filterData.f_pmask[i]);
2088
dbgprintf("%2X ", f->f_filterData.f_pmask[i]);
2089
} else if(f->f_filter_type == FILTER_EXPR) {
2090
dbgprintf("EXPRESSION-BASED Filter: can currently not be displayed");
4142
printf("PROPERTY-BASED Filter:\n");
4143
printf("\tProperty.: '%s'\n",
2092
dbgprintf("PROPERTY-BASED Filter:\n");
2093
dbgprintf("\tProperty.: '%s'\n",
4144
2094
rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSPropName));
4145
printf("\tOperation: ");
2095
dbgprintf("\tOperation: ");
4146
2096
if(f->f_filterData.prop.isNegated)
4148
printf("'%s'\n", getFIOPName(f->f_filterData.prop.operation));
4149
printf("\tValue....: '%s'\n",
2098
dbgprintf("'%s'\n", getFIOPName(f->f_filterData.prop.operation));
2099
dbgprintf("\tValue....: '%s'\n",
4150
2100
rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSCompValue));
4151
printf("\tAction...: ");
2101
dbgprintf("\tAction...: ");
4154
printf("\nActions:\n");
2104
dbgprintf("\nActions:\n");
4155
2105
llExecFunc(&f->llActList, dbgPrintInitInfoAction, NULL); /* actions */
4160
2110
if(bDebugPrintTemplateList)
4161
2111
tplPrintList();
4162
2112
if(bDebugPrintModuleList)
4164
2114
ochPrintList();
4166
2116
if(bDebugPrintCfSysLineHandlerList)
4167
2117
dbgPrintCfSysLineHandlers();
4170
/* now the allowedSender lists: */
4171
PrintAllowedSenders(1); /* UDP */
4172
PrintAllowedSenders(2); /* TCP */
4174
#endif /* #ifdef SYSLOG_INET */
4176
printf("Messages with malicious PTR DNS Records are %sdropped.\n",
2119
dbgprintf("Messages with malicious PTR DNS Records are %sdropped.\n",
4177
2120
bDropMalPTRMsgs ? "" : "not ");
4179
printf("Control characters are %sreplaced upon reception.\n",
2122
dbgprintf("Control characters are %sreplaced upon reception.\n",
4180
2123
bEscapeCCOnRcv? "" : "not ");
4182
2125
if(bEscapeCCOnRcv)
4183
printf("Control character escape sequence prefix is '%c'.\n",
2126
dbgprintf("Control character escape sequence prefix is '%c'.\n",
4184
2127
cCCEscapeChar);
4187
printf("Main queue size %d messages.\n", iMainMsgQueueSize);
2129
dbgprintf("Main queue size %d messages.\n", iMainMsgQueueSize);
2130
dbgprintf("Main queue worker threads: %d, Perists every %d updates.\n",
2131
iMainMsgQueueNumWorkers, iMainMsgQPersistUpdCnt);
2132
dbgprintf("Main queue timeouts: shutdown: %d, action completion shutdown: %d, enq: %d\n",
2133
iMainMsgQtoQShutdown, iMainMsgQtoActShutdown, iMainMsgQtoEnq);
2134
dbgprintf("Main queue watermarks: high: %d, low: %d, discard: %d, discard-severity: %d\n",
2135
iMainMsgQHighWtrMark, iMainMsgQLowWtrMark, iMainMsgQDiscardMark, iMainMsgQDiscardSeverity);
2136
dbgprintf("Main queue save on shutdown %d, max disk space allowed %lld\n",
2137
bMainMsgQSaveOnShutdown, iMainMsgQueMaxDiskSpace);
2139
iActionRetryCount = 0;
2140
iActionRetryInterval = 30000;
2141
static int iMainMsgQtoWrkShutdown = 60000;
2142
static int iMainMsgQtoWrkMinMsgs = 100;
2143
static int iMainMsgQbSaveOnShutdown = 1;
2144
iMainMsgQueMaxDiskSpace = 0;
2145
setQPROP(queueSettoWrkShutdown, "$MainMsgQueueTimeoutWorkerThreadShutdown", 5000);
2146
setQPROP(queueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", 100);
2147
setQPROP(queueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", 1);
2149
dbgprintf("Work Directory: '%s'.\n", pszWorkDir);
4192
/* process a configuration file
4193
* started with code from init() by rgerhards on 2007-07-31
2153
/* Start the input modules. This function will probably undergo big changes
2154
* while we implement the input module interface. For now, it does the most
2155
* important thing to get at least my poor initial input modules up and
2156
* running. Almost no config option is taken.
2157
* rgerhards, 2007-12-14
4195
static rsRetVal processConfFile(uchar *pConfFile)
2160
startInputModules(void)
4200
selector_t *fCurr = NULL;
4206
uchar cline[BUFSIZ];
4208
assert(pConfFile != NULL);
4210
if((cf = fopen((char*)pConfFile, "r")) == NULL) {
4211
ABORT_FINALIZE(RS_RET_FOPEN_FAILURE);
4214
/* Now process the file.
4218
while (fgets((char*)cline, sizeof(cbuf) - (cline - cbuf), cf) != NULL) {
4220
while (fgets(cline, sizeof(cline), cf) != NULL) {
4223
/* drop LF - TODO: make it better, replace fgets(), but its clean as it is */
4224
if(cline[strlen((char*)cline)-1] == '\n') {
4225
cline[strlen((char*)cline) -1] = '\0';
4227
/* check for end-of-section, comments, strip off trailing
4228
* spaces and newline character.
4232
if (*p == '\0' || *p == '#')
4236
strcpy((char*)cline, (char*)p);
4238
for (p = (uchar*) strchr((char*)cline, '\0'); isspace((int) *--p););
4241
if ((p - cbuf) > BUFSIZ - 30) {
4242
/* Oops the buffer is full - what now? */
4252
*++p = '\0'; // TODO: check this
4254
/* we now have the complete line, and are positioned at the first non-whitespace
4255
* character. So let's process it
4258
if(cfline(cbuf, &fCurr) != RS_RET_OK) {
4260
if(cfline((uchar*)cline, &fCurr) != RS_RET_OK) {
4262
/* we log a message, but otherwise ignore the error. After all, the next
4263
* line can be correct. -- rgerhards, 2007-08-02
4265
uchar szErrLoc[MAXFNAME + 64];
4266
dbgprintf("config line NOT successfully processed\n");
4267
snprintf((char*)szErrLoc, sizeof(szErrLoc) / sizeof(uchar),
4268
"%s, line %d", pConfFile, iLnNbr);
4269
logerrorSz("the last error occured in %s", (char*)szErrLoc);
4273
/* we probably have one selector left to be added - so let's do that now */
4274
CHKiRet(selectorAddList(fCurr));
4276
/* close the configuration file */
4280
if(iRet != RS_RET_OK) {
4283
selectorDestruct(fCurr);
4284
dbgprintf("error %d processing config file '%s'; os error (if any): %s\n",
4285
iRet, pConfFile, strerror_r(errno, errStr, sizeof(errStr)));
2165
/* loop through all modules and activate them (brr...) */
2166
pMod = module.GetNxtType(NULL, eMOD_IN);
2167
while(pMod != NULL) {
2168
if((iRet = pMod->mod.im.willRun()) == RS_RET_OK) {
2170
thrdCreate(pMod->mod.im.runInput, pMod->mod.im.afterRun);
2172
dbgprintf("module %lx will not run, iRet %d\n", (unsigned long) pMod, iRet);
2174
pMod = module.GetNxtType(pMod, eMOD_IN);
2178
return RS_RET_OK; /* intentional: we do not care about module errors */
4291
2182
/* INIT -- Initialize syslogd from configuration table
4292
2183
* init() is called at initial startup AND each time syslogd is HUPed
4294
static void init(void)
4299
2189
char cbuf[BUFSIZ];
4303
2190
char bufStartUpMsg[512];
4305
2191
struct sigaction sigAct;
2193
thrdTerminateAll(); /* stop all running input threads - TODO: reconsider location! */
4307
2195
/* initialize some static variables */
4308
2196
pDfltHostnameCmp = NULL;
4309
2197
pDfltProgNameCmp = NULL;
4310
2198
eDfltHostnameCmpMode = HN_NO_COMP;
4315
if (pAllowedSenders_UDP != NULL) {
4316
clearAllowedSenders (pAllowedSenders_UDP);
4317
pAllowedSenders_UDP = NULL;
4320
if (pAllowedSenders_TCP != NULL) {
4321
clearAllowedSenders (pAllowedSenders_TCP);
4322
pAllowedSenders_TCP = NULL;
4326
assert (pAllowedSenders_UDP == NULL &&
4327
pAllowedSenders_TCP == NULL );
4329
/* I was told by an IPv6 expert that calling getservbyname() seems to be
4330
* still valid, at least for the use case we have. So I re-enabled that
4331
* code. rgerhards, 2007-07-02
4333
if(!strcmp(LogPort, "0")) {
4334
/* we shall use the default syslog/udp port, so let's
4336
* NOTE: getservbyname() is not thread-safe, but this is OK as
4337
* it is called only during init, in single-threading mode.
4339
sp = getservbyname("syslog", "udp");
4342
logerror("Could not find syslog/udp port in /etc/services. "
4343
"Now using IANA-assigned default of 514.");
4346
/* we can dynamically allocate memory here and do NOT need
4347
* to care about freeing it because even though init() is
4348
* called on each restart, the LogPort can never again be
4349
* "0". So we will only once run into this part of the code
4350
* here. rgerhards, 2007-07-02
4351
* We save ourselfs the hassle of dynamic memory management
4352
* for the very same reason.
4354
static char defPort[8];
4355
snprintf(defPort, sizeof(defPort), "%d", ntohs(sp->s_port));
4360
2200
dbgprintf("rsyslog %s.\n", VERSION);
4361
2201
dbgprintf("Called init.\n");
4363
/* Close all open log files and free log descriptor array. */
2203
/* delete the message queue, which also flushes all messages left over */
2204
if(pMsgQueue != NULL) {
2205
dbgprintf("deleting main message queue\n");
2206
queueDestruct(&pMsgQueue); /* delete pThis here! */
2210
/* Close all open log files and free log descriptor array. This also frees
2211
* all output-modules instance data.
4364
2213
freeSelectors();
4366
2215
/* Unload all non-static modules */
4367
2216
dbgprintf("Unloading non-static modules.\n");
4368
modUnloadAndDestructDynamic();
2217
module.UnloadAndDestructAll(eMOD_LINK_DYNAMIC_LOADED);
4370
2219
dbgprintf("Clearing templates.\n");
4371
2220
tplDeleteNew();
4374
if(pMsgQueue != NULL) {
4375
dbgprintf("deleting message queue\n");
4376
queueDelete(pMsgQueue); /* delete fifo here! */
4381
2222
/* re-setting values to defaults (where applicable) */
4382
2223
/* TODO: once we have loadable modules, we must re-visit this code. The reason is
4383
2224
* that config variables are not re-set, because the module is not yet loaded. On
4397
2238
* We ignore any errors while doing this - we would be lost anyhow...
4399
2240
selector_t *f = NULL;
4400
char szTTYNameBuf[TTY_NAME_MAX+1]; /* +1 for NULL character */
2241
char szTTYNameBuf[_POSIX_TTY_NAME_MAX+1]; /* +1 for NULL character */
4401
2242
dbgprintf("primary config file could not be opened - using emergency definitions.\n");
4402
cfline((uchar*)"*.ERR\t" _PATH_CONSOLE, &f);
4403
cfline((uchar*)"*.PANIC\t*", &f);
2243
conf.cfline((uchar*)"*.ERR\t" _PATH_CONSOLE, &f);
2244
conf.cfline((uchar*)"*.PANIC\t*", &f);
4404
2245
if(ttyname_r(0, szTTYNameBuf, sizeof(szTTYNameBuf)) == 0) {
4405
2246
snprintf(cbuf,sizeof(cbuf), "*.*\t%s", szTTYNameBuf);
4406
cfline((uchar*)cbuf, &f);
2247
conf.cfline((uchar*)cbuf, &f);
4408
2249
selectorAddList(f);
4411
2254
/* we are now done with reading the configuration. This is the right time to
4412
2255
* free some objects that were just needed for loading it. rgerhards 2005-10-19
4414
2257
if(pDfltHostnameCmp != NULL) {
4415
rsCStrDestruct(pDfltHostnameCmp);
4416
pDfltHostnameCmp = NULL;
2258
rsCStrDestruct(&pDfltHostnameCmp);
4419
2261
if(pDfltProgNameCmp != NULL) {
4420
rsCStrDestruct(pDfltProgNameCmp);
4421
pDfltProgNameCmp = NULL;
4424
#ifdef SYSLOG_UNIXAF
4425
for (i = startIndexUxLocalSockets ; i < nfunix ; i++) {
4427
/* Don't close the socket, preserve it instead
4431
if ((funix[i] = create_unix_socket(funixn[i])) != -1)
4432
dbgprintf("Opened UNIX socket `%s' (fd %d).\n", funixn[i], funix[i]);
4437
/* I have moved initializing UDP sockets before the TCP sockets. This ensures
4438
* they are as soon ready for reception as possible. Of course, it is only a
4439
* very small window of exposure, but it doesn't hurt to limit the message
4440
* loss risk to as low as possible - especially if it costs nothing...
4441
* rgerhards, 2007-06-28
4443
if(Forwarding || AcceptRemote) {
4444
if (finet == NULL) {
4445
if((finet = create_udp_socket()) != NULL)
4446
dbgprintf("Opened %d syslog UDP port(s).\n", *finet);
4449
/* this case can happen during HUP processing. */
4450
closeUDPListenSockets();
4454
if(sockTCPLstn == NULL) {
4455
/* even when doing a re-init, we do not shut down and
4456
* re-open the TCP socket. That would break existing TCP
4457
* session, which we do not desire. Should at some time arise
4458
* need to do that, I recommend controlling that via a
4459
* user-selectable option. rgerhards, 2007-06-21
4461
if((sockTCPLstn = create_tcp_socket()) != NULL) {
4462
dbgprintf("Opened %d syslog TCP port(s).\n", *sockTCPLstn);
4468
# ifdef USE_PTHREADS
2262
rsCStrDestruct(&pDfltProgNameCmp);
2266
if(iMainMsgQueueNumWorkers < 1) {
2267
errmsg.LogError(NO_ERRCODE, "$MainMsgQueueNumWorkers must be at least 1! Set to 1.\n");
2268
iMainMsgQueueNumWorkers = 1;
2271
if(MainMsgQueType == QUEUETYPE_DISK) {
2272
errno = 0; /* for logerror! */
2273
if(pszWorkDir == NULL) {
2274
errmsg.LogError(NO_ERRCODE, "No $WorkDirectory specified - can not run main message queue in 'disk' mode. "
2275
"Using 'FixedArray' instead.\n");
2276
MainMsgQueType = QUEUETYPE_FIXED_ARRAY;
2278
if(pszMainMsgQFName == NULL) {
2279
errmsg.LogError(NO_ERRCODE, "No $MainMsgQueueFileName specified - can not run main message queue in "
2280
"'disk' mode. Using 'FixedArray' instead.\n");
2281
MainMsgQueType = QUEUETYPE_FIXED_ARRAY;
2285
/* switch the message object to threaded operation, if necessary */
2286
if(MainMsgQueType == QUEUETYPE_DIRECT || iMainMsgQueueNumWorkers > 1) {
2287
MsgEnableThreadSafety();
4469
2290
/* create message queue */
4470
pMsgQueue = queueInit();
4471
if(pMsgQueue == NULL) {
4473
logerror("error: could not create message queue - running single-threaded!\n");
2291
CHKiRet_Hdlr(queueConstruct(&pMsgQueue, MainMsgQueType, iMainMsgQueueNumWorkers, iMainMsgQueueSize, msgConsumer)) {
2292
/* no queue is fatal, we need to give up in that case... */
2293
fprintf(stderr, "fatal error %d: could not create message queue - rsyslogd can not run!\n", iRet);
2296
/* name our main queue object (it's not fatal if it fails...) */
2297
obj.SetName((obj_t*) pMsgQueue, (uchar*) "main queue");
2299
/* ... set some properties ... */
2300
# define setQPROP(func, directive, data) \
2301
CHKiRet_Hdlr(func(pMsgQueue, data)) { \
2302
errmsg.LogError(NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \
2304
# define setQPROPstr(func, directive, data) \
2305
CHKiRet_Hdlr(func(pMsgQueue, data, (data == NULL)? 0 : strlen((char*) data))) { \
2306
errmsg.LogError(NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \
2309
setQPROP(queueSetMaxFileSize, "$MainMsgQueueFileSize", iMainMsgQueMaxFileSize);
2310
setQPROP(queueSetsizeOnDiskMax, "$MainMsgQueueMaxDiskSpace", iMainMsgQueMaxDiskSpace);
2311
setQPROPstr(queueSetFilePrefix, "$MainMsgQueueFileName", pszMainMsgQFName);
2312
setQPROP(queueSetiPersistUpdCnt, "$MainMsgQueueCheckpointInterval", iMainMsgQPersistUpdCnt);
2313
setQPROP(queueSettoQShutdown, "$MainMsgQueueTimeoutShutdown", iMainMsgQtoQShutdown );
2314
setQPROP(queueSettoActShutdown, "$MainMsgQueueTimeoutActionCompletion", iMainMsgQtoActShutdown);
2315
setQPROP(queueSettoWrkShutdown, "$MainMsgQueueWorkerTimeoutThreadShutdown", iMainMsgQtoWrkShutdown);
2316
setQPROP(queueSettoEnq, "$MainMsgQueueTimeoutEnqueue", iMainMsgQtoEnq);
2317
setQPROP(queueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", iMainMsgQHighWtrMark);
2318
setQPROP(queueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", iMainMsgQLowWtrMark);
2319
setQPROP(queueSetiDiscardMrk, "$MainMsgQueueDiscardMark", iMainMsgQDiscardMark);
2320
setQPROP(queueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", iMainMsgQDiscardSeverity);
2321
setQPROP(queueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", iMainMsgQWrkMinMsgs);
2322
setQPROP(queueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", bMainMsgQSaveOnShutdown);
2323
setQPROP(queueSetiDeqSlowdown, "$MainMsgQueueDequeueSlowdown", iMainMsgQDeqSlowdown);
2328
/* ... and finally start the queue! */
2329
CHKiRet_Hdlr(queueStart(pMsgQueue)) {
2330
/* no queue is fatal, we need to give up in that case... */
2331
fprintf(stderr, "fatal error %d: could not start message queue - rsyslogd can not run!\n", iRet);
2335
bHaveMainQueue = (MainMsgQueType == QUEUETYPE_DIRECT) ? 0 : 1;
2336
dbgprintf("Main processing queue is initialized and running\n");
2338
/* the output part and the queue is now ready to run. So it is a good time
2339
* to start the inputs. Please note that the net code above should be
2340
* shuffled to down here once we have everything in input modules.
2341
* rgerhards, 2007-12-14
2343
startInputModules();
4482
2346
dbgPrintInitInfo();
4505
2360
sigAct.sa_handler = sighup_handler;
4506
2361
sigaction(SIGHUP, &sigAct, NULL);
4508
dbgprintf(" restarted.\n");
4512
/* Helper to cfline() and its helpers. Parses a template name
4513
* from an "action" line. Must be called with the Line pointer
4514
* pointing to the first character after the semicolon.
4515
* rgerhards 2004-11-19
4516
* changed function to work with OMSR. -- rgerhards, 2007-07-27
4517
* the default template is to be used when no template is specified.
4519
rsRetVal cflineParseTemplateName(uchar** pp, omodStringRequest_t *pOMSR, int iEntry, int iTplOpts, uchar *dfltTplName)
4527
assert(*pp != NULL);
4528
assert(pOMSR != NULL);
4531
/* a template must follow - search it and complain, if not found
4536
else if(*p != '\0' && *p != '#') {
4537
logerror("invalid character in selector line - ';template' expected");
4542
skipWhiteSpace(&p); /* go to begin of template name */
4545
/* no template specified, use the default */
4546
/* TODO: check NULL ptr */
4547
tplName = (uchar*) strdup((char*)dfltTplName);
4549
/* template specified, pick it up */
4550
if((pStrB = rsCStrConstruct()) == NULL) {
4551
glblHadMemShortage = 1;
4552
iRet = RS_RET_OUT_OF_MEMORY;
4556
/* now copy the string */
4557
while(*p && *p != '#' && !isspace((int) *p)) {
4558
CHKiRet(rsCStrAppendChar(pStrB, *p));
4561
CHKiRet(rsCStrFinish(pStrB));
4562
CHKiRet(rsCStrConvSzStrAndDestruct(pStrB, &tplName, 0));
4565
iRet = OMSRsetEntry(pOMSR, iEntry, tplName, iTplOpts);
4566
if(iRet != RS_RET_OK) goto finalize_it;
4574
/* Helper to cfline(). Parses a file name up until the first
4575
* comma and then looks for the template specifier. Tries
4576
* to find that template.
4577
* rgerhards 2004-11-18
4578
* parameter pFileName must point to a buffer large enough
4579
* to hold the largest possible filename.
4580
* rgerhards, 2007-07-25
4581
* updated to include OMSR pointer -- rgerhards, 2007-07-27
4583
rsRetVal cflineParseFileName(uchar* p, uchar *pFileName, omodStringRequest_t *pOMSR, int iEntry, int iTplOpts)
4585
register uchar *pName;
4589
assert(pOMSR != NULL);
4592
i = 1; /* we start at 1 so that we reseve space for the '\0'! */
4593
while(*p && *p != ';' && i < MAXFNAME) {
4599
iRet = cflineParseTemplateName(&p, pOMSR, iEntry, iTplOpts, (uchar*) " TradFmt");
4606
* Helper to cfline(). This function takes the filter part of a traditional, PRI
4607
* based line and decodes the PRIs given in the selector line. It processed the
4608
* line up to the beginning of the action part. A pointer to that beginnig is
4609
* passed back to the caller.
4610
* rgerhards 2005-09-15
4612
static rsRetVal cflineProcessTradPRIFilter(uchar **pline, register selector_t *f)
4624
assert(pline != NULL);
4625
assert(*pline != NULL);
4628
dbgprintf(" - traditional PRI filter\n");
4629
errno = 0; /* keep strerror_r() stuff out of logerror messages */
4631
f->f_filter_type = FILTER_PRI;
4632
/* Note: file structure is pre-initialized to zero because it was
4633
* created with calloc()!
4635
for (i = 0; i <= LOG_NFACILITIES; i++) {
4636
f->f_filterData.f_pmask[i] = TABLE_NOPRI;
4639
/* scan through the list of selectors */
4640
for (p = *pline; *p && *p != '\t' && *p != ' ';) {
4642
/* find the end of this facility name list */
4643
for (q = p; *q && *q != '\t' && *q++ != '.'; )
4646
/* collect priority name */
4647
for (bp = buf; *q && !strchr("\t ,;", *q); )
4652
while (strchr(",;", *q))
4655
/* decode priority name */
4656
if ( *buf == '!' ) {
4658
for (bp=buf; *(bp+1); bp++)
4668
pri = decode(&buf[1], PriNames);
4672
pri = decode(buf, PriNames);
4676
snprintf((char*) xbuf, sizeof(xbuf), "unknown priority name \"%s\"", buf);
4677
logerror((char*) xbuf);
4681
/* scan facilities */
4682
while (*p && !strchr("\t .;", *p)) {
4683
for (bp = buf; *p && !strchr("\t ,;.", *p); )
4687
for (i = 0; i <= LOG_NFACILITIES; i++) {
4688
if ( pri == INTERNAL_NOPRI ) {
4690
f->f_filterData.f_pmask[i] = TABLE_ALLPRI;
4692
f->f_filterData.f_pmask[i] = TABLE_NOPRI;
4694
else if ( singlpri ) {
4696
f->f_filterData.f_pmask[i] &= ~(1<<pri);
4698
f->f_filterData.f_pmask[i] |= (1<<pri);
4702
if ( pri == TABLE_ALLPRI ) {
4704
f->f_filterData.f_pmask[i] = TABLE_NOPRI;
4706
f->f_filterData.f_pmask[i] = TABLE_ALLPRI;
4711
for (i2= 0; i2 <= pri; ++i2)
4712
f->f_filterData.f_pmask[i] &= ~(1<<i2);
4714
for (i2= 0; i2 <= pri; ++i2)
4715
f->f_filterData.f_pmask[i] |= (1<<i2);
4720
i = decode(buf, FacNames);
4723
snprintf((char*) xbuf, sizeof(xbuf), "unknown facility name \"%s\"", buf);
4724
logerror((char*) xbuf);
4728
if ( pri == INTERNAL_NOPRI ) {
4730
f->f_filterData.f_pmask[i >> 3] = TABLE_ALLPRI;
4732
f->f_filterData.f_pmask[i >> 3] = TABLE_NOPRI;
4733
} else if ( singlpri ) {
4735
f->f_filterData.f_pmask[i >> 3] &= ~(1<<pri);
4737
f->f_filterData.f_pmask[i >> 3] |= (1<<pri);
4739
if ( pri == TABLE_ALLPRI ) {
4741
f->f_filterData.f_pmask[i >> 3] = TABLE_NOPRI;
4743
f->f_filterData.f_pmask[i >> 3] = TABLE_ALLPRI;
4746
for (i2= 0; i2 <= pri; ++i2)
4747
f->f_filterData.f_pmask[i >> 3] &= ~(1<<i2);
4749
for (i2= 0; i2 <= pri; ++i2)
4750
f->f_filterData.f_pmask[i >> 3] |= (1<<i2);
4754
while (*p == ',' || *p == ' ')
4761
/* skip to action part */
4762
while (*p == '\t' || *p == ' ')
4771
* Helper to cfline(). This function takes the filter part of a property
4772
* based filter and decodes it. It processes the line up to the beginning
4773
* of the action part. A pointer to that beginnig is passed back to the caller.
4774
* rgerhards 2005-09-15
4776
static rsRetVal cflineProcessPropFilter(uchar **pline, register selector_t *f)
4779
rsCStrObj *pCSCompOp;
4781
int iOffset; /* for compare operations */
4783
assert(pline != NULL);
4784
assert(*pline != NULL);
4787
dbgprintf(" - property-based filter\n");
4788
errno = 0; /* keep strerror_r() stuff out of logerror messages */
4790
f->f_filter_type = FILTER_PROP;
4792
/* create parser object starting with line string without leading colon */
4793
if((iRet = rsParsConstructFromSz(&pPars, (*pline)+1)) != RS_RET_OK) {
4794
logerrorInt("Error %d constructing parser object - ignoring selector", iRet);
4799
iRet = parsDelimCStr(pPars, &f->f_filterData.prop.pCSPropName, ',', 1, 1);
4800
if(iRet != RS_RET_OK) {
4801
logerrorInt("error %d parsing filter property - ignoring selector", iRet);
4802
rsParsDestruct(pPars);
4806
/* read operation */
4807
iRet = parsDelimCStr(pPars, &pCSCompOp, ',', 1, 1);
4808
if(iRet != RS_RET_OK) {
4809
logerrorInt("error %d compare operation property - ignoring selector", iRet);
4810
rsParsDestruct(pPars);
4814
/* we now first check if the condition is to be negated. To do so, we first
4815
* must make sure we have at least one char in the param and then check the
4817
* rgerhards, 2005-09-26
4819
if(rsCStrLen(pCSCompOp) > 0) {
4820
if(*rsCStrGetBufBeg(pCSCompOp) == '!') {
4821
f->f_filterData.prop.isNegated = 1;
4822
iOffset = 1; /* ignore '!' */
4824
f->f_filterData.prop.isNegated = 0;
4828
f->f_filterData.prop.isNegated = 0;
4832
if(!rsCStrOffsetSzStrCmp(pCSCompOp, iOffset, (uchar*) "contains", 8)) {
4833
f->f_filterData.prop.operation = FIOP_CONTAINS;
4834
} else if(!rsCStrOffsetSzStrCmp(pCSCompOp, iOffset, (uchar*) "isequal", 7)) {
4835
f->f_filterData.prop.operation = FIOP_ISEQUAL;
4836
} else if(!rsCStrOffsetSzStrCmp(pCSCompOp, iOffset, (uchar*) "startswith", 10)) {
4837
f->f_filterData.prop.operation = FIOP_STARTSWITH;
4838
} else if(!rsCStrOffsetSzStrCmp(pCSCompOp, iOffset, (unsigned char*) "regex", 5)) {
4839
f->f_filterData.prop.operation = FIOP_REGEX;
4841
logerrorSz("error: invalid compare operation '%s' - ignoring selector",
4842
(char*) rsCStrGetSzStrNoNULL(pCSCompOp));
4844
rsCStrDestruct (pCSCompOp); /* no longer needed */
4846
/* read compare value */
4847
iRet = parsQuotedCStr(pPars, &f->f_filterData.prop.pCSCompValue);
4848
if(iRet != RS_RET_OK) {
4849
logerrorInt("error %d compare value property - ignoring selector", iRet);
4850
rsParsDestruct(pPars);
4854
/* skip to action part */
4855
if((iRet = parsSkipWhitespace(pPars)) != RS_RET_OK) {
4856
logerrorInt("error %d skipping to action part - ignoring selector", iRet);
4857
rsParsDestruct(pPars);
4862
*pline = *pline + rsParsGetParsePointer(pPars) + 1;
4863
/* we are adding one for the skipped initial ":" */
4865
return rsParsDestruct(pPars);
4870
* Helper to cfline(). This function interprets a BSD host selector line
4871
* from the config file ("+/-hostname"). It stores it for further reference.
4872
* rgerhards 2005-10-19
4874
static rsRetVal cflineProcessHostSelector(uchar **pline)
4878
assert(pline != NULL);
4879
assert(*pline != NULL);
4880
assert(**pline == '-' || **pline == '+');
4882
dbgprintf(" - host selector line\n");
4884
/* check include/exclude setting */
4885
if(**pline == '+') {
4886
eDfltHostnameCmpMode = HN_COMP_MATCH;
4887
} else { /* we do not check for '-', it must be, else we wouldn't be here */
4888
eDfltHostnameCmpMode = HN_COMP_NOMATCH;
4890
(*pline)++; /* eat + or - */
4892
/* the below is somewhat of a quick hack, but it is efficient (this is
4893
* why it is in here. "+*" resets the tag selector with BSD syslog. We mimic
4894
* this, too. As it is easy to check that condition, we do not fire up a
4895
* parser process, just make sure we do not address beyond our space.
4896
* Order of conditions in the if-statement is vital! rgerhards 2005-10-18
4898
if(**pline != '\0' && **pline == '*' && *(*pline+1) == '\0') {
4899
dbgprintf("resetting BSD-like hostname filter\n");
4900
eDfltHostnameCmpMode = HN_NO_COMP;
4901
if(pDfltHostnameCmp != NULL) {
4902
if((iRet = rsCStrSetSzStr(pDfltHostnameCmp, NULL)) != RS_RET_OK)
4906
dbgprintf("setting BSD-like hostname filter to '%s'\n", *pline);
4907
if(pDfltHostnameCmp == NULL) {
4908
/* create string for parser */
4909
if((iRet = rsCStrConstructFromszStr(&pDfltHostnameCmp, *pline)) != RS_RET_OK)
4911
} else { /* string objects exists, just update... */
4912
if((iRet = rsCStrSetSzStr(pDfltHostnameCmp, *pline)) != RS_RET_OK)
4921
* Helper to cfline(). This function interprets a BSD tag selector line
4922
* from the config file ("!tagname"). It stores it for further reference.
4923
* rgerhards 2005-10-18
4925
static rsRetVal cflineProcessTagSelector(uchar **pline)
4929
assert(pline != NULL);
4930
assert(*pline != NULL);
4931
assert(**pline == '!');
4933
dbgprintf(" - programname selector line\n");
4935
(*pline)++; /* eat '!' */
4937
/* the below is somewhat of a quick hack, but it is efficient (this is
4938
* why it is in here. "!*" resets the tag selector with BSD syslog. We mimic
4939
* this, too. As it is easy to check that condition, we do not fire up a
4940
* parser process, just make sure we do not address beyond our space.
4941
* Order of conditions in the if-statement is vital! rgerhards 2005-10-18
4943
if(**pline != '\0' && **pline == '*' && *(*pline+1) == '\0') {
4944
dbgprintf("resetting programname filter\n");
4945
if(pDfltProgNameCmp != NULL) {
4946
if((iRet = rsCStrSetSzStr(pDfltProgNameCmp, NULL)) != RS_RET_OK)
4950
dbgprintf("setting programname filter to '%s'\n", *pline);
4951
if(pDfltProgNameCmp == NULL) {
4952
/* create string for parser */
4953
if((iRet = rsCStrConstructFromszStr(&pDfltProgNameCmp, *pline)) != RS_RET_OK)
4955
} else { /* string objects exists, just update... */
4956
if((iRet = rsCStrSetSzStr(pDfltProgNameCmp, *pline)) != RS_RET_OK)
4964
/* add an Action to the current selector
4965
* The pOMSR is freed, as it is not needed after this function.
4966
* Note: this function pulls global data that specifies action config state.
4967
* rgerhards, 2007-07-27
4969
rsRetVal addAction(action_t **ppAction, modInfo_t *pMod, void *pModData, omodStringRequest_t *pOMSR, int bSuspended)
4978
assert(ppAction != NULL);
4979
assert(pMod != NULL);
4980
assert(pOMSR != NULL);
4981
dbgprintf("Module %s processed this config line.\n", modGetName(pMod));
4983
CHKiRet(actionConstruct(&pAction)); /* create action object first */
4984
pAction->pMod = pMod;
4985
pAction->pModData = pModData;
4986
pAction->bExecWhenPrevSusp = bActExecWhenPrevSusp;
4988
/* check if we can obtain the template pointers - TODO: move to separat function? */
4989
pAction->iNumTpls = OMSRgetEntryCount(pOMSR);
4990
assert(pAction->iNumTpls >= 0); /* only debug check because this "can not happen" */
4991
/* please note: iNumTpls may validly be zero. This is the case if the module
4992
* does not request any templates. This sounds unlikely, but an actual example is
4993
* the discard action, which does not require a string. -- rgerhards, 2007-07-30
4995
if(pAction->iNumTpls > 0) {
4996
/* we first need to create the template pointer array */
4997
if((pAction->ppTpl = calloc(pAction->iNumTpls, sizeof(struct template *))) == NULL) {
4998
glblHadMemShortage = 1;
4999
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
5001
/* and now the array for doAction() message pointers */
5002
if((pAction->ppMsgs = calloc(pAction->iNumTpls, sizeof(uchar *))) == NULL) {
5003
glblHadMemShortage = 1;
5004
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
5008
for(i = 0 ; i < pAction->iNumTpls ; ++i) {
5009
CHKiRet(OMSRgetEntry(pOMSR, i, &pTplName, &iTplOpts));
5010
/* Ok, we got everything, so it now is time to look up the
5011
* template (Hint: templates MUST be defined before they are
5014
if((pAction->ppTpl[i] = tplFind((char*)pTplName, strlen((char*)pTplName))) == NULL) {
5015
snprintf(errMsg, sizeof(errMsg) / sizeof(char),
5016
" Could not find template '%s' - action disabled\n",
5020
ABORT_FINALIZE(RS_RET_NOT_FOUND);
5022
/* check required template options */
5023
if( (iTplOpts & OMSR_RQD_TPL_OPT_SQL)
5024
&& (pAction->ppTpl[i]->optFormatForSQL == 0)) {
5026
logerror("Action disabled. To use this action, you have to specify "
5027
"the SQL or stdSQL option in your template!\n");
5028
ABORT_FINALIZE(RS_RET_RQD_TPLOPT_MISSING);
5031
dbgprintf("template: '%s' assigned\n", pTplName);
5034
pAction->pMod = pMod;
5035
pAction->pModData = pModData;
5036
/* now check if the module is compatible with select features */
5037
if(pMod->isCompatibleWithFeature(sFEATURERepeatedMsgReduction) == RS_RET_OK)
5038
pAction->f_ReduceRepeated = bReduceRepeatMsgs;
5040
dbgprintf("module is incompatible with RepeatedMsgReduction - turned off\n");
5041
pAction->f_ReduceRepeated = 0;
5043
pAction->bEnabled = 1; /* action is enabled */
5046
actionSuspend(pAction);
5048
*ppAction = pAction; /* finally store the action pointer */
5051
if(iRet == RS_RET_OK)
5052
iRet = OMSRdestruct(pOMSR);
5054
/* do not overwrite error state! */
5055
OMSRdestruct(pOMSR);
5057
actionDestruct(pAction);
5064
/* read the filter part of a configuration line and store the filter
5065
* in the supplied selector_t
5066
* rgerhards, 2007-08-01
5068
static rsRetVal cflineDoFilter(uchar **pp, selector_t *f)
5075
/* check which filter we need to pull... */
5078
iRet = cflineProcessPropFilter(pp, f);
5081
iRet = cflineProcessTradPRIFilter(pp, f);
5085
/* we now check if there are some global (BSD-style) filter conditions
5086
* and, if so, we copy them over. rgerhards, 2005-10-18
5088
if(pDfltProgNameCmp != NULL)
5089
if((iRet = rsCStrConstructFromCStr(&(f->pCSProgNameComp), pDfltProgNameCmp)) != RS_RET_OK)
5092
if(eDfltHostnameCmpMode != HN_NO_COMP) {
5093
f->eHostnameCmpMode = eDfltHostnameCmpMode;
5094
if((iRet = rsCStrConstructFromCStr(&(f->pCSHostnameComp), pDfltHostnameCmp)) != RS_RET_OK)
5102
/* process the action part of a selector line
5103
* rgerhards, 2007-08-01
5105
static rsRetVal cflineDoAction(uchar **p, action_t **ppAction)
5109
omodStringRequest_t *pOMSR;
5114
assert(ppAction != NULL);
5116
/* loop through all modules and see if one picks up the line */
5117
pMod = omodGetNxt(NULL);
5118
while(pMod != NULL) {
5119
iRet = pMod->mod.om.parseSelectorAct(p, &pModData, &pOMSR);
5120
dbgprintf("tried selector action for %s: %d\n", modGetName(pMod), iRet);
5121
if(iRet == RS_RET_OK || iRet == RS_RET_SUSPENDED) {
5122
if((iRet = addAction(&pAction, pMod, pModData, pOMSR, (iRet == RS_RET_SUSPENDED)? 1 : 0)) == RS_RET_OK) {
5123
/* now check if the module is compatible with select features */
5124
if(pMod->isCompatibleWithFeature(sFEATURERepeatedMsgReduction) == RS_RET_OK)
5125
pAction->f_ReduceRepeated = bReduceRepeatMsgs;
5127
dbgprintf("module is incompatible with RepeatedMsgReduction - turned off\n");
5128
pAction->f_ReduceRepeated = 0;
5130
pAction->bEnabled = 1; /* action is enabled */
5134
else if(iRet != RS_RET_CONFLINE_UNPROCESSED) {
5135
/* In this case, the module would have handled the config
5136
* line, but some error occured while doing so. This error should
5137
* already by reported by the module. We do not try any other
5138
* modules on this line, because we found the right one.
5139
* rgerhards, 2007-07-24
5141
dbgprintf("error %d parsing config line\n", (int) iRet);
5144
pMod = omodGetNxt(pMod);
5147
*ppAction = pAction;
5152
/* helper to selectorAddListCheckActions()
5153
* This is the fucntion to be executed by llExecFunc
5155
DEFFUNC_llExecFunc(selectorAddListCheckActionsChecker)
5158
action_t *pAction = (action_t *) pData;
5160
assert(pAction != NULL);
5162
if(pAction->pMod->needUDPSocket(pAction->pModData) == RS_RET_TRUE) {
5169
/* loop through a list of actions and perform necessary checks and
5170
* housekeeping. This function must only be called when the owning
5171
* selector_t looks valid and is not likely to be discarded. However,
5172
* if we do not return RS_RET_OK, the caller MUST discard the
5173
* owning selector_t. -- rgerhards, 2007-08-02
5175
static rsRetVal selectorAddListCheckActions(selector_t *f)
5181
CHKiRet(llExecFunc(&f->llActList, selectorAddListCheckActionsChecker, NULL));
2363
dbgprintf(" (re)started.\n");
5497
2522
while(iminternalRemoveMsg(&iPri, &pMsg, &iFlags) == RS_RET_OK) {
5498
logmsg(iPri, pMsg, iFlags);
5504
/* helper function for mainloop(). This is used to add all module
5505
* writeFDsfor Select via llExecFunc().
5506
* rgerhards, 2007-08-02
5508
typedef struct selectHelperWriteFDSInfo_s { /* struct for pParam */
5511
} selectHelperWriteFDSInfo_t;
5512
DEFFUNC_llExecFunc(mainloopAddModWriteFDSforSelect)
5515
action_t *pAction = (action_t*) pData;
5516
selectHelperWriteFDSInfo_t *pState = (selectHelperWriteFDSInfo_t*) pParam;
5519
assert(pAction != NULL);
5520
assert(pState != NULL);
5522
if(pAction->pMod->getWriteFDForSelect(pAction->pModData, &fdMod) == RS_RET_OK) {
5523
FD_SET(fdMod, pState->pWritefds);
5524
if(fdMod > *pState->pMaxfds)
5525
*pState->pMaxfds = fdMod;
5532
/* helper function for mainloop(). This is used to call module action
5533
* handlers after select if a fd is writable.
5534
* HINT: when we change to the new threading model, this function
5535
* is probably no longer needed.
5536
* rgerhards, 2007-08-02
5538
DEFFUNC_llExecFunc(mainloopCallWithWritableFDsActions)
5541
action_t *pAction = (action_t*) pData;
5542
selectHelperWriteFDSInfo_t *pState = (selectHelperWriteFDSInfo_t*) pParam;
5545
assert(pAction != NULL);
5546
assert(pState != NULL);
5548
if(pAction->pMod->getWriteFDForSelect(pAction->pModData, &fdMod) == RS_RET_OK) {
5549
if(FD_ISSET(fdMod, pState->pWritefds)) {
5550
if((iRet = pAction->pMod->onSelectReadyWrite(pAction->pModData))
5552
dbgprintf("error %d from onSelectReadyWrite() - continuing\n", iRet);
5554
if(--(pState->pMaxfds) == 0) {
5555
ABORT_FINALIZE(RS_RET_FINISHED); /* all processed, nothing left to do */
5565
/* process the select() selector array after the successful select.
5566
* processing is completed as soon as all selectors needing attention
5568
* rgerhards, 2007-08-08
5570
static rsRetVal processSelectAfter(int maxfds, int nfds, fd_set *pReadfds, fd_set *pWritefds)
5576
char line[MAXLINE +1];
5577
selectHelperWriteFDSInfo_t writeFDSInfo;
5580
struct sockaddr_storage frominet;
5582
uchar fromHost[NI_MAXHOST];
5583
uchar fromHostFQDN[NI_MAXHOST];
5586
#endif /* #ifdef SYSLOG_INET */
5588
/* the following macro is used to decrement the number of to-be-probed
5589
* fds and abort this function when we are done with all.
5591
# define FDPROCESSED() if(--nfds == 0) { ABORT_FINALIZE(RS_RET_OK); }
5596
dbgprintf("Select interrupted.\n");
5597
ABORT_FINALIZE(RS_RET_OK); /* we are done in any case */
5601
dbgprintf("\nSuccessful select, descriptor count = %d, Activity on: ", nfds);
5602
for (i = 0; i <= maxfds; ++i)
5603
if ( FD_ISSET(i, pReadfds) )
5604
dbgprintf("%d ", i);
5609
/* Now check the TCP send sockets. So far, we only see if they become
5610
* writable and then change their internal status. No real async
5611
* writing is currently done. This code will be replaced once liblogging
5612
* is used, thus we try not to focus too much on it.
5614
* IMPORTANT: With the current code, the writefds must be checked first,
5615
* because the readfds might have messages to be forwarded, which
5616
* rely on the status setting that is done here!
5617
* rgerhards 2005-07-20
5619
* liblogging implementation will not happen as anticipated above. So
5620
* this code here will stay for quite a while.
5621
* rgerhards, 2006-12-07
5623
writeFDSInfo.pWritefds = pWritefds;
5624
writeFDSInfo.pMaxfds = &nfds;
5625
for(f = Files; f != NULL ; f = f->f_next) {
5626
iRetLL = llExecFunc(&f->llActList, mainloopCallWithWritableFDsActions, &writeFDSInfo);
5627
if(iRetLL == RS_RET_FINISHED) {
5628
ABORT_FINALIZE(RS_RET_OK); /* we are done in this case */
5631
#endif /* #ifdef SYSLOG_INET */
5632
#ifdef SYSLOG_UNIXAF
5633
for (i = 0; i < nfunix; i++) {
5634
if ((fd = funix[i]) != -1 && FD_ISSET(fd, pReadfds)) {
5636
iRcvd = recv(fd, line, MAXLINE - 1, 0);
5637
dbgprintf("Message from UNIX socket: #%d\n", fd);
5639
printchopped(LocalHostName, line, iRcvd, fd, funixParseHost[i]);
5640
} else if (iRcvd < 0 && errno != EINTR) {
5642
dbgprintf("UNIX socket error: %d = %s.\n", \
5643
errno, strerror_r(errno, errStr, sizeof(errStr)));
5644
logerror("recvfrom UNIX");
5652
if (finet != NULL && AcceptRemote) {
5653
for (i = 0; i < *finet; i++) {
5654
if (FD_ISSET(finet[i+1], pReadfds)) {
5655
socklen = sizeof(frominet);
5656
memset(line, 0xff, sizeof(line)); // TODO: I think we need this for debug only - remove after bug hunt
5657
l = recvfrom(finet[i+1], line, MAXLINE - 1, 0,
5658
(struct sockaddr *)&frominet, &socklen);
5660
if(cvthname(&frominet, fromHost, fromHostFQDN) == RS_RET_OK) {
5661
dbgprintf("Message from inetd socket: #%d, host: %s\n",
5662
finet[i+1], fromHost);
5663
/* Here we check if a host is permitted to send us
5664
* syslog messages. If it isn't, we do not further
5665
* process the message but log a warning (if we are
5666
* configured to do this).
5667
* rgerhards, 2005-09-26
5669
if(isAllowedSender(pAllowedSenders_UDP,
5670
(struct sockaddr *)&frominet, (char*)fromHostFQDN)) {
5671
printchopped((char*)fromHost, line, l, finet[i+1], 1);
5673
if(option_DisallowWarning) {
5674
logerrorSz("UDP message from disallowed sender %s discarded",
5679
} else if (l < 0 && errno != EINTR && errno != EAGAIN) {
5681
dbgprintf("INET socket error: %d = %s.\n",
5682
errno, strerror_r(errno, errStr, sizeof(errStr)));
5683
logerror("recvfrom inet");
5684
/* should be harmless */
5692
if(sockTCPLstn != NULL && *sockTCPLstn) {
5693
for (i = 0; i < *sockTCPLstn; i++) {
5694
if (FD_ISSET(sockTCPLstn[i+1], pReadfds)) {
5695
dbgprintf("New connect on TCP inetd socket: #%d\n", sockTCPLstn[i+1]);
5696
TCPSessAccept(sockTCPLstn[i+1]);
5701
/* now check the sessions */
5702
iTCPSess = TCPSessGetNxtSess(-1);
5703
while(iTCPSess != -1) {
5706
fdSess = pTCPSessions[iTCPSess].sock;
5707
if(FD_ISSET(fdSess, pReadfds)) {
5709
dbgprintf("tcp session socket with new data: #%d\n", fdSess);
5711
/* Receive message */
5712
state = recv(fdSess, buf, sizeof(buf), 0);
5714
/* process any incomplete frames left over */
5715
TCPSessPrepareClose(iTCPSess);
5716
/* Session closed */
5717
TCPSessClose(iTCPSess);
5718
} else if(state == -1) {
5719
logerrorInt("TCP session %d will be closed, error ignored\n",
5721
TCPSessClose(iTCPSess);
5723
/* valid data received, process it! */
5724
if(TCPSessDataRcvd(iTCPSess, buf, state) == 0) {
5725
/* in this case, something went awfully wrong.
5726
* We are instructed to terminate the session.
5728
logerrorInt("Tearing down TCP Session %d - see "
5729
"previous messages for reason(s)\n",
5731
TCPSessClose(iTCPSess);
5736
iTCPSess = TCPSessGetNxtSess(iTCPSess);
2523
logmsg(pMsg, iFlags);
5746
2528
/* This is the main processing loop. It is called after successful initialization.
5747
2529
* When it returns, the syslogd terminates.
2530
* Its sole function is to provide some housekeeping things. The real work is done
2531
* by the other threads spawned.
5749
static void mainloop(void)
5756
selectHelperWriteFDSInfo_t writeFDSInfo;
5760
#endif /* #ifdef SYSLOG_INET */
5763
2536
struct timeval tvSelectTimeout;
5767
2539
while(!bFinished){
5772
2540
/* first check if we have any internal messages queued and spit them out */
2541
/* TODO: do we need this any longer? I doubt it, but let's care about it
2542
* later -- rgerhards, 2007-12-21
5773
2544
processImInternal();
5775
#ifdef SYSLOG_UNIXAF
5776
/* Add the Unix Domain Sockets to the list of read
5778
* rgerhards 2005-08-01: we must now check if there are
5779
* any local sockets to listen to at all. If the -o option
5780
* is given without -a, we do not need to listen at all..
5782
/* Copy master connections */
5783
for (i = startIndexUxLocalSockets; i < nfunix; i++) {
5784
if (funix[i] != -1) {
5785
FD_SET(funix[i], &readfds);
5786
if (funix[i]>maxfds) maxfds=funix[i];
5791
/* Add the UDP listen sockets to the list of read descriptors.
5793
if(finet != NULL && AcceptRemote) {
5794
for (i = 0; i < *finet; i++) {
5795
if (finet[i+1] != -1) {
5797
debugListenInfo(finet[i+1], "UDP");
5798
FD_SET(finet[i+1], &readfds);
5799
if(finet[i+1]>maxfds) maxfds=finet[i+1];
5804
/* Add the TCP listen sockets to the list of read descriptors.
5806
if(sockTCPLstn != NULL && *sockTCPLstn) {
5807
for (i = 0; i < *sockTCPLstn; i++) {
5808
/* The if() below is theoretically not needed, but I leave it in
5809
* so that a socket may become unsuable during execution. That
5810
* feature is not yet supported by the current code base.
5812
if (sockTCPLstn[i+1] != -1) {
5814
debugListenInfo(sockTCPLstn[i+1], "TCP");
5815
FD_SET(sockTCPLstn[i+1], &readfds);
5816
if(sockTCPLstn[i+1]>maxfds) maxfds=sockTCPLstn[i+1];
5819
/* do the sessions */
5820
iTCPSess = TCPSessGetNxtSess(-1);
5821
while(iTCPSess != -1) {
5823
fdSess = pTCPSessions[iTCPSess].sock;
5824
dbgprintf("Adding TCP Session %d\n", fdSess);
5825
FD_SET(fdSess, &readfds);
5826
if (fdSess>maxfds) maxfds=fdSess;
5827
/* now get next... */
5828
iTCPSess = TCPSessGetNxtSess(iTCPSess);
5832
/* TODO: activate the code below only if we actually need to check
5833
* for outstanding writefds.
5836
/* Now add the TCP output sockets to the writefds set. This implementation
5837
* is not optimal (performance-wise) and it should be replaced with something
5838
* better in the longer term. I've not yet done this, as this code is
5839
* scheduled to be replaced after the liblogging integration.
5840
* rgerhards 2005-07-20
5843
writeFDSInfo.pWritefds = &writefds;
5844
writeFDSInfo.pMaxfds = &maxfds;
5845
for (f = Files; f != NULL ; f = f->f_next) {
5846
llExecFunc(&f->llActList, mainloopAddModWriteFDSforSelect, &writeFDSInfo);
5851
if ( debugging_on ) {
5852
dbgprintf("----------------------------------------\n");
5853
dbgprintf("Calling select, active file descriptors (max %d): ", maxfds);
5854
for (nfds= 0; nfds <= maxfds; ++nfds)
5855
if ( FD_ISSET(nfds, &readfds) )
5856
dbgprintf("%d ", nfds);
5860
#define MAIN_SELECT_TIMEVAL NULL
5863
/* There seems to be a problem with BSD and threads. When running on
5864
* multiple threads, a signal will not cause the select call to be
5865
* interrrupted. I am not sure if this is by design or an bug (some
5866
* information on the web let's me think it is a bug), but that really
5867
* does not matter. The issue with our code is that we will not gain
5868
* control when rsyslogd is terminated or huped. What I am doing now is
5869
* make the select call timeout after 10 seconds, so that we can check
5870
* the condition then. Obviously, this causes some sluggish behaviour and
5871
* also the loss of some (very few) cpu cycles. Both, I think, are
5872
* absolutely acceptable.
5873
* rgerhards, 2005-10-26
5874
* TODO: I got some information: this seems to be expected signal() behaviour
5875
* we should investigate the use of sigaction() (see klogd.c for an sample).
5876
* rgerhards, 2007-06-22
5877
* rgerhards, 2007-09-11: code has been converted to sigaction() now. We need
5878
* to re-check on BSD, I think the issue is now solved.
5880
tvSelectTimeout.tv_sec = 10;
2546
/* this is now just a wait */
2547
tvSelectTimeout.tv_sec = TIMERINTVL;
5881
2548
tvSelectTimeout.tv_usec = 0;
5882
# undef MAIN_SELECT_TIMEVAL
5883
# define MAIN_SELECT_TIMEVAL &tvSelectTimeout
5887
#define MAIN_SELECT_WRITEFDS (fd_set *) &writefds
5889
#define MAIN_SELECT_WRITEFDS NULL
5891
nfds = select(maxfds+1, (fd_set *) &readfds, MAIN_SELECT_WRITEFDS,
5892
(fd_set *) NULL, MAIN_SELECT_TIMEVAL);
5894
if(bRequestDoMark) {
5897
/* We do not use continue, because domark() is carried out
5898
* only when something else happened.
2549
select(1, NULL, NULL, NULL, &tvSelectTimeout);
2551
break; /* exit as quickly as possible - see long comment below */
2553
/* If we received a HUP signal, we call doFlushRptdMsgs() a bit early. This
2554
* doesn't matter, because doFlushRptdMsgs() checks timestamps. What may happen,
2555
* however, is that the too-early call may lead to a bit too-late output
2556
* of "last message repeated n times" messages. But that is quite acceptable.
2557
* rgerhards, 2007-12-21
2558
* ... and just to explain, we flush here because that is exactly what the mainloop
2559
* shall do - provide a periodic interval in which not-yet-flushed messages will
2560
* be flushed. Be careful, there is a potential race condition: doFlushRptdMsgs()
2561
* needs to aquire a lock on the action objects. If, however, long-running consumers
2562
* cause the main queue worker threads to lock them for a long time, we may receive
2563
* a starvation condition, resulting in the mainloop being held on lock for an extended
2564
* period of time. That, in turn, could lead to unresponsiveness to termination
2565
* requests. It is especially important that the bFinished flag is checked before
2566
* doFlushRptdMsgs() is called (I know because I ran into that situation). I am
2567
* not yet sure if the remaining probability window of a termination-related
2568
* problem is large enough to justify changing the code - I would consider it
2569
* extremely unlikely that the problem ever occurs in practice. Fixing it would
2570
* require not only a lot of effort but would cost considerable performance. So
2571
* for the time being, I think the remaining risk can be accepted.
2572
* rgerhards, 2008-01-10
5902
2577
dbgprintf("\nReceived SIGHUP, reloading rsyslogd.\n");
5903
/* worker thread is stopped as part of init() */
2578
/* main queue is stopped as part of init() */
5909
dbgprintf("No select activity.\n");
5913
processSelectAfter(maxfds, nfds, &readfds, MAIN_SELECT_WRITEFDS);
5915
#undef MAIN_SELECT_TIMEVAL
5916
#undef MAIN_SELECT_WRITEFDS
5920
2587
/* If user is not root, prints warnings or even exits
5988
2665
* is that rsyslog will terminate if we can not register our built-in config commands.
5989
2666
* This, I think, is the right thing to do. -- rgerhards, 2007-07-31
5992
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesize", 0, eCmdHdlrInt, NULL, &iMainMsgQueueSize));
5994
CHKiRet(regCfSysLineHdlr((uchar *)"repeatedmsgreduction", 0, eCmdHdlrBinary, NULL, &bReduceRepeatMsgs));
5995
CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlywhenpreviousissuspended", 0, eCmdHdlrBinary, NULL, &bActExecWhenPrevSusp));
5996
CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL));
5997
CHKiRet(regCfSysLineHdlr((uchar *)"controlcharacterescapeprefix", 0, eCmdHdlrGetChar, NULL, &cCCEscapeChar));
5998
CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactersonreceive", 0, eCmdHdlrBinary, NULL, &bEscapeCCOnRcv));
5999
CHKiRet(regCfSysLineHdlr((uchar *)"dropmsgswithmaliciousdnsptrrecords", 0, eCmdHdlrBinary, NULL, &bDropMalPTRMsgs));
6000
CHKiRet(regCfSysLineHdlr((uchar *)"droptrailinglfonreception", 0, eCmdHdlrBinary, NULL, &bDropTrailingLF));
6001
CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, doNameLine, (void*)DIR_TEMPLATE));
6002
CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, doNameLine, (void*)DIR_OUTCHANNEL));
6003
CHKiRet(regCfSysLineHdlr((uchar *)"allowedsender", 0, eCmdHdlrCustomHandler, doNameLine, (void*)DIR_ALLOWEDSENDER));
6004
CHKiRet(regCfSysLineHdlr((uchar *)"modload", 0, eCmdHdlrCustomHandler, doModLoad, NULL));
6005
CHKiRet(regCfSysLineHdlr((uchar *)"includeconfig", 0, eCmdHdlrCustomHandler, doIncludeLine, NULL));
6006
CHKiRet(regCfSysLineHdlr((uchar *)"umask", 0, eCmdHdlrFileCreateMode, setUmask, NULL));
6007
CHKiRet(regCfSysLineHdlr((uchar *)"debugprinttemplatelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintTemplateList));
6008
CHKiRet(regCfSysLineHdlr((uchar *)"debugprintmodulelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintModuleList));
2668
CHKiRet(regCfSysLineHdlr((uchar *)"workdirectory", 0, eCmdHdlrGetWord, NULL, &pszWorkDir, NULL));
2669
CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeretrycount", 0, eCmdHdlrInt, NULL, &glbliActionResumeRetryCount, NULL));
2670
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuefilename", 0, eCmdHdlrGetWord, NULL, &pszMainMsgQFName, NULL));
2671
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesize", 0, eCmdHdlrInt, NULL, &iMainMsgQueueSize, NULL));
2672
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuehighwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQHighWtrMark, NULL));
2673
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuelowwatermark", 0, eCmdHdlrInt, NULL, &iMainMsgQLowWtrMark, NULL));
2674
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardmark", 0, eCmdHdlrInt, NULL, &iMainMsgQDiscardMark, NULL));
2675
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardseverity", 0, eCmdHdlrSeverity, NULL, &iMainMsgQDiscardSeverity, NULL));
2676
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuecheckpointinterval", 0, eCmdHdlrInt, NULL, &iMainMsgQPersistUpdCnt, NULL));
2677
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetype", 0, eCmdHdlrGetWord, setMainMsgQueType, NULL, NULL));
2678
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkerthreads", 0, eCmdHdlrInt, NULL, &iMainMsgQueueNumWorkers, NULL));
2679
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutshutdown", 0, eCmdHdlrInt, NULL, &iMainMsgQtoQShutdown, NULL));
2680
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutactioncompletion", 0, eCmdHdlrInt, NULL, &iMainMsgQtoActShutdown, NULL));
2681
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutenqueue", 0, eCmdHdlrInt, NULL, &iMainMsgQtoEnq, NULL));
2682
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworketimeoutrthreadshutdown", 0, eCmdHdlrInt, NULL, &iMainMsgQtoWrkShutdown, NULL));
2683
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeueslowdown", 0, eCmdHdlrInt, NULL, &iMainMsgQDeqSlowdown, NULL));
2684
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkerthreadminimummessages", 0, eCmdHdlrInt, NULL, &iMainMsgQWrkMinMsgs, NULL));
2685
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuemaxfilesize", 0, eCmdHdlrSize, NULL, &iMainMsgQueMaxFileSize, NULL));
2686
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuemaxdiskspace", 0, eCmdHdlrSize, NULL, &iMainMsgQueMaxDiskSpace, NULL));
2687
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesaveonshutdown", 0, eCmdHdlrBinary, NULL, &bMainMsgQSaveOnShutdown, NULL));
2688
CHKiRet(regCfSysLineHdlr((uchar *)"repeatedmsgreduction", 0, eCmdHdlrBinary, NULL, &bReduceRepeatMsgs, NULL));
2689
CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlywhenpreviousissuspended", 0, eCmdHdlrBinary, NULL, &bActExecWhenPrevSusp, NULL));
2690
CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL));
2691
CHKiRet(regCfSysLineHdlr((uchar *)"controlcharacterescapeprefix", 0, eCmdHdlrGetChar, NULL, &cCCEscapeChar, NULL));
2692
CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactersonreceive", 0, eCmdHdlrBinary, NULL, &bEscapeCCOnRcv, NULL));
2693
CHKiRet(regCfSysLineHdlr((uchar *)"dropmsgswithmaliciousdnsptrrecords", 0, eCmdHdlrBinary, NULL, &bDropMalPTRMsgs, NULL));
2694
CHKiRet(regCfSysLineHdlr((uchar *)"droptrailinglfonreception", 0, eCmdHdlrBinary, NULL, &bDropTrailingLF, NULL));
2695
CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_TEMPLATE, NULL));
2696
CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_OUTCHANNEL, NULL));
2697
CHKiRet(regCfSysLineHdlr((uchar *)"allowedsender", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_ALLOWEDSENDER, NULL));
2698
CHKiRet(regCfSysLineHdlr((uchar *)"modload", 0, eCmdHdlrCustomHandler, conf.doModLoad, NULL, NULL));
2699
CHKiRet(regCfSysLineHdlr((uchar *)"includeconfig", 0, eCmdHdlrCustomHandler, conf.doIncludeLine, NULL, NULL));
2700
CHKiRet(regCfSysLineHdlr((uchar *)"umask", 0, eCmdHdlrFileCreateMode, setUmask, NULL, NULL));
2701
CHKiRet(regCfSysLineHdlr((uchar *)"debugprinttemplatelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintTemplateList, NULL));
2702
CHKiRet(regCfSysLineHdlr((uchar *)"debugprintmodulelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintModuleList, NULL));
6009
2703
CHKiRet(regCfSysLineHdlr((uchar *)"debugprintcfsyslinehandlerlist", 0, eCmdHdlrBinary,
6010
NULL, &bDebugPrintCfSysLineHandlerList));
6011
CHKiRet(regCfSysLineHdlr((uchar *)"moddir", 0, eCmdHdlrGetWord, NULL, &pModDir));
6012
CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL));
2704
NULL, &bDebugPrintCfSysLineHandlerList, NULL));
2705
CHKiRet(regCfSysLineHdlr((uchar *)"moddir", 0, eCmdHdlrGetWord, NULL, &pModDir, NULL));
2706
CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL));
2708
/* now add other modules handlers (we should work on that to be able to do it in ClassInit(), but so far
2709
* that is not possible). -- rgerhards, 2008-01-28
2711
CHKiRet(actionAddCfSysLineHdrl());