summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2013-01-09 17:54:25 +0100
committerRainer Gerhards <rgerhards@adiscon.com>2013-01-09 17:54:25 +0100
commitea1bceb8cc849fbd8423ffe12a8e156611bc531f (patch)
tree434da3af857c88645029f7bd1ee7b7c00b8e0b1c
parentdcf3e763194fce727ac3050bf6d2adbeef983530 (diff)
parentb6249c44616cd828c2d53506109b50afd2e61839 (diff)
downloadrsyslog-ea1bceb8cc849fbd8423ffe12a8e156611bc531f.tar.gz
rsyslog-ea1bceb8cc849fbd8423ffe12a8e156611bc531f.tar.bz2
rsyslog-ea1bceb8cc849fbd8423ffe12a8e156611bc531f.zip
Merge branch 'v7-stable' into v7-stable-libnet-frag
Conflicts: ChangeLog
-rw-r--r--ChangeLog17
-rw-r--r--compat/Makefile.am6
-rwxr-xr-xcompat/getifaddrs.c275
-rwxr-xr-xcompat/ifaddrs.h89
-rw-r--r--configure.ac4
-rw-r--r--grammar/lexer.l24
-rw-r--r--runtime/msg.c7
-rw-r--r--runtime/net.c4
-rw-r--r--runtime/srutils.c3
9 files changed, 419 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 88406bc1..aed33f82 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,5 @@
----------------------------------------------------------------------------
-Version 7.2.6 [v7-stable] 2013-01-??
+Version 7.2.x (?really?) [v7-stable] 2013-??-??
- omudpspoof: add support for new config system
- omudpspoof: add support for packets larger than 1472 bytes
On Ethernet, they need to be transmitted in multiple fragments. While
@@ -10,6 +10,21 @@ Version 7.2.6 [v7-stable] 2013-01-??
lead to problems (unfortunately, at least some libnet versions do not
report a proper error state but still "success"...). The order of libnet
calls has been adjusted to by in sync with what the core engine does.
+----------------------------------------------------------------------------
+Version 7.2.6 [v7-stable] 2013-01-??
+- slightly improved config parser error messages when invalid escapes happen
+- bugfix: some property-based filter were incorrectly parsed
+ This usually lead to a syntax error on startup and rsyslogd not actually
+ starting up. The problem was the regex, which did not care for double
+ quote characters to follow in the action part - unfortunately something
+ that can frequently happen with v6+ format. An example:
+ :programname, isequal, "as" {action(type="omfile" ...) }
+ Here, the part
+ :programname, isequal, "as" {action(type="omfile"
+ was treated as the property filter, and the rest as action part.
+ Obviously, this did not work out. Unfortunately, such situations usually
+ resulted in very hard to understand error messages.
+----------------------------------------------------------------------------
Version 7.2.5 [v7-stable] 2013-01-08
- build system cleanup (thanks to Michael Biebl for this!)
- bugfix: omelasticsearch did not properly compile on some platforms
diff --git a/compat/Makefile.am b/compat/Makefile.am
new file mode 100644
index 00000000..635ad280
--- /dev/null
+++ b/compat/Makefile.am
@@ -0,0 +1,6 @@
+pkglib_LTLIBRARIES = compat.la
+
+compat_la_SOURCES = getifaddrs.c
+compat_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS)
+compat_la_LDFLAGS = -module -avoid-version
+compat_la_LIBADD = $(IMUDP_LIBS)
diff --git a/compat/getifaddrs.c b/compat/getifaddrs.c
new file mode 100755
index 00000000..8acd4840
--- /dev/null
+++ b/compat/getifaddrs.c
@@ -0,0 +1,275 @@
+#include "config.h"
+#ifndef HAVE_GETIFADDRS
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <netdb.h>
+#include <nss_dbdefs.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/sockio.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <net/if.h>
+#include <ifaddrs.h>
+#include <libsocket_priv.h>
+
+/*
+ * Create a linked list of `struct ifaddrs' structures, one for each
+ * address that is UP. If successful, store the list in *ifap and
+ * return 0. On errors, return -1 and set `errno'.
+ *
+ * The storage returned in *ifap is allocated dynamically and can
+ * only be properly freed by passing it to `freeifaddrs'.
+ */
+int
+getifaddrs(struct ifaddrs **ifap)
+{
+ int err;
+ char *cp;
+ struct ifaddrs *curr;
+
+ if (ifap == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+ *ifap = NULL;
+ err = getallifaddrs(AF_UNSPEC, ifap, LIFC_ENABLED);
+ if (err == 0) {
+ for (curr = *ifap; curr != NULL; curr = curr->ifa_next) {
+ if ((cp = strchr(curr->ifa_name, ':')) != NULL)
+ *cp = '\0';
+ }
+ }
+ return (err);
+}
+
+void
+freeifaddrs(struct ifaddrs *ifa)
+{
+ struct ifaddrs *curr;
+
+ while (ifa != NULL) {
+ curr = ifa;
+ ifa = ifa->ifa_next;
+ free(curr->ifa_name);
+ free(curr->ifa_addr);
+ free(curr->ifa_netmask);
+ free(curr->ifa_dstaddr);
+ free(curr);
+ }
+}
+
+/*
+ * Returns all addresses configured on the system. If flags contain
+ * LIFC_ENABLED, only the addresses that are UP are returned.
+ * Address list that is returned by this function must be freed
+ * using freeifaddrs().
+ */
+int
+getallifaddrs(sa_family_t af, struct ifaddrs **ifap, int64_t flags)
+{
+ struct lifreq *buf = NULL;
+ struct lifreq *lifrp;
+ struct lifreq lifrl;
+ int ret;
+ int s, n, numifs;
+ struct ifaddrs *curr, *prev;
+ sa_family_t lifr_af;
+ int sock4;
+ int sock6;
+ int err;
+
+ if ((sock4 = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ return (-1);
+ if ((sock6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+ err = errno;
+ close(sock4);
+ errno = err;
+ return (-1);
+ }
+
+retry:
+ /* Get all interfaces from SIOCGLIFCONF */
+ ret = getallifs(sock4, af, &buf, &numifs, (flags & ~LIFC_ENABLED));
+ if (ret != 0)
+ goto fail;
+
+ /*
+ * Loop through the interfaces obtained from SIOCGLIFCOMF
+ * and retrieve the addresses, netmask and flags.
+ */
+ prev = NULL;
+ lifrp = buf;
+ *ifap = NULL;
+ for (n = 0; n < numifs; n++, lifrp++) {
+
+ /* Prepare for the ioctl call */
+ (void) strncpy(lifrl.lifr_name, lifrp->lifr_name,
+ sizeof (lifrl.lifr_name));
+ lifr_af = lifrp->lifr_addr.ss_family;
+ if (af != AF_UNSPEC && lifr_af != af)
+ continue;
+
+ s = (lifr_af == AF_INET ? sock4 : sock6);
+
+ if (ioctl(s, SIOCGLIFFLAGS, (caddr_t)&lifrl) < 0)
+ goto fail;
+ if ((flags & LIFC_ENABLED) && !(lifrl.lifr_flags & IFF_UP))
+ continue;
+
+ /*
+ * Allocate the current list node. Each node contains data
+ * for one ifaddrs structure.
+ */
+ curr = calloc(1, sizeof (struct ifaddrs));
+ if (curr == NULL)
+ goto fail;
+
+ if (prev != NULL) {
+ prev->ifa_next = curr;
+ } else {
+ /* First node in the linked list */
+ *ifap = curr;
+ }
+ prev = curr;
+
+ curr->ifa_flags = lifrl.lifr_flags;
+ if ((curr->ifa_name = strdup(lifrp->lifr_name)) == NULL)
+ goto fail;
+
+ curr->ifa_addr = malloc(sizeof (struct sockaddr_storage));
+ if (curr->ifa_addr == NULL)
+ goto fail;
+ (void) memcpy(curr->ifa_addr, &lifrp->lifr_addr,
+ sizeof (struct sockaddr_storage));
+
+ /* Get the netmask */
+ if (ioctl(s, SIOCGLIFNETMASK, (caddr_t)&lifrl) < 0)
+ goto fail;
+ curr->ifa_netmask = malloc(sizeof (struct sockaddr_storage));
+ if (curr->ifa_netmask == NULL)
+ goto fail;
+ (void) memcpy(curr->ifa_netmask, &lifrl.lifr_addr,
+ sizeof (struct sockaddr_storage));
+
+ /* Get the destination for a pt-pt interface */
+ if (curr->ifa_flags & IFF_POINTOPOINT) {
+ if (ioctl(s, SIOCGLIFDSTADDR, (caddr_t)&lifrl) < 0)
+ goto fail;
+ curr->ifa_dstaddr = malloc(
+ sizeof (struct sockaddr_storage));
+ if (curr->ifa_dstaddr == NULL)
+ goto fail;
+ (void) memcpy(curr->ifa_dstaddr, &lifrl.lifr_addr,
+ sizeof (struct sockaddr_storage));
+ } else if (curr->ifa_flags & IFF_BROADCAST) {
+ if (ioctl(s, SIOCGLIFBRDADDR, (caddr_t)&lifrl) < 0)
+ goto fail;
+ curr->ifa_broadaddr = malloc(
+ sizeof (struct sockaddr_storage));
+ if (curr->ifa_broadaddr == NULL)
+ goto fail;
+ (void) memcpy(curr->ifa_broadaddr, &lifrl.lifr_addr,
+ sizeof (struct sockaddr_storage));
+ }
+
+ }
+ free(buf);
+ close(sock4);
+ close(sock6);
+ return (0);
+fail:
+ err = errno;
+ free(buf);
+ freeifaddrs(*ifap);
+ *ifap = NULL;
+ if (err == ENXIO)
+ goto retry;
+ close(sock4);
+ close(sock6);
+ errno = err;
+ return (-1);
+}
+
+/*
+ * Do a SIOCGLIFCONF and store all the interfaces in `buf'.
+ */
+int
+getallifs(int s, sa_family_t af, struct lifreq **lifr, int *numifs,
+ int64_t lifc_flags)
+{
+ struct lifnum lifn;
+ struct lifconf lifc;
+ size_t bufsize;
+ char *tmp;
+ caddr_t *buf = (caddr_t *)lifr;
+
+ lifn.lifn_family = af;
+ lifn.lifn_flags = lifc_flags;
+
+ *buf = NULL;
+retry:
+ if (ioctl(s, SIOCGLIFNUM, &lifn) < 0)
+ goto fail;
+
+ /*
+ * When calculating the buffer size needed, add a small number
+ * of interfaces to those we counted. We do this to capture
+ * the interface status of potential interfaces which may have
+ * been plumbed between the SIOCGLIFNUM and the SIOCGLIFCONF.
+ */
+ bufsize = (lifn.lifn_count + 4) * sizeof (struct lifreq);
+
+ if ((tmp = realloc(*buf, bufsize)) == NULL)
+ goto fail;
+
+ *buf = tmp;
+ lifc.lifc_family = af;
+ lifc.lifc_flags = lifc_flags;
+ lifc.lifc_len = bufsize;
+ lifc.lifc_buf = *buf;
+ if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0)
+ goto fail;
+
+ *numifs = lifc.lifc_len / sizeof (struct lifreq);
+ if (*numifs >= (lifn.lifn_count + 4)) {
+ /*
+ * If every entry was filled, there are probably
+ * more interfaces than (lifn.lifn_count + 4).
+ * Redo the ioctls SIOCGLIFNUM and SIOCGLIFCONF to
+ * get all the interfaces.
+ */
+ goto retry;
+ }
+ return (0);
+fail:
+ free(*buf);
+ *buf = NULL;
+ return (-1);
+}
+#endif /* HAVE_GETIFADDRS */
diff --git a/compat/ifaddrs.h b/compat/ifaddrs.h
new file mode 100755
index 00000000..ec359c13
--- /dev/null
+++ b/compat/ifaddrs.h
@@ -0,0 +1,89 @@
+#include "config.h"
+#ifndef HAVE_GETIFADDRS
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+#ifndef _IFADDRS_H
+#define _IFADDRS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+
+/*
+ * The `getifaddrs' function generates a linked list of these structures.
+ * Each element of the list describes one network interface.
+ */
+#if defined(_INT64_TYPE)
+struct ifaddrs {
+ struct ifaddrs *ifa_next; /* Pointer to the next structure. */
+ char *ifa_name; /* Name of this network interface. */
+ uint64_t ifa_flags; /* Flags as from SIOCGLIFFLAGS ioctl. */
+ struct sockaddr *ifa_addr; /* Network address of this interface. */
+ struct sockaddr *ifa_netmask; /* Netmask of this interface. */
+ union {
+ /*
+ * At most one of the following two is valid. If the
+ * IFF_BROADCAST bit is set in `ifa_flags', then
+ * `ifa_broadaddr' is valid. If the IFF_POINTOPOINT bit is
+ * set, then `ifa_dstaddr' is valid. It is never the case that
+ * both these bits are set at once.
+ */
+ struct sockaddr *ifu_broadaddr;
+ struct sockaddr *ifu_dstaddr;
+ } ifa_ifu;
+ void *ifa_data; /* Address-specific data (may be unused). */
+/*
+ * This may have been defined in <net/if.h>.
+ */
+#ifndef ifa_broadaddr
+#define ifa_broadaddr ifa_ifu.ifu_broadaddr /* broadcast address */
+#endif
+#ifndef ifa_dstaddr
+#define ifa_dstaddr ifa_ifu.ifu_dstaddr /* other end of p-to-p link */
+#endif
+};
+#endif
+
+/*
+ * Create a linked list of `struct ifaddrs' structures, one for each
+ * network interface on the host machine. If successful, store the
+ * list in *ifap and return 0. On errors, return -1 and set `errno'.
+ *
+ * The storage returned in *ifap is allocated dynamically and can
+ * only be properly freed by passing it to `freeifaddrs'.
+ */
+extern int getifaddrs(struct ifaddrs **);
+
+/* Reclaim the storage allocated by a previous `getifaddrs' call. */
+extern void freeifaddrs(struct ifaddrs *);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IFADDRS_H */
+#endif /* HAVE_GETIFADDRS */
diff --git a/configure.ac b/configure.ac
index cd410e3c..69de5e33 100644
--- a/configure.ac
+++ b/configure.ac
@@ -114,7 +114,7 @@ AC_TYPE_SIGNAL
AC_FUNC_STAT
AC_FUNC_STRERROR_R
AC_FUNC_VPRINTF
-AC_CHECK_FUNCS([flock basename alarm clock_gettime gethostbyname gethostname gettimeofday localtime_r memset mkdir regcomp select setid socket strcasecmp strchr strdup strerror strndup strnlen strrchr strstr strtol strtoul sysinfo uname ttyname_r getline malloc_trim prctl epoll_create epoll_create1 fdatasync lseek64])
+AC_CHECK_FUNCS([flock basename alarm clock_gettime getifaddrs gethostbyname gethostname gettimeofday localtime_r memset mkdir regcomp select setid socket strcasecmp strchr strdup strerror strndup strnlen strrchr strstr strtol strtoul uname ttyname_r getline malloc_trim prctl epoll_create epoll_create1 fdatasync lseek64])
# the check below is probably ugly. If someone knows how to do it in a better way, please
# let me know! -- rgerhards, 2010-10-06
@@ -122,6 +122,7 @@ AC_CHECK_DECL([SCM_CREDENTIALS], [AC_DEFINE(HAVE_SCM_CREDENTIALS, [1], [set defi
#include <sys/socket.h>])
AC_CHECK_DECL([SO_TIMESTAMP], [AC_DEFINE(HAVE_SO_TIMESTAMP, [1], [set define])], [], [#include <sys/types.h>
#include <sys/socket.h>])
+AC_CHECK_MEMBER([struct sysinfo.uptime], [AC_DEFINE(HAVE_SYSINFO_UPTIME, [1], [set define])], [], [#include <sys/sysinfo.h>])
# Check for MAXHOSTNAMELEN
AC_MSG_CHECKING(for MAXHOSTNAMELEN)
@@ -1282,6 +1283,7 @@ AM_CONDITIONAL(ENABLE_OMHIREDIS, test x$enable_omhiredis = xyes)
AC_CONFIG_FILES([Makefile \
runtime/Makefile \
+ compat/Makefile \
grammar/Makefile \
tools/Makefile \
doc/Makefile \
diff --git a/grammar/lexer.l b/grammar/lexer.l
index 63eaa8ce..e1f5a9c3 100644
--- a/grammar/lexer.l
+++ b/grammar/lexer.l
@@ -141,9 +141,13 @@ int fileno(FILE *stream);
<EXPR>[ \t\n]
<EXPR>[a-z][a-z0-9_]* { yylval.estr = es_newStrFromCStr(yytext, yyleng);
return FUNC; }
-<EXPR>. { dbgprintf("invalid char in expr: %s\n", yytext); }
+<EXPR>. { parser_errmsg("invalid character '%s' in expression "
+ "- is there an invalid escape sequence somewhere?",
+ yytext); }
<INCALL>[ \t\n]
-<INCALL>. { dbgprintf("invalid char in CALL stmt: %s\n", yytext); }
+<INCALL>. { parser_errmsg("invalid character '%s' in 'call' statement"
+ "- is there an invalid escape sequence somewhere?",
+ yytext); }
<INCALL>[a-zA-Z][a-zA-Z0-9_\.]* { yylval.estr = es_newStrFromCStr(yytext, yyleng);
BEGIN INITIAL;
return NAME; }
@@ -185,8 +189,11 @@ int fileno(FILE *stream);
"module"[ \n\t]*"(" { yylval.objType = CNFOBJ_MODULE;
BEGIN INOBJ; return BEGINOBJ; }
"action"[ \n\t]*"(" { BEGIN INOBJ; return BEGIN_ACTION; }
-^[ \t]*:\$?[a-z\-]+[ ]*,[ ]*!?[a-z]+[ ]*,[ ]*\".*\" {
- yylval.s = strdup(rmLeadingSpace(yytext)); return PROPFILT; }
+^[ \t]*:\$?[a-z\-]+[ ]*,[ ]*!?[a-z]+[ ]*,[ ]*\"(\\\"|[^\"])*\" {
+ yylval.s = strdup(rmLeadingSpace(yytext));
+ dbgprintf("lexer: propfilt is '%s'\n", yylval.s);
+ return PROPFILT;
+ }
^[ \t]*[\*a-z][\*a-z]*[0-7]*[\.,][,!=;\.\*a-z0-7]+ { yylval.s = strdup(rmLeadingSpace(yytext)); return PRIFILT; }
"~" |
"*" |
@@ -216,7 +223,9 @@ int fileno(FILE *stream);
<COMMENT>([^*]|\n)+|.
<INOBJ>#.*$ /* skip comments in input */
<INOBJ>[ \n\t]
-<INOBJ>. { dbgprintf("INOBJ: invalid char '%s'\n", yytext); }
+<INOBJ>. { parser_errmsg("invalid character '%s' in object definition "
+ "- is there an invalid escape sequence somewhere?",
+ yytext); }
\$[a-z]+.*$ { /* see comment on $IncludeConfig above */
if(!strncasecmp(yytext, "$includeconfig ", 14)) {
yyless(14);
@@ -234,8 +243,9 @@ int fileno(FILE *stream);
^[ \t]*[+-][a-z0-9.:-]+[ \t]*$ { yylval.s = strdup(yytext); return BSD_HOST_SELECTOR; }
\#.*\n /* skip comments in input */
[\n\t ] /* drop whitespace */
-. { dbgprintf("invalid char: %s\n", yytext);
- }
+. { parser_errmsg("invalid character '%s' "
+ "- is there an invalid escape sequence somewhere?",
+ yytext); }
<<EOF>> { if(popfile() != 0) yyterminate(); }
%%
diff --git a/runtime/msg.c b/runtime/msg.c
index 10605ba4..32a02424 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -36,7 +36,9 @@
#include <assert.h>
#include <ctype.h>
#include <sys/socket.h>
+#if HAVE_SYSINFO_UPTIME
#include <sys/sysinfo.h>
+#endif
#include <netdb.h>
#include <libestr.h>
#include <json/json.h>
@@ -2773,7 +2775,10 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
*pbMustBeFreed = 0;
break;
case PROP_SYS_UPTIME:
-# ifndef HAVE_SYSINFO
+# ifndef HAVE_SYSINFO_UPTIME
+ /* An alternative on some systems (eg Solaris) is to scan
+ * /var/adm/utmpx for last boot time.
+ */
pRes = (uchar*) "UPTIME NOT available on this system";
*pbMustBeFreed = 0;
# else
diff --git a/runtime/net.c b/runtime/net.c
index dcf9cb52..1a8f2438 100644
--- a/runtime/net.c
+++ b/runtime/net.c
@@ -54,7 +54,11 @@
#include <fnmatch.h>
#include <fcntl.h>
#include <unistd.h>
+#if HAVE_GETIFADDRS
#include <ifaddrs.h>
+#else
+#include "compat/ifaddrs.h"
+#endif /* HAVE_GETIFADDRS */
#include <sys/types.h>
#include <arpa/inet.h>
diff --git a/runtime/srutils.c b/runtime/srutils.c
index f420c0f7..4ce6196a 100644
--- a/runtime/srutils.c
+++ b/runtime/srutils.c
@@ -92,6 +92,9 @@ syslogName_t syslogFacNames[] = {
#if defined(LOG_FTP)
{"ftp", LOG_FTP},
#endif
+#if defined(LOG_AUDIT)
+ {"audit", LOG_AUDIT},
+#endif
{"local0", LOG_LOCAL0},
{"local1", LOG_LOCAL1},
{"local2", LOG_LOCAL2},