diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2013-01-09 17:54:25 +0100 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2013-01-09 17:54:25 +0100 |
commit | ea1bceb8cc849fbd8423ffe12a8e156611bc531f (patch) | |
tree | 434da3af857c88645029f7bd1ee7b7c00b8e0b1c | |
parent | dcf3e763194fce727ac3050bf6d2adbeef983530 (diff) | |
parent | b6249c44616cd828c2d53506109b50afd2e61839 (diff) | |
download | rsyslog-ea1bceb8cc849fbd8423ffe12a8e156611bc531f.tar.gz rsyslog-ea1bceb8cc849fbd8423ffe12a8e156611bc531f.tar.bz2 rsyslog-ea1bceb8cc849fbd8423ffe12a8e156611bc531f.zip |
Merge branch 'v7-stable' into v7-stable-libnet-frag
Conflicts:
ChangeLog
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | compat/Makefile.am | 6 | ||||
-rwxr-xr-x | compat/getifaddrs.c | 275 | ||||
-rwxr-xr-x | compat/ifaddrs.h | 89 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | grammar/lexer.l | 24 | ||||
-rw-r--r-- | runtime/msg.c | 7 | ||||
-rw-r--r-- | runtime/net.c | 4 | ||||
-rw-r--r-- | runtime/srutils.c | 3 |
9 files changed, 419 insertions, 10 deletions
@@ -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}, |