import rsyslog-8.37.0-13.el8
This commit is contained in:
commit
5208615781
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
SOURCES/rsyslog-8.37.0.tar.gz
|
||||
SOURCES/rsyslog-doc-8.37.0.tar.gz
|
2
.rsyslog.metadata
Normal file
2
.rsyslog.metadata
Normal file
@ -0,0 +1,2 @@
|
||||
43076e3010fc3fd5178201a916beb93848b5249c SOURCES/rsyslog-8.37.0.tar.gz
|
||||
4c75f56e2d55c4c87d07781fb6d9deabf63395fb SOURCES/rsyslog-doc-8.37.0.tar.gz
|
21
SOURCES/rsyslog-8.32.0-service.patch
Normal file
21
SOURCES/rsyslog-8.32.0-service.patch
Normal file
@ -0,0 +1,21 @@
|
||||
diff -up ./rsyslog.service.in.service ./rsyslog.service.in
|
||||
--- ./rsyslog.service.in.service 2018-03-01 13:58:11.480598935 +0100
|
||||
+++ ./rsyslog.service.in 2018-03-01 13:58:25.433518607 +0100
|
||||
@@ -1,12 +1,16 @@
|
||||
[Unit]
|
||||
Description=System Logging Service
|
||||
Requires=syslog.socket
|
||||
+Wants=network.target network-online.target
|
||||
+After=network.target network-online.target
|
||||
Documentation=man:rsyslogd(8)
|
||||
Documentation=http://www.rsyslog.com/doc/
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
-ExecStart=@sbindir@/rsyslogd -n -iNONE
|
||||
+EnvironmentFile=-/etc/sysconfig/rsyslog
|
||||
+ExecStart=@sbindir@/rsyslogd -n $SYSLOGD_OPTIONS
|
||||
+UMask=0066
|
||||
StandardOutput=null
|
||||
Restart=on-failure
|
||||
|
416
SOURCES/rsyslog-8.37.0-rhbz1614179-imfile-symlink-support.patch
Normal file
416
SOURCES/rsyslog-8.37.0-rhbz1614179-imfile-symlink-support.patch
Normal file
@ -0,0 +1,416 @@
|
||||
From 3822da837e4d531e8a9cd78ae76359a410f8d98d Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Vymazal <jvymazal@redhat.com>
|
||||
Date: Thu, 31 May 2018 16:30:08 +0200
|
||||
Subject: [PATCH] Symlink support for imfile
|
||||
|
||||
this introduces symlink detection and following as well
|
||||
as monitoring changes on them. Also added test for the new
|
||||
functionality and ensuring the original symlink behavior
|
||||
stays as well.
|
||||
---
|
||||
plugins/imfile/imfile.c | 182 +++++++++++++++++++++++++++----------
|
||||
1 file changed, 133 insertions(+), 49 deletions(-)
|
||||
|
||||
diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c
|
||||
index 3c9308bfe..4ca23d2ca 100644
|
||||
--- a/plugins/imfile/imfile.c
|
||||
+++ b/plugins/imfile/imfile.c
|
||||
@@ -152,6 +152,7 @@ struct act_obj_s {
|
||||
fs_edge_t *edge; /* edge which this object belongs to */
|
||||
char *name; /* full path name of active object */
|
||||
char *basename; /* only basename */ //TODO: remove when refactoring rename support
|
||||
+ char *source_name; /* if this object is target of a symlink, source_name is its name (else NULL) */
|
||||
//char *statefile; /* base name of state file (for move operations) */
|
||||
int wd;
|
||||
#if defined(OS_SOLARIS) && defined (HAVE_PORT_SOURCE_FILE)
|
||||
@@ -167,6 +168,7 @@ struct act_obj_s {
|
||||
int nRecords; /**< How many records did we process before persisting the stream? */
|
||||
ratelimit_t *ratelimiter;
|
||||
multi_submit_t multiSub;
|
||||
+ int is_symlink;
|
||||
};
|
||||
struct fs_edge_s {
|
||||
fs_node_t *parent;
|
||||
@@ -181,7 +182,8 @@ struct act_obj_s {
|
||||
instanceConf_t **instarr;
|
||||
};
|
||||
struct fs_node_s {
|
||||
- fs_edge_t *edges;
|
||||
+ fs_edge_t *edges; /* NULL in leaf nodes */
|
||||
+ fs_node_t *root; /* node one level up (NULL for file system root) */
|
||||
};
|
||||
|
||||
|
||||
@@ -189,7 +191,7 @@ static rsRetVal persistStrmState(act_obj_t *);
|
||||
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal);
|
||||
static rsRetVal ATTR_NONNULL(1) pollFile(act_obj_t *act);
|
||||
static int ATTR_NONNULL() getBasename(uchar *const __restrict__ basen, uchar *const __restrict__ path);
|
||||
-static void ATTR_NONNULL() act_obj_unlink(act_obj_t *const act);
|
||||
+static void ATTR_NONNULL() act_obj_unlink(act_obj_t *act);
|
||||
static uchar * ATTR_NONNULL(1, 2) getStateFileName(const act_obj_t *, uchar *, const size_t);
|
||||
static int ATTR_NONNULL() getFullStateFileName(const uchar *const, uchar *const pszout, const size_t ilenout);
|
||||
|
||||
@@ -483,14 +485,17 @@ in_setupWatch(act_obj_t *const act, const int is_file)
|
||||
goto done;
|
||||
|
||||
wd = inotify_add_watch(ino_fd, act->name,
|
||||
- (is_file) ? IN_MODIFY : IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO);
|
||||
+ (is_file) ? IN_MODIFY|IN_DONT_FOLLOW : IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO);
|
||||
if(wd < 0) {
|
||||
- LogError(errno, RS_RET_IO_ERROR, "imfile: cannot watch object '%s'",
|
||||
- act->name);
|
||||
+ if (errno == EACCES) { /* There is high probability of selinux denial on top-level paths */
|
||||
+ DBGPRINTF("imfile: permission denied when adding watch for '%s'\n", act->name);
|
||||
+ } else {
|
||||
+ LogError(errno, RS_RET_IO_ERROR, "imfile: cannot watch object '%s'", act->name);
|
||||
+ }
|
||||
goto done;
|
||||
}
|
||||
wdmapAdd(wd, act);
|
||||
- DBGPRINTF("in_setupDirWatch: watch %d added for dir %s(%p)\n", wd, act->name, act);
|
||||
+ DBGPRINTF("in_setupWatch: watch %d added for %s(object %p)\n", wd, act->name, act);
|
||||
done: return wd;
|
||||
}
|
||||
|
||||
@@ -605,7 +610,7 @@ done: return;
|
||||
static void ATTR_NONNULL()
|
||||
fen_setupWatch(act_obj_t *const act __attribute__((unused)))
|
||||
{
|
||||
- DBGPRINTF("fen_setupWatch: DUMMY CALLED - not on Solaris?");
|
||||
+ DBGPRINTF("fen_setupWatch: DUMMY CALLED - not on Solaris?\n");
|
||||
}
|
||||
#endif /* FEN */
|
||||
|
||||
@@ -633,38 +638,48 @@ fs_node_print(const fs_node_t *const node, const int level)
|
||||
}
|
||||
}
|
||||
|
||||
-
|
||||
/* add a new file system object if it not yet exists, ignore call
|
||||
* if it already does.
|
||||
*/
|
||||
-static rsRetVal ATTR_NONNULL()
|
||||
+static rsRetVal ATTR_NONNULL(1,2)
|
||||
act_obj_add(fs_edge_t *const edge, const char *const name, const int is_file,
|
||||
- const ino_t ino)
|
||||
+ const ino_t ino, const int is_symlink, const char *const source)
|
||||
{
|
||||
act_obj_t *act;
|
||||
char basename[MAXFNAME];
|
||||
DEFiRet;
|
||||
|
||||
- DBGPRINTF("act_obj_add: edge %p, name '%s'\n", edge, name);
|
||||
+ DBGPRINTF("act_obj_add: edge %p, name '%s' (source '%s')\n", edge, name, source? source : "---");
|
||||
for(act = edge->active ; act != NULL ; act = act->next) {
|
||||
if(!strcmp(act->name, name)) {
|
||||
- DBGPRINTF("active object '%s' already exists in '%s' - no need to add\n",
|
||||
- name, edge->path);
|
||||
- FINALIZE;
|
||||
+ if (!source || !act->source_name || !strcmp(act->source_name, source)) {
|
||||
+ DBGPRINTF("active object '%s' already exists in '%s' - no need to add\n",
|
||||
+ name, edge->path);
|
||||
+ FINALIZE;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
DBGPRINTF("add new active object '%s' in '%s'\n", name, edge->path);
|
||||
CHKmalloc(act = calloc(sizeof(act_obj_t), 1));
|
||||
CHKmalloc(act->name = strdup(name));
|
||||
- getBasename((uchar*)basename, (uchar*)name);
|
||||
- CHKmalloc(act->basename = strdup(basename));
|
||||
+ if (-1 == getBasename((uchar*)basename, (uchar*)name)) {
|
||||
+ CHKmalloc(act->basename = strdup(name)); /* assume basename is same as name */
|
||||
+ } else {
|
||||
+ CHKmalloc(act->basename = strdup(basename));
|
||||
+ }
|
||||
act->edge = edge;
|
||||
act->ino = ino;
|
||||
+ act->is_symlink = is_symlink;
|
||||
+ if (source) { /* we are target of symlink */
|
||||
+ CHKmalloc(act->source_name = strdup(source));
|
||||
+ } else {
|
||||
+ act->source_name = NULL;
|
||||
+ }
|
||||
#ifdef HAVE_INOTIFY_INIT
|
||||
act->wd = in_setupWatch(act, is_file);
|
||||
#endif
|
||||
fen_setupWatch(act);
|
||||
- if(is_file) {
|
||||
+ if(is_file && !is_symlink) {
|
||||
const instanceConf_t *const inst = edge->instarr[0];// TODO: same file, multiple instances?
|
||||
CHKiRet(ratelimitNew(&act->ratelimiter, "imfile", name));
|
||||
CHKmalloc(act->multiSub.ppMsgs = MALLOC(inst->nMultiSub * sizeof(smsg_t *)));
|
||||
@@ -702,27 +717,24 @@ detect_updates(fs_edge_t *const edge)
|
||||
{
|
||||
act_obj_t *act;
|
||||
struct stat fileInfo;
|
||||
+ int restart = 0;
|
||||
|
||||
- for(act = edge->active ; act != NULL ; ) {
|
||||
+ for(act = edge->active ; act != NULL ; act = act->next) {
|
||||
DBGPRINTF("detect_updates checking active obj '%s'\n", act->name);
|
||||
- const int r = stat(act->name, &fileInfo);
|
||||
+ const int r = lstat(act->name, &fileInfo);
|
||||
if(r == -1) { /* object gone away? */
|
||||
DBGPRINTF("object gone away, unlinking: '%s'\n", act->name);
|
||||
- act_obj_t *toDel = act;
|
||||
- act = act->next;
|
||||
- DBGPRINTF("new next act %p\n", act);
|
||||
- act_obj_unlink(toDel);
|
||||
- continue;
|
||||
+ act_obj_unlink(act);
|
||||
+ restart = 1;
|
||||
+ break;
|
||||
}
|
||||
// TODO: add inode check for change notification!
|
||||
|
||||
- /* Note: active nodes may get deleted, so we need to do the
|
||||
- * pointer advancement at the end of the for loop!
|
||||
- */
|
||||
- act = act->next;
|
||||
}
|
||||
|
||||
-
|
||||
+ if (restart) {
|
||||
+ detect_updates(edge);
|
||||
+ }
|
||||
}
|
||||
|
||||
|
||||
@@ -746,14 +758,52 @@ poll_active_files(fs_edge_t *const edge)
|
||||
}
|
||||
}
|
||||
|
||||
+static rsRetVal ATTR_NONNULL()
|
||||
+process_symlink(fs_edge_t *const chld, const char *symlink)
|
||||
+{
|
||||
+ DEFiRet;
|
||||
+ char *target = NULL;
|
||||
+ CHKmalloc(target = realpath(symlink, target));
|
||||
+ struct stat fileInfo;
|
||||
+ if(lstat(target, &fileInfo) != 0) {
|
||||
+ LogError(errno, RS_RET_ERR, "imfile: process_symlink: cannot stat file '%s' - ignored", target);
|
||||
+ FINALIZE;
|
||||
+ }
|
||||
+ const int is_file = (S_ISREG(fileInfo.st_mode));
|
||||
+ DBGPRINTF("process_symlink: found '%s', File: %d (config file: %d), symlink: %d\n",
|
||||
+ target, is_file, chld->is_file, 0);
|
||||
+ if (act_obj_add(chld, target, is_file, fileInfo.st_ino, 0, symlink) == RS_RET_OK) {
|
||||
+ /* need to watch parent target as well for proper rotation support */
|
||||
+ uint idx = ustrlen(chld->active->name) - ustrlen(chld->active->basename);
|
||||
+ if (idx) { /* basename is different from name */
|
||||
+ char parent[MAXFNAME];
|
||||
+ idx--; /* move past trailing slash */
|
||||
+ memcpy(parent, chld->active->name, idx);
|
||||
+ parent[idx] = '\0';
|
||||
+ if(lstat(parent, &fileInfo) != 0) {
|
||||
+ LogError(errno, RS_RET_ERR,
|
||||
+ "imfile: process_symlink: cannot stat directory '%s' - ignored", parent);
|
||||
+ FINALIZE;
|
||||
+ }
|
||||
+ if (chld->parent->root->edges) {
|
||||
+ DBGPRINTF("process_symlink: adding parent '%s' of target '%s'\n", parent, target);
|
||||
+ act_obj_add(chld->parent->root->edges, parent, 0, fileInfo.st_ino, 0, NULL);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+finalize_it:
|
||||
+ free(target);
|
||||
+ RETiRet;
|
||||
+}
|
||||
|
||||
-static void ATTR_NONNULL() poll_tree(fs_edge_t *const chld);
|
||||
static void ATTR_NONNULL()
|
||||
poll_tree(fs_edge_t *const chld)
|
||||
{
|
||||
struct stat fileInfo;
|
||||
glob_t files;
|
||||
int need_globfree = 0;
|
||||
+ int issymlink;
|
||||
DBGPRINTF("poll_tree: chld %p, name '%s', path: %s\n", chld, chld->name, chld->path);
|
||||
detect_updates(chld);
|
||||
const int ret = glob((char*)chld->path, runModConf->sortFiles|GLOB_BRACE, NULL, &files);
|
||||
@@ -766,18 +803,27 @@ poll_tree(fs_edge_t *const chld)
|
||||
goto done;
|
||||
}
|
||||
char *const file = files.gl_pathv[i];
|
||||
- if(stat(file, &fileInfo) != 0) {
|
||||
+ if(lstat(file, &fileInfo) != 0) {
|
||||
LogError(errno, RS_RET_ERR,
|
||||
"imfile: poll_tree cannot stat file '%s' - ignored", file);
|
||||
continue;
|
||||
}
|
||||
|
||||
- const int is_file = S_ISREG(fileInfo.st_mode);
|
||||
- DBGPRINTF("poll_tree: found '%s', File: %d (config file: %d)\n",
|
||||
- file, is_file, chld->is_file);
|
||||
+ if (S_ISLNK(fileInfo.st_mode)) {
|
||||
+ rsRetVal slink_ret = process_symlink(chld, file);
|
||||
+ if (slink_ret != RS_RET_OK) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ issymlink = 1;
|
||||
+ } else {
|
||||
+ issymlink = 0;
|
||||
+ }
|
||||
+ const int is_file = (S_ISREG(fileInfo.st_mode) || issymlink);
|
||||
+ DBGPRINTF("poll_tree: found '%s', File: %d (config file: %d), symlink: %d\n",
|
||||
+ file, is_file, chld->is_file, issymlink);
|
||||
if(!is_file && S_ISREG(fileInfo.st_mode)) {
|
||||
LogMsg(0, RS_RET_ERR, LOG_WARNING,
|
||||
- "imfile: '%s' is neither a regular file nor a "
|
||||
+ "imfile: '%s' is neither a regular file, symlink, nor a "
|
||||
"directory - ignored", file);
|
||||
continue;
|
||||
}
|
||||
@@ -788,7 +834,7 @@ poll_tree(fs_edge_t *const chld)
|
||||
(chld->is_file) ? "FILE" : "DIRECTORY");
|
||||
continue;
|
||||
}
|
||||
- act_obj_add(chld, file, is_file, fileInfo.st_ino);
|
||||
+ act_obj_add(chld, file, is_file, fileInfo.st_ino, issymlink, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -829,8 +875,20 @@ act_obj_destroy(act_obj_t *const act, const int is_deleted)
|
||||
if(act == NULL)
|
||||
return;
|
||||
|
||||
- DBGPRINTF("act_obj_destroy: act %p '%s', wd %d, pStrm %p, is_deleted %d, in_move %d\n",
|
||||
- act, act->name, act->wd, act->pStrm, is_deleted, act->in_move);
|
||||
+ DBGPRINTF("act_obj_destroy: act %p '%s' (source '%s'), wd %d, pStrm %p, is_deleted %d, in_move %d\n",
|
||||
+ act, act->name, act->source_name? act->source_name : "---", act->wd, act->pStrm, is_deleted,
|
||||
+ act->in_move);
|
||||
+ if(act->is_symlink && is_deleted) {
|
||||
+ act_obj_t *target_act;
|
||||
+ for(target_act = act->edge->active ; target_act != NULL ; target_act = target_act->next) {
|
||||
+ if(target_act->source_name && !strcmp(target_act->source_name, act->name)) {
|
||||
+ DBGPRINTF("act_obj_destroy: unlinking slink target %s of %s "
|
||||
+ "symlink\n", target_act->name, act->name);
|
||||
+ act_obj_unlink(target_act);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
if(act->ratelimiter != NULL) {
|
||||
ratelimitDestruct(act->ratelimiter);
|
||||
}
|
||||
@@ -862,6 +920,7 @@ act_obj_destroy(act_obj_t *const act, const int is_deleted)
|
||||
}
|
||||
#endif
|
||||
free(act->basename);
|
||||
+ free(act->source_name);
|
||||
//free(act->statefile);
|
||||
free(act->multiSub.ppMsgs);
|
||||
#if defined(OS_SOLARIS) && defined (HAVE_PORT_SOURCE_FILE)
|
||||
@@ -909,7 +968,7 @@ chk_active(const act_obj_t *act, const act_obj_t *const deleted)
|
||||
* destruct it.
|
||||
*/
|
||||
static void //ATTR_NONNULL()
|
||||
-act_obj_unlink(act_obj_t *const act)
|
||||
+act_obj_unlink(act_obj_t *act)
|
||||
{
|
||||
DBGPRINTF("act_obj_unlink %p: %s\n", act, act->name);
|
||||
if(act->prev == NULL) {
|
||||
@@ -921,6 +980,7 @@ act_obj_unlink(act_obj_t *const act)
|
||||
act->next->prev = act->prev;
|
||||
}
|
||||
act_obj_destroy(act, 1);
|
||||
+ act = NULL;
|
||||
//dbgprintf("printout of fs tree post unlink\n");
|
||||
//fs_node_print(runModConf->conf_tree, 0);
|
||||
//dbg_wdmapPrint("wdmap after");
|
||||
@@ -1025,6 +1038,7 @@ fs_node_walk(fs_node_t *const node,
|
||||
*/
|
||||
static rsRetVal
|
||||
fs_node_add(fs_node_t *const node,
|
||||
+ fs_node_t *const source,
|
||||
const uchar *const toFind,
|
||||
const size_t pathIdx,
|
||||
instanceConf_t *const inst)
|
||||
@@ -1053,6 +1067,7 @@ fs_node_add(fs_node_t *const node,
|
||||
memcpy(name, toFind+pathIdx, len);
|
||||
name[len] = '\0';
|
||||
DBGPRINTF("fs_node_add: name '%s'\n", name);
|
||||
+ node->root = source;
|
||||
|
||||
fs_edge_t *chld;
|
||||
for(chld = node->edges ; chld != NULL ; chld = chld->next) {
|
||||
@@ -1064,7 +1079,7 @@ fs_node_add(fs_node_t *const node,
|
||||
chld->instarr[chld->ninst-1] = inst;
|
||||
/* recurse */
|
||||
if(!isFile) {
|
||||
- CHKiRet(fs_node_add(chld->node, toFind, nextPathIdx, inst));
|
||||
+ CHKiRet(fs_node_add(chld->node, node, toFind, nextPathIdx, inst));
|
||||
}
|
||||
FINALIZE;
|
||||
}
|
||||
@@ -1086,7 +1101,7 @@ fs_node_add(fs_node_t *const node,
|
||||
DBGPRINTF("fs_node_add(%p, '%s') returns %p\n", node, toFind, newchld->node);
|
||||
|
||||
if(!isFile) {
|
||||
- CHKiRet(fs_node_add(newchld->node, toFind, nextPathIdx, inst));
|
||||
+ CHKiRet(fs_node_add(newchld->node, node, toFind, nextPathIdx, inst));
|
||||
}
|
||||
|
||||
/* link to list */
|
||||
@@ -1162,7 +1222,11 @@ enqLine(act_obj_t *const act,
|
||||
msgSetPRI(pMsg, inst->iFacility | inst->iSeverity);
|
||||
MsgSetRuleset(pMsg, inst->pBindRuleset);
|
||||
if(inst->addMetadata) {
|
||||
- metadata_values[0] = (const uchar*)act->name;
|
||||
+ if (act->source_name) {
|
||||
+ metadata_values[0] = (const uchar*)act->source_name;
|
||||
+ } else {
|
||||
+ metadata_values[0] = (const uchar*)act->name;
|
||||
+ }
|
||||
snprintf((char *)file_offset, MAX_OFFSET_REPRESENTATION_NUM_BYTES+1, "%lld", strtOffs);
|
||||
metadata_values[1] = file_offset;
|
||||
msgAddMultiMetadata(pMsg, metadata_names, metadata_values, 2);
|
||||
@@ -1389,13 +1453,16 @@ pollFile(act_obj_t *const act)
|
||||
{
|
||||
cstr_t *pCStr = NULL;
|
||||
DEFiRet;
|
||||
+ if (act->is_symlink) {
|
||||
+ FINALIZE; /* no reason to poll symlink file */
|
||||
+ }
|
||||
/* Note: we must do pthread_cleanup_push() immediately, because the POSIX macros
|
||||
* otherwise do not work if I include the _cleanup_pop() inside an if... -- rgerhards, 2008-08-14
|
||||
*/
|
||||
pthread_cleanup_push(pollFileCancelCleanup, &pCStr);
|
||||
iRet = pollFileReal(act, &pCStr);
|
||||
pthread_cleanup_pop(0);
|
||||
- RETiRet;
|
||||
+finalize_it: RETiRet;
|
||||
}
|
||||
|
||||
|
||||
@@ -1931,7 +1946,7 @@ CODESTARTactivateCnf
|
||||
"be processed. Reason", inst->pszFileName);
|
||||
}
|
||||
}
|
||||
- fs_node_add(runModConf->conf_tree, inst->pszFileName, 0, inst);
|
||||
+ fs_node_add(runModConf->conf_tree, NULL, inst->pszFileName, 0, inst);
|
||||
}
|
||||
|
||||
if(Debug) {
|
||||
@@ -2031,6 +2113,9 @@ flag_in_move(fs_edge_t *const edge, const char *name_moved)
|
||||
DBGPRINTF("name check fails, '%s' != '%s'\n", act->basename, name_moved);
|
||||
}
|
||||
}
|
||||
+ if (!act && edge->next) {
|
||||
+ flag_in_move(edge->next, name_moved);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void ATTR_NONNULL(1)
|
||||
@@ -2057,7 +2145,7 @@ in_processEvent(struct inotify_event *ev)
|
||||
}
|
||||
if(ev->mask & (IN_MOVED_FROM | IN_MOVED_TO)) {
|
||||
fs_node_walk(etry->act->edge->node, poll_tree);
|
||||
- } else if(etry->act->edge->is_file) {
|
||||
+ } else if(etry->act->edge->is_file && !(etry->act->is_symlink)) {
|
||||
in_handleFileEvent(ev, etry); // esentially poll_file()!
|
||||
} else {
|
||||
fs_node_walk(etry->act->edge->node, poll_tree);
|
@ -0,0 +1,286 @@
|
||||
From 9ac54f0d7d70b8a9879889b4522a1d552fca1100 Mon Sep 17 00:00:00 2001
|
||||
From: Noriko Hosoi <nhosoi@momo7.localdomain>
|
||||
Date: Thu, 12 Jul 2018 11:52:04 -0700
|
||||
Subject: [PATCH] Introducing an option preservecase to imudp and imtcp module
|
||||
for managing the case of FROMHOST value.
|
||||
|
||||
Usage:
|
||||
module(load="imudp" [preservecase="on"|"off"])
|
||||
module(load="imtdp" [preservecase="on"|"off"])
|
||||
|
||||
If preservecase="on", FROMHOST value is handled in the case sensitive manner.
|
||||
If preservecase="off", FROMHOST value is handled in the case insensitive manner.
|
||||
|
||||
To maintain the current behaviour, the default value of preservecase is
|
||||
"on" for imtcp and "off" for imudp.
|
||||
|
||||
Incremented tcpsrvCURR_IF_VERSION by 1.
|
||||
|
||||
References:
|
||||
https://github.com/rsyslog/rsyslog/pull/2774
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1309698
|
||||
---
|
||||
plugins/imtcp/imtcp.c | 14 ++++++++++++--
|
||||
plugins/imudp/imudp.c | 15 ++++++++++++---
|
||||
runtime/msg.c | 6 +++++-
|
||||
runtime/msg.h | 2 ++
|
||||
runtime/net.c | 2 +-
|
||||
runtime/tcpsrv.c | 21 +++++++++++++++++++++
|
||||
runtime/tcpsrv.h | 5 ++++-
|
||||
7 files changed, 57 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c
|
||||
index 8e3dcc0a2..45fa240b5 100644
|
||||
--- a/plugins/imtcp/imtcp.c
|
||||
+++ b/plugins/imtcp/imtcp.c
|
||||
@@ -100,6 +100,7 @@ static struct configSettings_s {
|
||||
int bDisableLFDelim;
|
||||
int discardTruncatedMsg;
|
||||
int bUseFlowControl;
|
||||
+ int bPreserveCase;
|
||||
uchar *gnutlsPriorityString;
|
||||
uchar *pszStrmDrvrAuthMode;
|
||||
uchar *pszInputName;
|
||||
@@ -144,6 +145,7 @@ struct modConfData_s {
|
||||
uchar *pszStrmDrvrAuthMode; /* authentication mode to use */
|
||||
struct cnfarray *permittedPeers;
|
||||
sbool configSetViaV2Method;
|
||||
+ sbool bPreserveCase; /* preserve case of fromhost; true by default */
|
||||
};
|
||||
|
||||
static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
|
||||
@@ -169,7 +171,8 @@ static struct cnfparamdescr modpdescr[] = {
|
||||
{ "keepalive.probes", eCmdHdlrPositiveInt, 0 },
|
||||
{ "keepalive.time", eCmdHdlrPositiveInt, 0 },
|
||||
{ "keepalive.interval", eCmdHdlrPositiveInt, 0 },
|
||||
- { "gnutlsprioritystring", eCmdHdlrString, 0 }
|
||||
+ { "gnutlsprioritystring", eCmdHdlrString, 0 },
|
||||
+ { "preservecase", eCmdHdlrBinary, 0 }
|
||||
};
|
||||
static struct cnfparamblk modpblk =
|
||||
{ CNFPARAMBLK_VERSION,
|
||||
@@ -375,6 +378,7 @@ addListner(modConfData_t *modConf, instanceConf_t *inst)
|
||||
if(pPermPeersRoot != NULL) {
|
||||
CHKiRet(tcpsrv.SetDrvrPermPeers(pOurTcpsrv, pPermPeersRoot));
|
||||
}
|
||||
+ CHKiRet(tcpsrv.SetPreserveCase(pOurTcpsrv, modConf->bPreserveCase));
|
||||
}
|
||||
|
||||
/* initialized, now add socket and listener params */
|
||||
@@ -473,6 +477,7 @@ CODESTARTbeginCnfLoad
|
||||
loadModConf->pszStrmDrvrAuthMode = NULL;
|
||||
loadModConf->permittedPeers = NULL;
|
||||
loadModConf->configSetViaV2Method = 0;
|
||||
+ loadModConf->bPreserveCase = 1; /* default to true */
|
||||
bLegacyCnfModGlobalsPermitted = 1;
|
||||
/* init legacy config variables */
|
||||
cs.pszStrmDrvrAuthMode = NULL;
|
||||
@@ -543,6 +548,8 @@ CODESTARTsetModCnf
|
||||
loadModConf->pszStrmDrvrName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
} else if(!strcmp(modpblk.descr[i].name, "permittedpeer")) {
|
||||
loadModConf->permittedPeers = cnfarrayDup(pvals[i].val.d.ar);
|
||||
+ } else if(!strcmp(modpblk.descr[i].name, "preservecase")) {
|
||||
+ loadModConf->bPreserveCase = (int) pvals[i].val.d.n;
|
||||
} else {
|
||||
dbgprintf("imtcp: program error, non-handled "
|
||||
"param '%s' in beginCnfLoad\n", modpblk.descr[i].name);
|
||||
@@ -584,6 +591,7 @@ CODESTARTendCnfLoad
|
||||
loadModConf->pszStrmDrvrAuthMode = cs.pszStrmDrvrAuthMode;
|
||||
cs.pszStrmDrvrAuthMode = NULL;
|
||||
}
|
||||
+ pModConf->bPreserveCase = cs.bPreserveCase;
|
||||
}
|
||||
free(cs.pszStrmDrvrAuthMode);
|
||||
cs.pszStrmDrvrAuthMode = NULL;
|
||||
@@ -731,6 +739,7 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus
|
||||
cs.pszInputName = NULL;
|
||||
free(cs.pszStrmDrvrAuthMode);
|
||||
cs.pszStrmDrvrAuthMode = NULL;
|
||||
+ cs.bPreserveCase = 1;
|
||||
return RS_RET_OK;
|
||||
}
|
||||
|
||||
@@ -797,7 +806,8 @@ CODEmodInit_QueryRegCFSLineHdlr
|
||||
NULL, &cs.bEmitMsgOnClose, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
||||
CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0, eCmdHdlrInt,
|
||||
NULL, &cs.iStrmDrvrMode, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
||||
-
|
||||
+ CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverpreservecase"), 1, eCmdHdlrBinary,
|
||||
+ NULL, &cs.bPreserveCase, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
||||
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler,
|
||||
resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
|
||||
ENDmodInit
|
||||
diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c
|
||||
index 51a9d712a..74437781c 100644
|
||||
--- a/plugins/imudp/imudp.c
|
||||
+++ b/plugins/imudp/imudp.c
|
||||
@@ -152,6 +152,7 @@ struct modConfData_s {
|
||||
int batchSize; /* max nbr of input batch --> also recvmmsg() max count */
|
||||
int8_t wrkrMax; /* max nbr of worker threads */
|
||||
sbool configSetViaV2Method;
|
||||
+ sbool bPreserveCase; /* preserves the case of fromhost; "off" by default */
|
||||
};
|
||||
static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
|
||||
static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */
|
||||
@@ -162,7 +163,8 @@ static struct cnfparamdescr modpdescr[] = {
|
||||
{ "schedulingpriority", eCmdHdlrInt, 0 },
|
||||
{ "batchsize", eCmdHdlrInt, 0 },
|
||||
{ "threads", eCmdHdlrPositiveInt, 0 },
|
||||
- { "timerequery", eCmdHdlrInt, 0 }
|
||||
+ { "timerequery", eCmdHdlrInt, 0 },
|
||||
+ { "preservecase", eCmdHdlrBinary, 0 }
|
||||
};
|
||||
static struct cnfparamblk modpblk =
|
||||
{ CNFPARAMBLK_VERSION,
|
||||
@@ -447,8 +449,12 @@ processPacket(struct lstn_s *lstn, struct sockaddr_storage *frominetPrev, int *p
|
||||
if(lstn->dfltTZ != NULL)
|
||||
MsgSetDfltTZ(pMsg, (char*) lstn->dfltTZ);
|
||||
pMsg->msgFlags = NEEDS_PARSING | PARSE_HOSTNAME | NEEDS_DNSRESOL;
|
||||
- if(*pbIsPermitted == 2)
|
||||
- pMsg->msgFlags |= NEEDS_ACLCHK_U; /* request ACL check after resolution */
|
||||
+ if(*pbIsPermitted == 2) {
|
||||
+ pMsg->msgFlags |= NEEDS_ACLCHK_U; /* request ACL check after resolution */
|
||||
+ }
|
||||
+ if(runModConf->bPreserveCase) {
|
||||
+ pMsg->msgFlags |= PRESERVE_CASE; /* preserve case of fromhost */
|
||||
+ }
|
||||
CHKiRet(msgSetFromSockinfo(pMsg, frominet));
|
||||
CHKiRet(ratelimitAddMsg(lstn->ratelimiter, multiSub, pMsg));
|
||||
STATSCOUNTER_INC(lstn->ctrSubmit, lstn->mutCtrSubmit);
|
||||
@@ -1030,6 +1036,7 @@ CODESTARTbeginCnfLoad
|
||||
loadModConf->iTimeRequery = TIME_REQUERY_DFLT;
|
||||
loadModConf->iSchedPrio = SCHED_PRIO_UNSET;
|
||||
loadModConf->pszSchedPolicy = NULL;
|
||||
+ loadModConf->bPreserveCase = 0; /* off */
|
||||
bLegacyCnfModGlobalsPermitted = 1;
|
||||
/* init legacy config vars */
|
||||
cs.pszBindRuleset = NULL;
|
||||
@@ -1079,6 +1086,8 @@ CODESTARTsetModCnf
|
||||
} else {
|
||||
loadModConf->wrkrMax = wrkrMax;
|
||||
}
|
||||
+ } else if(!strcmp(modpblk.descr[i].name, "preservecase")) {
|
||||
+ loadModConf->bPreserveCase = (int) pvals[i].val.d.n;
|
||||
} else {
|
||||
dbgprintf("imudp: program error, non-handled "
|
||||
"param '%s' in beginCnfLoad\n", modpblk.descr[i].name);
|
||||
diff --git a/runtime/msg.c b/runtime/msg.c
|
||||
index c43f81314..9ed4eaf84 100644
|
||||
--- a/runtime/msg.c
|
||||
+++ b/runtime/msg.c
|
||||
@@ -506,7 +506,11 @@ resolveDNS(smsg_t * const pMsg) {
|
||||
MsgLock(pMsg);
|
||||
CHKiRet(objUse(net, CORE_COMPONENT));
|
||||
if(pMsg->msgFlags & NEEDS_DNSRESOL) {
|
||||
- localRet = net.cvthname(pMsg->rcvFrom.pfrominet, &localName, NULL, &ip);
|
||||
+ if (pMsg->msgFlags & PRESERVE_CASE) {
|
||||
+ localRet = net.cvthname(pMsg->rcvFrom.pfrominet, NULL, &localName, &ip);
|
||||
+ } else {
|
||||
+ localRet = net.cvthname(pMsg->rcvFrom.pfrominet, &localName, NULL, &ip);
|
||||
+ }
|
||||
if(localRet == RS_RET_OK) {
|
||||
/* we pass down the props, so no need for AddRef */
|
||||
MsgSetRcvFromWithoutAddRef(pMsg, localName);
|
||||
diff --git a/runtime/msg.h b/runtime/msg.h
|
||||
index cd530aca3..1287cb7a4 100644
|
||||
--- a/runtime/msg.h
|
||||
+++ b/runtime/msg.h
|
||||
@@ -156,6 +156,8 @@ struct msg {
|
||||
/* check UDP ACLs after DNS resolution has been done in main queue consumer */
|
||||
#define NO_PRI_IN_RAW 0x100
|
||||
/* rawmsg does not include a PRI (Solaris!), but PRI is already set correctly in the msg object */
|
||||
+#define PRESERVE_CASE 0x200
|
||||
+/* preserve case in fromhost */
|
||||
|
||||
/* (syslog) protocol types */
|
||||
#define MSG_LEGACY_PROTOCOL 0
|
||||
diff --git a/runtime/net.c b/runtime/net.c
|
||||
index d6ff8a3d4..aef906601 100644
|
||||
--- a/runtime/net.c
|
||||
+++ b/runtime/net.c
|
||||
@@ -1152,7 +1152,7 @@ cvthname(struct sockaddr_storage *f, prop_t **localName, prop_t **fqdn, prop_t *
|
||||
{
|
||||
DEFiRet;
|
||||
assert(f != NULL);
|
||||
- iRet = dnscacheLookup(f, NULL, fqdn, localName, ip);
|
||||
+ iRet = dnscacheLookup(f, fqdn, NULL, localName, ip);
|
||||
RETiRet;
|
||||
}
|
||||
|
||||
diff --git a/runtime/tcpsrv.c b/runtime/tcpsrv.c
|
||||
index 61e9ff4d2..d5993b4f0 100644
|
||||
--- a/runtime/tcpsrv.c
|
||||
+++ b/runtime/tcpsrv.c
|
||||
@@ -495,6 +495,15 @@ SessAccept(tcpsrv_t *pThis, tcpLstnPortList_t *pLstnInfo, tcps_sess_t **ppSess,
|
||||
|
||||
/* get the host name */
|
||||
CHKiRet(netstrm.GetRemoteHName(pNewStrm, &fromHostFQDN));
|
||||
+ if (!pThis->bPreserveCase) {
|
||||
+ /* preserve_case = off */
|
||||
+ uchar *p;
|
||||
+ for(p = fromHostFQDN; *p; p++) {
|
||||
+ if (isupper((int) *p)) {
|
||||
+ *p = tolower((int) *p);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
CHKiRet(netstrm.GetRemoteIP(pNewStrm, &fromHostIP));
|
||||
CHKiRet(netstrm.GetRemAddr(pNewStrm, &addr));
|
||||
/* TODO: check if we need to strip the domain name here -- rgerhards, 2008-04-24 */
|
||||
@@ -1001,6 +1010,7 @@ BEGINobjConstruct(tcpsrv) /* be sure to specify the object type also in END macr
|
||||
pThis->ratelimitBurst = 10000;
|
||||
pThis->bUseFlowControl = 1;
|
||||
pThis->pszDrvrName = NULL;
|
||||
+ pThis->bPreserveCase = 1; /* preserve case in fromhost; default to true. */
|
||||
ENDobjConstruct(tcpsrv)
|
||||
|
||||
|
||||
@@ -1433,6 +1443,16 @@ SetSessMax(tcpsrv_t *pThis, int iMax)
|
||||
}
|
||||
|
||||
|
||||
+static rsRetVal
|
||||
+SetPreserveCase(tcpsrv_t *pThis, int bPreserveCase)
|
||||
+{
|
||||
+ DEFiRet;
|
||||
+ ISOBJ_TYPE_assert(pThis, tcpsrv);
|
||||
+ pThis-> bPreserveCase = bPreserveCase;
|
||||
+ RETiRet;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* queryInterface function
|
||||
* rgerhards, 2008-02-29
|
||||
*/
|
||||
@@ -1491,6 +1511,7 @@ CODESTARTobjQueryInterface(tcpsrv)
|
||||
pIf->SetRuleset = SetRuleset;
|
||||
pIf->SetLinuxLikeRatelimiters = SetLinuxLikeRatelimiters;
|
||||
pIf->SetNotificationOnRemoteClose = SetNotificationOnRemoteClose;
|
||||
+ pIf->SetPreserveCase = SetPreserveCase;
|
||||
|
||||
finalize_it:
|
||||
ENDobjQueryInterface(tcpsrv)
|
||||
diff --git a/runtime/tcpsrv.h b/runtime/tcpsrv.h
|
||||
index 22a65c20a..f17b1b438 100644
|
||||
--- a/runtime/tcpsrv.h
|
||||
+++ b/runtime/tcpsrv.h
|
||||
@@ -85,6 +85,7 @@ struct tcpsrv_s {
|
||||
int maxFrameSize; /**< max frame size for octet counted*/
|
||||
int bDisableLFDelim; /**< if 1, standard LF frame delimiter is disabled (*very dangerous*) */
|
||||
int discardTruncatedMsg;/**< discard msg part that has been truncated*/
|
||||
+ sbool bPreserveCase; /**< preserve case in fromhost */
|
||||
int ratelimitInterval;
|
||||
int ratelimitBurst;
|
||||
tcps_sess_t **pSessions;/**< array of all of our sessions */
|
||||
@@ -177,8 +178,10 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */
|
||||
rsRetVal (*SetbSPFramingFix)(tcpsrv_t*, sbool);
|
||||
/* added v19 -- PascalWithopf, 2017-08-08 */
|
||||
rsRetVal (*SetGnutlsPriorityString)(tcpsrv_t*, uchar*);
|
||||
+ /* added v21 -- Preserve case in fromhost, 2018-08-16 */
|
||||
+ rsRetVal (*SetPreserveCase)(tcpsrv_t *pThis, int bPreserveCase);
|
||||
ENDinterface(tcpsrv)
|
||||
-#define tcpsrvCURR_IF_VERSION 20 /* increment whenever you change the interface structure! */
|
||||
+#define tcpsrvCURR_IF_VERSION 21 /* increment whenever you change the interface structure! */
|
||||
/* change for v4:
|
||||
* - SetAddtlFrameDelim() added -- rgerhards, 2008-12-10
|
||||
* - SetInputName() added -- rgerhards, 2008-12-10
|
761
SOURCES/rsyslog-8.37.0-rhbz1622768-kubernetes-404-handling.patch
Normal file
761
SOURCES/rsyslog-8.37.0-rhbz1622768-kubernetes-404-handling.patch
Normal file
@ -0,0 +1,761 @@
|
||||
From 3987cd929d859f900318b393133c3bdde8dfffd5 Mon Sep 17 00:00:00 2001
|
||||
From: Rich Megginson <rmeggins@redhat.com>
|
||||
Date: Tue, 28 Aug 2018 12:44:23 -0600
|
||||
Subject: [PATCH] mmkubertnetes: action fails preparation cycle if kubernetes
|
||||
API destroys resource during bootup sequence
|
||||
|
||||
The plugin was not handling 404 Not Found correctly when looking
|
||||
up pods and namespaces. In this case, we assume the pod/namespace
|
||||
was deleted, annotate the record with whatever metadata we have,
|
||||
and cache the fact that the pod/namespace is missing so we don't
|
||||
attempt to look it up again.
|
||||
In addition, the plugin was not handling error 429 Busy correctly.
|
||||
In this case, it should also annotate the record with whatever
|
||||
metadata it has, and _not_ cache anything. By default the plugin
|
||||
will retry every 5 seconds to connect to Kubernetes. This
|
||||
behavior is controlled by the new config param `busyretryinterval`.
|
||||
This commit also adds impstats counters so that admins can
|
||||
view the state of the plugin to see if the lookups are working
|
||||
or are returning errors. The stats are reported per-instance
|
||||
or per-action to facilitate using multiple different actions
|
||||
for different Kubernetes servers.
|
||||
This commit also adds support for client cert auth to
|
||||
Kubernetes via the two new config params `tls.mycert` and
|
||||
`tls.myprivkey`.
|
||||
---
|
||||
contrib/mmkubernetes/mmkubernetes.c | 296 ++++++++++++++++++++++++----
|
||||
7 files changed, 160 insertions(+), 36 deletions(-)
|
||||
|
||||
diff --git a/contrib/mmkubernetes/mmkubernetes.c b/contrib/mmkubernetes/mmkubernetes.c
|
||||
index 422cb2577..5bf5b049d 100644
|
||||
--- a/contrib/mmkubernetes/mmkubernetes.c
|
||||
+++ b/contrib/mmkubernetes/mmkubernetes.c
|
||||
@@ -52,9 +52,12 @@
|
||||
#include "syslogd-types.h"
|
||||
#include "module-template.h"
|
||||
#include "errmsg.h"
|
||||
+#include "statsobj.h"
|
||||
#include "regexp.h"
|
||||
#include "hashtable.h"
|
||||
#include "srUtils.h"
|
||||
+#include "unicode-helper.h"
|
||||
+#include "datetime.h"
|
||||
|
||||
/* static data */
|
||||
MODULE_TYPE_OUTPUT /* this is technically an output plugin */
|
||||
@@ -62,6 +65,8 @@ MODULE_TYPE_KEEP /* releasing the module would cause a leak through libcurl */
|
||||
MODULE_CNFNAME("mmkubernetes")
|
||||
DEF_OMOD_STATIC_DATA
|
||||
DEFobjCurrIf(regexp)
|
||||
+DEFobjCurrIf(statsobj)
|
||||
+DEFobjCurrIf(datetime)
|
||||
|
||||
#define HAVE_LOADSAMPLESFROMSTRING 1
|
||||
#if defined(NO_LOADSAMPLESFROMSTRING)
|
||||
@@ -95,12 +100,14 @@ DEFobjCurrIf(regexp)
|
||||
#define DFLT_CONTAINER_NAME "$!CONTAINER_NAME" /* name of variable holding CONTAINER_NAME value */
|
||||
#define DFLT_CONTAINER_ID_FULL "$!CONTAINER_ID_FULL" /* name of variable holding CONTAINER_ID_FULL value */
|
||||
#define DFLT_KUBERNETES_URL "https://kubernetes.default.svc.cluster.local:443"
|
||||
+#define DFLT_BUSY_RETRY_INTERVAL 5 /* retry every 5 seconds */
|
||||
|
||||
static struct cache_s {
|
||||
const uchar *kbUrl;
|
||||
struct hashtable *mdHt;
|
||||
struct hashtable *nsHt;
|
||||
pthread_mutex_t *cacheMtx;
|
||||
+ int lastBusyTime;
|
||||
} **caches;
|
||||
|
||||
typedef struct {
|
||||
@@ -116,6 +123,8 @@ struct modConfData_s {
|
||||
uchar *srcMetadataPath; /* where to get data for kubernetes queries */
|
||||
uchar *dstMetadataPath; /* where to put metadata obtained from kubernetes */
|
||||
uchar *caCertFile; /* File holding the CA cert (+optional chain) of CA that issued the Kubernetes server cert */
|
||||
+ uchar *myCertFile; /* File holding cert corresponding to private key used for client cert auth */
|
||||
+ uchar *myPrivKeyFile; /* File holding private key corresponding to cert used for client cert auth */
|
||||
sbool allowUnsignedCerts; /* For testing/debugging - do not check for CA certs (CURLOPT_SSL_VERIFYPEER FALSE) */
|
||||
uchar *token; /* The token value to use to authenticate to Kubernetes - takes precedence over tokenFile */
|
||||
uchar *tokenFile; /* The file whose contents is the token value to use to authenticate to Kubernetes */
|
||||
@@ -127,6 +136,7 @@ struct modConfData_s {
|
||||
uchar *fnRulebase; /* lognorm rulebase filename for container log filename match */
|
||||
char *contRules; /* lognorm rules for CONTAINER_NAME value match */
|
||||
uchar *contRulebase; /* lognorm rulebase filename for CONTAINER_NAME value match */
|
||||
+ int busyRetryInterval; /* how to handle 429 response - 0 means error, non-zero means retry every N seconds */
|
||||
};
|
||||
|
||||
/* action (instance) configuration data */
|
||||
@@ -135,6 +145,8 @@ typedef struct _instanceData {
|
||||
msgPropDescr_t *srcMetadataDescr; /* where to get data for kubernetes queries */
|
||||
uchar *dstMetadataPath; /* where to put metadata obtained from kubernetes */
|
||||
uchar *caCertFile; /* File holding the CA cert (+optional chain) of CA that issued the Kubernetes server cert */
|
||||
+ uchar *myCertFile; /* File holding cert corresponding to private key used for client cert auth */
|
||||
+ uchar *myPrivKeyFile; /* File holding private key corresponding to cert used for client cert auth */
|
||||
sbool allowUnsignedCerts; /* For testing/debugging - do not check for CA certs (CURLOPT_SSL_VERIFYPEER FALSE) */
|
||||
uchar *token; /* The token value to use to authenticate to Kubernetes - takes precedence over tokenFile */
|
||||
uchar *tokenFile; /* The file whose contents is the token value to use to authenticate to Kubernetes */
|
||||
@@ -151,6 +163,7 @@ typedef struct _instanceData {
|
||||
msgPropDescr_t *contNameDescr; /* CONTAINER_NAME field */
|
||||
msgPropDescr_t *contIdFullDescr; /* CONTAINER_ID_FULL field */
|
||||
struct cache_s *cache;
|
||||
+ int busyRetryInterval; /* how to handle 429 response - 0 means error, non-zero means retry every N seconds */
|
||||
} instanceData;
|
||||
|
||||
typedef struct wrkrInstanceData {
|
||||
@@ -159,6 +172,16 @@ typedef struct wrkrInstanceData {
|
||||
struct curl_slist *curlHdr;
|
||||
char *curlRply;
|
||||
size_t curlRplyLen;
|
||||
+ statsobj_t *stats; /* stats for this instance */
|
||||
+ STATSCOUNTER_DEF(k8sRecordSeen, mutK8sRecordSeen)
|
||||
+ STATSCOUNTER_DEF(namespaceMetadataSuccess, mutNamespaceMetadataSuccess)
|
||||
+ STATSCOUNTER_DEF(namespaceMetadataNotFound, mutNamespaceMetadataNotFound)
|
||||
+ STATSCOUNTER_DEF(namespaceMetadataBusy, mutNamespaceMetadataBusy)
|
||||
+ STATSCOUNTER_DEF(namespaceMetadataError, mutNamespaceMetadataError)
|
||||
+ STATSCOUNTER_DEF(podMetadataSuccess, mutPodMetadataSuccess)
|
||||
+ STATSCOUNTER_DEF(podMetadataNotFound, mutPodMetadataNotFound)
|
||||
+ STATSCOUNTER_DEF(podMetadataBusy, mutPodMetadataBusy)
|
||||
+ STATSCOUNTER_DEF(podMetadataError, mutPodMetadataError)
|
||||
} wrkrInstanceData_t;
|
||||
|
||||
/* module parameters (v6 config format) */
|
||||
@@ -167,6 +190,8 @@ static struct cnfparamdescr modpdescr[] = {
|
||||
{ "srcmetadatapath", eCmdHdlrString, 0 },
|
||||
{ "dstmetadatapath", eCmdHdlrString, 0 },
|
||||
{ "tls.cacert", eCmdHdlrString, 0 },
|
||||
+ { "tls.mycert", eCmdHdlrString, 0 },
|
||||
+ { "tls.myprivkey", eCmdHdlrString, 0 },
|
||||
{ "allowunsignedcerts", eCmdHdlrBinary, 0 },
|
||||
{ "token", eCmdHdlrString, 0 },
|
||||
{ "tokenfile", eCmdHdlrString, 0 },
|
||||
@@ -174,7 +199,8 @@ static struct cnfparamdescr modpdescr[] = {
|
||||
{ "de_dot", eCmdHdlrBinary, 0 },
|
||||
{ "de_dot_separator", eCmdHdlrString, 0 },
|
||||
{ "filenamerulebase", eCmdHdlrString, 0 },
|
||||
- { "containerrulebase", eCmdHdlrString, 0 }
|
||||
+ { "containerrulebase", eCmdHdlrString, 0 },
|
||||
+ { "busyretryinterval", eCmdHdlrInt, 0 }
|
||||
#if HAVE_LOADSAMPLESFROMSTRING == 1
|
||||
,
|
||||
{ "filenamerules", eCmdHdlrArray, 0 },
|
||||
@@ -193,6 +219,8 @@ static struct cnfparamdescr actpdescr[] = {
|
||||
{ "srcmetadatapath", eCmdHdlrString, 0 },
|
||||
{ "dstmetadatapath", eCmdHdlrString, 0 },
|
||||
{ "tls.cacert", eCmdHdlrString, 0 },
|
||||
+ { "tls.mycert", eCmdHdlrString, 0 },
|
||||
+ { "tls.myprivkey", eCmdHdlrString, 0 },
|
||||
{ "allowunsignedcerts", eCmdHdlrBinary, 0 },
|
||||
{ "token", eCmdHdlrString, 0 },
|
||||
{ "tokenfile", eCmdHdlrString, 0 },
|
||||
@@ -200,7 +228,8 @@ static struct cnfparamdescr actpdescr[] = {
|
||||
{ "de_dot", eCmdHdlrBinary, 0 },
|
||||
{ "de_dot_separator", eCmdHdlrString, 0 },
|
||||
{ "filenamerulebase", eCmdHdlrString, 0 },
|
||||
- { "containerrulebase", eCmdHdlrString, 0 }
|
||||
+ { "containerrulebase", eCmdHdlrString, 0 },
|
||||
+ { "busyretryinterval", eCmdHdlrInt, 0 }
|
||||
#if HAVE_LOADSAMPLESFROMSTRING == 1
|
||||
,
|
||||
{ "filenamerules", eCmdHdlrArray, 0 },
|
||||
@@ -493,8 +522,9 @@ ENDbeginCnfLoad
|
||||
BEGINsetModCnf
|
||||
struct cnfparamvals *pvals = NULL;
|
||||
int i;
|
||||
- FILE *fp;
|
||||
+ FILE *fp = NULL;
|
||||
int ret;
|
||||
+ char errStr[1024];
|
||||
CODESTARTsetModCnf
|
||||
pvals = nvlstGetParams(lst, &modpblk, NULL);
|
||||
if(pvals == NULL) {
|
||||
@@ -509,6 +539,7 @@ CODESTARTsetModCnf
|
||||
}
|
||||
|
||||
loadModConf->de_dot = DFLT_DE_DOT;
|
||||
+ loadModConf->busyRetryInterval = DFLT_BUSY_RETRY_INTERVAL;
|
||||
for(i = 0 ; i < modpblk.nParams ; ++i) {
|
||||
if(!pvals[i].bUsed) {
|
||||
continue;
|
||||
@@ -528,15 +559,42 @@ CODESTARTsetModCnf
|
||||
loadModConf->caCertFile = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
fp = fopen((const char*)loadModConf->caCertFile, "r");
|
||||
if(fp == NULL) {
|
||||
- char errStr[1024];
|
||||
rs_strerror_r(errno, errStr, sizeof(errStr));
|
||||
iRet = RS_RET_NO_FILE_ACCESS;
|
||||
LogError(0, iRet,
|
||||
- "error: certificate file %s couldn't be accessed: %s\n",
|
||||
+ "error: 'tls.cacert' file %s couldn't be accessed: %s\n",
|
||||
loadModConf->caCertFile, errStr);
|
||||
ABORT_FINALIZE(iRet);
|
||||
} else {
|
||||
fclose(fp);
|
||||
+ fp = NULL;
|
||||
+ }
|
||||
+ } else if(!strcmp(modpblk.descr[i].name, "tls.mycert")) {
|
||||
+ free(loadModConf->myCertFile);
|
||||
+ loadModConf->myCertFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
+ fp = fopen((const char*)loadModConf->myCertFile, "r");
|
||||
+ if(fp == NULL) {
|
||||
+ rs_strerror_r(errno, errStr, sizeof(errStr));
|
||||
+ iRet = RS_RET_NO_FILE_ACCESS;
|
||||
+ LogError(0, iRet,
|
||||
+ "error: 'tls.mycert' file %s couldn't be accessed: %s\n",
|
||||
+ loadModConf->myCertFile, errStr);
|
||||
+ } else {
|
||||
+ fclose(fp);
|
||||
+ fp = NULL;
|
||||
+ }
|
||||
+ } else if(!strcmp(modpblk.descr[i].name, "tls.myprivkey")) {
|
||||
+ loadModConf->myPrivKeyFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
+ fp = fopen((const char*)loadModConf->myPrivKeyFile, "r");
|
||||
+ if(fp == NULL) {
|
||||
+ rs_strerror_r(errno, errStr, sizeof(errStr));
|
||||
+ iRet = RS_RET_NO_FILE_ACCESS;
|
||||
+ LogError(0, iRet,
|
||||
+ "error: 'tls.myprivkey' file %s couldn't be accessed: %s\n",
|
||||
+ loadModConf->myPrivKeyFile, errStr);
|
||||
+ } else {
|
||||
+ fclose(fp);
|
||||
+ fp = NULL;
|
||||
}
|
||||
} else if(!strcmp(modpblk.descr[i].name, "allowunsignedcerts")) {
|
||||
loadModConf->allowUnsignedCerts = pvals[i].val.d.n;
|
||||
@@ -548,7 +606,6 @@ CODESTARTsetModCnf
|
||||
loadModConf->tokenFile = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
fp = fopen((const char*)loadModConf->tokenFile, "r");
|
||||
if(fp == NULL) {
|
||||
- char errStr[1024];
|
||||
rs_strerror_r(errno, errStr, sizeof(errStr));
|
||||
iRet = RS_RET_NO_FILE_ACCESS;
|
||||
LogError(0, iRet,
|
||||
@@ -557,6 +614,7 @@ CODESTARTsetModCnf
|
||||
ABORT_FINALIZE(iRet);
|
||||
} else {
|
||||
fclose(fp);
|
||||
+ fp = NULL;
|
||||
}
|
||||
} else if(!strcmp(modpblk.descr[i].name, "annotation_match")) {
|
||||
free_annotationmatch(&loadModConf->annotation_match);
|
||||
@@ -577,7 +635,6 @@ CODESTARTsetModCnf
|
||||
loadModConf->fnRulebase = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
fp = fopen((const char*)loadModConf->fnRulebase, "r");
|
||||
if(fp == NULL) {
|
||||
- char errStr[1024];
|
||||
rs_strerror_r(errno, errStr, sizeof(errStr));
|
||||
iRet = RS_RET_NO_FILE_ACCESS;
|
||||
LogError(0, iRet,
|
||||
@@ -586,6 +643,7 @@ CODESTARTsetModCnf
|
||||
ABORT_FINALIZE(iRet);
|
||||
} else {
|
||||
fclose(fp);
|
||||
+ fp = NULL;
|
||||
}
|
||||
#if HAVE_LOADSAMPLESFROMSTRING == 1
|
||||
} else if(!strcmp(modpblk.descr[i].name, "containerrules")) {
|
||||
@@ -597,7 +655,6 @@ CODESTARTsetModCnf
|
||||
loadModConf->contRulebase = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
fp = fopen((const char*)loadModConf->contRulebase, "r");
|
||||
if(fp == NULL) {
|
||||
- char errStr[1024];
|
||||
rs_strerror_r(errno, errStr, sizeof(errStr));
|
||||
iRet = RS_RET_NO_FILE_ACCESS;
|
||||
LogError(0, iRet,
|
||||
@@ -606,7 +663,10 @@ CODESTARTsetModCnf
|
||||
ABORT_FINALIZE(iRet);
|
||||
} else {
|
||||
fclose(fp);
|
||||
+ fp = NULL;
|
||||
}
|
||||
+ } else if(!strcmp(modpblk.descr[i].name, "busyretryinterval")) {
|
||||
+ loadModConf->busyRetryInterval = pvals[i].val.d.n;
|
||||
} else {
|
||||
dbgprintf("mmkubernetes: program error, non-handled "
|
||||
"param '%s' in module() block\n", modpblk.descr[i].name);
|
||||
@@ -650,6 +710,8 @@ CODESTARTsetModCnf
|
||||
caches = calloc(1, sizeof(struct cache_s *));
|
||||
|
||||
finalize_it:
|
||||
+ if (fp)
|
||||
+ fclose(fp);
|
||||
if(pvals != NULL)
|
||||
cnfparamvalsDestruct(pvals, &modpblk);
|
||||
ENDsetModCnf
|
||||
@@ -667,6 +729,8 @@ CODESTARTfreeInstance
|
||||
free(pData->srcMetadataDescr);
|
||||
free(pData->dstMetadataPath);
|
||||
free(pData->caCertFile);
|
||||
+ free(pData->myCertFile);
|
||||
+ free(pData->myPrivKeyFile);
|
||||
free(pData->token);
|
||||
free(pData->tokenFile);
|
||||
free(pData->fnRules);
|
||||
@@ -710,6 +774,45 @@ CODESTARTcreateWrkrInstance
|
||||
char *tokenHdr = NULL;
|
||||
FILE *fp = NULL;
|
||||
char *token = NULL;
|
||||
+ char *statsName = NULL;
|
||||
+
|
||||
+ CHKiRet(statsobj.Construct(&(pWrkrData->stats)));
|
||||
+ if ((-1 == asprintf(&statsName, "mmkubernetes(%s)", pWrkrData->pData->kubernetesUrl)) ||
|
||||
+ (!statsName)) {
|
||||
+ ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
|
||||
+ }
|
||||
+ CHKiRet(statsobj.SetName(pWrkrData->stats, (uchar *)statsName));
|
||||
+ free(statsName);
|
||||
+ statsName = NULL;
|
||||
+ CHKiRet(statsobj.SetOrigin(pWrkrData->stats, UCHAR_CONSTANT("mmkubernetes")));
|
||||
+ STATSCOUNTER_INIT(pWrkrData->k8sRecordSeen, pWrkrData->mutK8sRecordSeen);
|
||||
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("recordseen"),
|
||||
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->k8sRecordSeen)));
|
||||
+ STATSCOUNTER_INIT(pWrkrData->namespaceMetadataSuccess, pWrkrData->mutNamespaceMetadataSuccess);
|
||||
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacemetadatasuccess"),
|
||||
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceMetadataSuccess)));
|
||||
+ STATSCOUNTER_INIT(pWrkrData->namespaceMetadataNotFound, pWrkrData->mutNamespaceMetadataNotFound);
|
||||
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacemetadatanotfound"),
|
||||
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceMetadataNotFound)));
|
||||
+ STATSCOUNTER_INIT(pWrkrData->namespaceMetadataBusy, pWrkrData->mutNamespaceMetadataBusy);
|
||||
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacemetadatabusy"),
|
||||
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceMetadataBusy)));
|
||||
+ STATSCOUNTER_INIT(pWrkrData->namespaceMetadataError, pWrkrData->mutNamespaceMetadataError);
|
||||
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacemetadataerror"),
|
||||
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceMetadataError)));
|
||||
+ STATSCOUNTER_INIT(pWrkrData->podMetadataSuccess, pWrkrData->mutPodMetadataSuccess);
|
||||
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podmetadatasuccess"),
|
||||
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podMetadataSuccess)));
|
||||
+ STATSCOUNTER_INIT(pWrkrData->podMetadataNotFound, pWrkrData->mutPodMetadataNotFound);
|
||||
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podmetadatanotfound"),
|
||||
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podMetadataNotFound)));
|
||||
+ STATSCOUNTER_INIT(pWrkrData->podMetadataBusy, pWrkrData->mutPodMetadataBusy);
|
||||
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podmetadatabusy"),
|
||||
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podMetadataBusy)));
|
||||
+ STATSCOUNTER_INIT(pWrkrData->podMetadataError, pWrkrData->mutPodMetadataError);
|
||||
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podmetadataerror"),
|
||||
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podMetadataError)));
|
||||
+ CHKiRet(statsobj.ConstructFinalize(pWrkrData->stats));
|
||||
|
||||
hdr = curl_slist_append(hdr, "Content-Type: text/json; charset=utf-8");
|
||||
if (pWrkrData->pData->token) {
|
||||
@@ -749,12 +852,20 @@ CODESTARTcreateWrkrInstance
|
||||
curl_easy_setopt(ctx, CURLOPT_WRITEDATA, pWrkrData);
|
||||
if(pWrkrData->pData->caCertFile)
|
||||
curl_easy_setopt(ctx, CURLOPT_CAINFO, pWrkrData->pData->caCertFile);
|
||||
+ if(pWrkrData->pData->myCertFile)
|
||||
+ curl_easy_setopt(ctx, CURLOPT_SSLCERT, pWrkrData->pData->myCertFile);
|
||||
+ if(pWrkrData->pData->myPrivKeyFile)
|
||||
+ curl_easy_setopt(ctx, CURLOPT_SSLKEY, pWrkrData->pData->myPrivKeyFile);
|
||||
if(pWrkrData->pData->allowUnsignedCerts)
|
||||
curl_easy_setopt(ctx, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
|
||||
pWrkrData->curlCtx = ctx;
|
||||
finalize_it:
|
||||
free(token);
|
||||
+ free(statsName);
|
||||
+ if ((iRet != RS_RET_OK) && pWrkrData->stats) {
|
||||
+ statsobj.Destruct(&(pWrkrData->stats));
|
||||
+ }
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
}
|
||||
@@ -765,6 +876,7 @@ BEGINfreeWrkrInstance
|
||||
CODESTARTfreeWrkrInstance
|
||||
curl_easy_cleanup(pWrkrData->curlCtx);
|
||||
curl_slist_free_all(pWrkrData->curlHdr);
|
||||
+ statsobj.Destruct(&(pWrkrData->stats));
|
||||
ENDfreeWrkrInstance
|
||||
|
||||
|
||||
@@ -790,6 +902,8 @@ cacheNew(const uchar *const url)
|
||||
key_equals_string, hashtable_json_object_put);
|
||||
cache->nsHt = create_hashtable(100, hash_from_string,
|
||||
key_equals_string, hashtable_json_object_put);
|
||||
+ dbgprintf("mmkubernetes: created cache mdht [%p] nsht [%p]\n",
|
||||
+ cache->mdHt, cache->nsHt);
|
||||
cache->cacheMtx = malloc(sizeof(pthread_mutex_t));
|
||||
if (!cache->mdHt || !cache->nsHt || !cache->cacheMtx) {
|
||||
free (cache);
|
||||
@@ -797,6 +911,7 @@ cacheNew(const uchar *const url)
|
||||
FINALIZE;
|
||||
}
|
||||
pthread_mutex_init(cache->cacheMtx, NULL);
|
||||
+ cache->lastBusyTime = 0;
|
||||
|
||||
finalize_it:
|
||||
return cache;
|
||||
@@ -816,9 +931,10 @@ static void cacheFree(struct cache_s *cache)
|
||||
BEGINnewActInst
|
||||
struct cnfparamvals *pvals = NULL;
|
||||
int i;
|
||||
- FILE *fp;
|
||||
+ FILE *fp = NULL;
|
||||
char *rxstr = NULL;
|
||||
char *srcMetadataPath = NULL;
|
||||
+ char errStr[1024];
|
||||
CODESTARTnewActInst
|
||||
DBGPRINTF("newActInst (mmkubernetes)\n");
|
||||
|
||||
@@ -840,6 +956,7 @@ CODESTARTnewActInst
|
||||
|
||||
pData->de_dot = loadModConf->de_dot;
|
||||
pData->allowUnsignedCerts = loadModConf->allowUnsignedCerts;
|
||||
+ pData->busyRetryInterval = loadModConf->busyRetryInterval;
|
||||
for(i = 0 ; i < actpblk.nParams ; ++i) {
|
||||
if(!pvals[i].bUsed) {
|
||||
continue;
|
||||
@@ -863,7 +980,6 @@ CODESTARTnewActInst
|
||||
pData->caCertFile = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
fp = fopen((const char*)pData->caCertFile, "r");
|
||||
if(fp == NULL) {
|
||||
- char errStr[1024];
|
||||
rs_strerror_r(errno, errStr, sizeof(errStr));
|
||||
iRet = RS_RET_NO_FILE_ACCESS;
|
||||
LogError(0, iRet,
|
||||
@@ -872,6 +988,33 @@ CODESTARTnewActInst
|
||||
ABORT_FINALIZE(iRet);
|
||||
} else {
|
||||
fclose(fp);
|
||||
+ fp = NULL;
|
||||
+ }
|
||||
+ } else if(!strcmp(actpblk.descr[i].name, "tls.mycert")) {
|
||||
+ pData->myCertFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
+ fp = fopen((const char*)pData->myCertFile, "r");
|
||||
+ if(fp == NULL) {
|
||||
+ rs_strerror_r(errno, errStr, sizeof(errStr));
|
||||
+ iRet = RS_RET_NO_FILE_ACCESS;
|
||||
+ LogError(0, iRet,
|
||||
+ "error: 'tls.mycert' file %s couldn't be accessed: %s\n",
|
||||
+ pData->myCertFile, errStr);
|
||||
+ } else {
|
||||
+ fclose(fp);
|
||||
+ fp = NULL;
|
||||
+ }
|
||||
+ } else if(!strcmp(actpblk.descr[i].name, "tls.myprivkey")) {
|
||||
+ pData->myPrivKeyFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
+ fp = fopen((const char*)pData->myPrivKeyFile, "r");
|
||||
+ if(fp == NULL) {
|
||||
+ rs_strerror_r(errno, errStr, sizeof(errStr));
|
||||
+ iRet = RS_RET_NO_FILE_ACCESS;
|
||||
+ LogError(0, iRet,
|
||||
+ "error: 'tls.myprivkey' file %s couldn't be accessed: %s\n",
|
||||
+ pData->myPrivKeyFile, errStr);
|
||||
+ } else {
|
||||
+ fclose(fp);
|
||||
+ fp = NULL;
|
||||
}
|
||||
} else if(!strcmp(actpblk.descr[i].name, "allowunsignedcerts")) {
|
||||
pData->allowUnsignedCerts = pvals[i].val.d.n;
|
||||
@@ -883,7 +1026,6 @@ CODESTARTnewActInst
|
||||
pData->tokenFile = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
fp = fopen((const char*)pData->tokenFile, "r");
|
||||
if(fp == NULL) {
|
||||
- char errStr[1024];
|
||||
rs_strerror_r(errno, errStr, sizeof(errStr));
|
||||
iRet = RS_RET_NO_FILE_ACCESS;
|
||||
LogError(0, iRet,
|
||||
@@ -892,6 +1034,7 @@ CODESTARTnewActInst
|
||||
ABORT_FINALIZE(iRet);
|
||||
} else {
|
||||
fclose(fp);
|
||||
+ fp = NULL;
|
||||
}
|
||||
} else if(!strcmp(actpblk.descr[i].name, "annotation_match")) {
|
||||
free_annotationmatch(&pData->annotation_match);
|
||||
@@ -912,7 +1055,6 @@ CODESTARTnewActInst
|
||||
pData->fnRulebase = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
fp = fopen((const char*)pData->fnRulebase, "r");
|
||||
if(fp == NULL) {
|
||||
- char errStr[1024];
|
||||
rs_strerror_r(errno, errStr, sizeof(errStr));
|
||||
iRet = RS_RET_NO_FILE_ACCESS;
|
||||
LogError(0, iRet,
|
||||
@@ -921,6 +1063,7 @@ CODESTARTnewActInst
|
||||
ABORT_FINALIZE(iRet);
|
||||
} else {
|
||||
fclose(fp);
|
||||
+ fp = NULL;
|
||||
}
|
||||
#if HAVE_LOADSAMPLESFROMSTRING == 1
|
||||
} else if(!strcmp(modpblk.descr[i].name, "containerrules")) {
|
||||
@@ -932,7 +1075,6 @@ CODESTARTnewActInst
|
||||
pData->contRulebase = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
fp = fopen((const char*)pData->contRulebase, "r");
|
||||
if(fp == NULL) {
|
||||
- char errStr[1024];
|
||||
rs_strerror_r(errno, errStr, sizeof(errStr));
|
||||
iRet = RS_RET_NO_FILE_ACCESS;
|
||||
LogError(0, iRet,
|
||||
@@ -941,7 +1083,10 @@ CODESTARTnewActInst
|
||||
ABORT_FINALIZE(iRet);
|
||||
} else {
|
||||
fclose(fp);
|
||||
+ fp = NULL;
|
||||
}
|
||||
+ } else if(!strcmp(actpblk.descr[i].name, "busyretryinterval")) {
|
||||
+ pData->busyRetryInterval = pvals[i].val.d.n;
|
||||
} else {
|
||||
dbgprintf("mmkubernetes: program error, non-handled "
|
||||
"param '%s' in action() block\n", actpblk.descr[i].name);
|
||||
@@ -982,6 +1127,10 @@ CODESTARTnewActInst
|
||||
pData->dstMetadataPath = (uchar *) strdup((char *) loadModConf->dstMetadataPath);
|
||||
if(pData->caCertFile == NULL && loadModConf->caCertFile)
|
||||
pData->caCertFile = (uchar *) strdup((char *) loadModConf->caCertFile);
|
||||
+ if(pData->myCertFile == NULL && loadModConf->myCertFile)
|
||||
+ pData->myCertFile = (uchar *) strdup((char *) loadModConf->myCertFile);
|
||||
+ if(pData->myPrivKeyFile == NULL && loadModConf->myPrivKeyFile)
|
||||
+ pData->myPrivKeyFile = (uchar *) strdup((char *) loadModConf->myPrivKeyFile);
|
||||
if(pData->token == NULL && loadModConf->token)
|
||||
pData->token = (uchar *) strdup((char *) loadModConf->token);
|
||||
if(pData->tokenFile == NULL && loadModConf->tokenFile)
|
||||
@@ -1018,6 +1167,8 @@ CODESTARTnewActInst
|
||||
CODE_STD_FINALIZERnewActInst
|
||||
if(pvals != NULL)
|
||||
cnfparamvalsDestruct(pvals, &actpblk);
|
||||
+ if(fp)
|
||||
+ fclose(fp);
|
||||
free(rxstr);
|
||||
free(srcMetadataPath);
|
||||
ENDnewActInst
|
||||
@@ -1061,6 +1212,8 @@ CODESTARTfreeCnf
|
||||
free(pModConf->srcMetadataPath);
|
||||
free(pModConf->dstMetadataPath);
|
||||
free(pModConf->caCertFile);
|
||||
+ free(pModConf->myCertFile);
|
||||
+ free(pModConf->myPrivKeyFile);
|
||||
free(pModConf->token);
|
||||
free(pModConf->tokenFile);
|
||||
free(pModConf->de_dot_separator);
|
||||
@@ -1069,8 +1222,11 @@ CODESTARTfreeCnf
|
||||
free(pModConf->contRules);
|
||||
free(pModConf->contRulebase);
|
||||
free_annotationmatch(&pModConf->annotation_match);
|
||||
- for(i = 0; caches[i] != NULL; i++)
|
||||
+ for(i = 0; caches[i] != NULL; i++) {
|
||||
+ dbgprintf("mmkubernetes: freeing cache [%d] mdht [%p] nsht [%p]\n",
|
||||
+ i, caches[i]->mdHt, caches[i]->nsHt);
|
||||
cacheFree(caches[i]);
|
||||
+ }
|
||||
free(caches);
|
||||
ENDfreeCnf
|
||||
|
||||
@@ -1082,6 +1238,8 @@ CODESTARTdbgPrintInstInfo
|
||||
dbgprintf("\tsrcMetadataPath='%s'\n", pData->srcMetadataDescr->name);
|
||||
dbgprintf("\tdstMetadataPath='%s'\n", pData->dstMetadataPath);
|
||||
dbgprintf("\ttls.cacert='%s'\n", pData->caCertFile);
|
||||
+ dbgprintf("\ttls.mycert='%s'\n", pData->myCertFile);
|
||||
+ dbgprintf("\ttls.myprivkey='%s'\n", pData->myPrivKeyFile);
|
||||
dbgprintf("\tallowUnsignedCerts='%d'\n", pData->allowUnsignedCerts);
|
||||
dbgprintf("\ttoken='%s'\n", pData->token);
|
||||
dbgprintf("\ttokenFile='%s'\n", pData->tokenFile);
|
||||
@@ -1093,6 +1251,7 @@ CODESTARTdbgPrintInstInfo
|
||||
dbgprintf("\tfilenamerules='%s'\n", pData->fnRules);
|
||||
dbgprintf("\tcontainerrules='%s'\n", pData->contRules);
|
||||
#endif
|
||||
+ dbgprintf("\tbusyretryinterval='%d'\n", pData->busyRetryInterval);
|
||||
ENDdbgPrintInstInfo
|
||||
|
||||
|
||||
@@ -1206,6 +1365,24 @@ queryKB(wrkrInstanceData_t *pWrkrData, char *url, struct json_object **rply)
|
||||
struct json_object *jo;
|
||||
long resp_code = 400;
|
||||
|
||||
+ if (pWrkrData->pData->cache->lastBusyTime) {
|
||||
+ time_t now;
|
||||
+ datetime.GetTime(&now);
|
||||
+ now -= pWrkrData->pData->cache->lastBusyTime;
|
||||
+ if (now < pWrkrData->pData->busyRetryInterval) {
|
||||
+ LogMsg(0, RS_RET_RETRY, LOG_DEBUG,
|
||||
+ "mmkubernetes: Waited [%ld] of [%d] seconds for the requested url [%s]\n",
|
||||
+ now, pWrkrData->pData->busyRetryInterval, url);
|
||||
+ ABORT_FINALIZE(RS_RET_RETRY);
|
||||
+ } else {
|
||||
+ LogMsg(0, RS_RET_OK, LOG_DEBUG,
|
||||
+ "mmkubernetes: Cleared busy status after [%d] seconds - "
|
||||
+ "will retry the requested url [%s]\n",
|
||||
+ pWrkrData->pData->busyRetryInterval, url);
|
||||
+ pWrkrData->pData->cache->lastBusyTime = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* query kubernetes for pod info */
|
||||
ccode = curl_easy_setopt(pWrkrData->curlCtx, CURLOPT_URL, url);
|
||||
if(ccode != CURLE_OK)
|
||||
@@ -1238,17 +1415,23 @@ queryKB(wrkrInstanceData_t *pWrkrData, char *url, struct json_object **rply)
|
||||
ABORT_FINALIZE(RS_RET_ERR);
|
||||
}
|
||||
if(resp_code == 404) {
|
||||
- LogMsg(0, RS_RET_ERR, LOG_ERR,
|
||||
+ LogMsg(0, RS_RET_NOT_FOUND, LOG_INFO,
|
||||
"mmkubernetes: Not Found: the resource does not exist at url [%s]\n",
|
||||
url);
|
||||
- ABORT_FINALIZE(RS_RET_ERR);
|
||||
+ ABORT_FINALIZE(RS_RET_NOT_FOUND);
|
||||
}
|
||||
if(resp_code == 429) {
|
||||
- LogMsg(0, RS_RET_ERR, LOG_ERR,
|
||||
+ if (pWrkrData->pData->busyRetryInterval) {
|
||||
+ time_t now;
|
||||
+ datetime.GetTime(&now);
|
||||
+ pWrkrData->pData->cache->lastBusyTime = now;
|
||||
+ }
|
||||
+
|
||||
+ LogMsg(0, RS_RET_RETRY, LOG_INFO,
|
||||
"mmkubernetes: Too Many Requests: the server is too heavily loaded "
|
||||
"to provide the data for the requested url [%s]\n",
|
||||
url);
|
||||
- ABORT_FINALIZE(RS_RET_ERR);
|
||||
+ ABORT_FINALIZE(RS_RET_RETRY);
|
||||
}
|
||||
if(resp_code != 200) {
|
||||
LogMsg(0, RS_RET_ERR, LOG_ERR,
|
||||
@@ -1299,12 +1482,14 @@ BEGINdoAction
|
||||
char *mdKey = NULL;
|
||||
struct json_object *jMetadata = NULL, *jMetadataCopy = NULL, *jMsgMeta = NULL,
|
||||
*jo = NULL;
|
||||
- int add_ns_metadata = 0;
|
||||
+ int add_pod_metadata = 1;
|
||||
CODESTARTdoAction
|
||||
CHKiRet_Hdlr(extractMsgMetadata(pMsg, pWrkrData->pData, &jMsgMeta)) {
|
||||
ABORT_FINALIZE((iRet == RS_RET_NOT_FOUND) ? RS_RET_OK : iRet);
|
||||
}
|
||||
|
||||
+ STATSCOUNTER_INC(pWrkrData->k8sRecordSeen, pWrkrData->mutK8sRecordSeen);
|
||||
+
|
||||
if (fjson_object_object_get_ex(jMsgMeta, "pod_name", &jo))
|
||||
podName = json_object_get_string(jo);
|
||||
if (fjson_object_object_get_ex(jMsgMeta, "namespace_name", &jo))
|
||||
@@ -1347,28 +1532,49 @@ CODESTARTdoAction
|
||||
}
|
||||
iRet = queryKB(pWrkrData, url, &jReply);
|
||||
free(url);
|
||||
- /* todo: implement support for the .orphaned namespace */
|
||||
- if (iRet != RS_RET_OK) {
|
||||
+ if (iRet == RS_RET_NOT_FOUND) {
|
||||
+ /* negative cache namespace - make a dummy empty namespace metadata object */
|
||||
+ jNsMeta = json_object_new_object();
|
||||
+ STATSCOUNTER_INC(pWrkrData->namespaceMetadataNotFound,
|
||||
+ pWrkrData->mutNamespaceMetadataNotFound);
|
||||
+ } else if (iRet == RS_RET_RETRY) {
|
||||
+ /* server is busy - retry or error */
|
||||
+ STATSCOUNTER_INC(pWrkrData->namespaceMetadataBusy,
|
||||
+ pWrkrData->mutNamespaceMetadataBusy);
|
||||
+ if (0 == pWrkrData->pData->busyRetryInterval) {
|
||||
+ pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx);
|
||||
+ ABORT_FINALIZE(RS_RET_ERR);
|
||||
+ }
|
||||
+ add_pod_metadata = 0; /* don't cache pod metadata either - retry both */
|
||||
+ } else if (iRet != RS_RET_OK) {
|
||||
+ /* hard error - something the admin needs to fix e.g. network, config, auth */
|
||||
json_object_put(jReply);
|
||||
jReply = NULL;
|
||||
+ STATSCOUNTER_INC(pWrkrData->namespaceMetadataError,
|
||||
+ pWrkrData->mutNamespaceMetadataError);
|
||||
pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx);
|
||||
FINALIZE;
|
||||
- }
|
||||
-
|
||||
- if(fjson_object_object_get_ex(jReply, "metadata", &jNsMeta)) {
|
||||
+ } else if (fjson_object_object_get_ex(jReply, "metadata", &jNsMeta)) {
|
||||
jNsMeta = json_object_get(jNsMeta);
|
||||
parse_labels_annotations(jNsMeta, &pWrkrData->pData->annotation_match,
|
||||
pWrkrData->pData->de_dot,
|
||||
(const char *)pWrkrData->pData->de_dot_separator,
|
||||
pWrkrData->pData->de_dot_separator_len);
|
||||
- add_ns_metadata = 1;
|
||||
+ STATSCOUNTER_INC(pWrkrData->namespaceMetadataSuccess,
|
||||
+ pWrkrData->mutNamespaceMetadataSuccess);
|
||||
} else {
|
||||
/* namespace with no metadata??? */
|
||||
LogMsg(0, RS_RET_ERR, LOG_INFO,
|
||||
"mmkubernetes: namespace [%s] has no metadata!\n", ns);
|
||||
- jNsMeta = NULL;
|
||||
+ /* negative cache namespace - make a dummy empty namespace metadata object */
|
||||
+ jNsMeta = json_object_new_object();
|
||||
+ STATSCOUNTER_INC(pWrkrData->namespaceMetadataSuccess,
|
||||
+ pWrkrData->mutNamespaceMetadataSuccess);
|
||||
}
|
||||
|
||||
+ if(jNsMeta) {
|
||||
+ hashtable_insert(pWrkrData->pData->cache->nsHt, strdup(ns), jNsMeta);
|
||||
+ }
|
||||
json_object_put(jReply);
|
||||
jReply = NULL;
|
||||
}
|
||||
@@ -1381,14 +1587,28 @@ CODESTARTdoAction
|
||||
}
|
||||
iRet = queryKB(pWrkrData, url, &jReply);
|
||||
free(url);
|
||||
- if(iRet != RS_RET_OK) {
|
||||
- if(jNsMeta && add_ns_metadata) {
|
||||
- hashtable_insert(pWrkrData->pData->cache->nsHt, strdup(ns), jNsMeta);
|
||||
+ if (iRet == RS_RET_NOT_FOUND) {
|
||||
+ /* negative cache pod - make a dummy empty pod metadata object */
|
||||
+ iRet = RS_RET_OK;
|
||||
+ STATSCOUNTER_INC(pWrkrData->podMetadataNotFound, pWrkrData->mutPodMetadataNotFound);
|
||||
+ } else if (iRet == RS_RET_RETRY) {
|
||||
+ /* server is busy - retry or error */
|
||||
+ STATSCOUNTER_INC(pWrkrData->podMetadataBusy, pWrkrData->mutPodMetadataBusy);
|
||||
+ if (0 == pWrkrData->pData->busyRetryInterval) {
|
||||
+ pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx);
|
||||
+ ABORT_FINALIZE(RS_RET_ERR);
|
||||
}
|
||||
+ add_pod_metadata = 0; /* do not cache so that we can retry */
|
||||
+ iRet = RS_RET_OK;
|
||||
+ } else if(iRet != RS_RET_OK) {
|
||||
+ /* hard error - something the admin needs to fix e.g. network, config, auth */
|
||||
json_object_put(jReply);
|
||||
jReply = NULL;
|
||||
+ STATSCOUNTER_INC(pWrkrData->podMetadataError, pWrkrData->mutPodMetadataError);
|
||||
pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx);
|
||||
FINALIZE;
|
||||
+ } else {
|
||||
+ STATSCOUNTER_INC(pWrkrData->podMetadataSuccess, pWrkrData->mutPodMetadataSuccess);
|
||||
}
|
||||
|
||||
jo = json_object_new_object();
|
||||
@@ -1435,11 +1655,9 @@ CODESTARTdoAction
|
||||
json_object_object_add(jo, "container_id", json_object_get(jo2));
|
||||
json_object_object_add(jMetadata, "docker", jo);
|
||||
|
||||
- hashtable_insert(pWrkrData->pData->cache->mdHt, mdKey, jMetadata);
|
||||
- mdKey = NULL;
|
||||
- if(jNsMeta && add_ns_metadata) {
|
||||
- hashtable_insert(pWrkrData->pData->cache->nsHt, strdup(ns), jNsMeta);
|
||||
- ns = NULL;
|
||||
+ if (add_pod_metadata) {
|
||||
+ hashtable_insert(pWrkrData->pData->cache->mdHt, mdKey, jMetadata);
|
||||
+ mdKey = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1450,6 +1668,11 @@ CODESTARTdoAction
|
||||
* outside of the cache lock
|
||||
*/
|
||||
jMetadataCopy = json_tokener_parse(json_object_get_string(jMetadata));
|
||||
+ if (!add_pod_metadata) {
|
||||
+ /* jMetadata object was created from scratch and not cached */
|
||||
+ json_object_put(jMetadata);
|
||||
+ jMetadata = NULL;
|
||||
+ }
|
||||
pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx);
|
||||
/* the +1 is there to skip the leading '$' */
|
||||
msgAddJSON(pMsg, (uchar *) pWrkrData->pData->dstMetadataPath + 1, jMetadataCopy, 0, 0);
|
||||
@@ -1470,7 +1693,9 @@ BEGINmodExit
|
||||
CODESTARTmodExit
|
||||
curl_global_cleanup();
|
||||
|
||||
+ objRelease(datetime, CORE_COMPONENT);
|
||||
objRelease(regexp, LM_REGEXP_FILENAME);
|
||||
+ objRelease(statsobj, CORE_COMPONENT);
|
||||
ENDmodExit
|
||||
|
||||
|
||||
@@ -1489,8 +1714,9 @@ CODESTARTmodInit
|
||||
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
|
||||
CODEmodInit_QueryRegCFSLineHdlr
|
||||
DBGPRINTF("mmkubernetes: module compiled with rsyslog version %s.\n", VERSION);
|
||||
+ CHKiRet(objUse(statsobj, CORE_COMPONENT));
|
||||
CHKiRet(objUse(regexp, LM_REGEXP_FILENAME));
|
||||
-
|
||||
+ CHKiRet(objUse(datetime, CORE_COMPONENT));
|
||||
/* CURL_GLOBAL_ALL initializes more than is needed but the
|
||||
* libcurl documentation discourages use of other values
|
||||
*/
|
@ -0,0 +1,263 @@
|
||||
From e8d64cbd15fa84907dc23f8b52d6f2f847b46fec Mon Sep 17 00:00:00 2001
|
||||
From: Rich Megginson <rmeggins@redhat.com>
|
||||
Date: Mon, 10 Sep 2018 17:25:38 -0600
|
||||
Subject: [PATCH] imfile: support for endmsg.regex
|
||||
|
||||
This adds support for endmsg.regex. It is similar to
|
||||
startmsg.regex except that it matches the line that denotes
|
||||
the end of the message, rather than the start of the next message.
|
||||
This is primarily for container log file use cases such as this:
|
||||
|
||||
date stdout P start of message
|
||||
date stdout P middle of message
|
||||
date stdout F end of message
|
||||
|
||||
The `F` means this is the line which contains the final part of
|
||||
the message. The fully assembled message should be
|
||||
`start of message middle of message end of message`.
|
||||
`startmsg.regex="^[^ ]+ stdout F "` will match.
|
||||
|
||||
(cherry picked from commit c902a0938fe163b5351829d2b72001d024895c16)
|
||||
(cherry picked from commit dd4a72c4d52d8da98ed6b86114868e1a450ccb41)
|
||||
---
|
||||
plugins/imfile/imfile.c | 44 ++++--
|
||||
plugins/imptcp/imptcp.c | 10 +-
|
||||
runtime/stream.c | 28 +++-
|
||||
runtime/stream.h | 2 +-
|
||||
4 files changed, 62 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c
|
||||
index 7767c9f02..87706082f 100644
|
||||
--- a/plugins/imfile/imfile.c
|
||||
+++ b/plugins/imfile/imfile.c
|
||||
@@ -126,7 +126,9 @@ struct instanceConf_s {
|
||||
sbool bRMStateOnDel;
|
||||
uint8_t readMode;
|
||||
uchar *startRegex;
|
||||
- regex_t end_preg; /* compiled version of startRegex */
|
||||
+ uchar *endRegex;
|
||||
+ regex_t start_preg; /* compiled version of startRegex */
|
||||
+ regex_t end_preg; /* compiled version of endRegex */
|
||||
sbool discardTruncatedMsg;
|
||||
sbool msgDiscardingError;
|
||||
sbool escapeLF;
|
||||
@@ -281,6 +283,7 @@ static struct cnfparamdescr inppdescr[] = {
|
||||
{ "ruleset", eCmdHdlrString, 0 },
|
||||
{ "readmode", eCmdHdlrInt, 0 },
|
||||
{ "startmsg.regex", eCmdHdlrString, 0 },
|
||||
+ { "endmsg.regex", eCmdHdlrString, 0 },
|
||||
{ "discardtruncatedmsg", eCmdHdlrBinary, 0 },
|
||||
{ "msgdiscardingerror", eCmdHdlrBinary, 0 },
|
||||
{ "escapelf", eCmdHdlrBinary, 0 },
|
||||
@@ -1421,6 +1424,7 @@ pollFileReal(act_obj_t *act, cstr_t **pCStr)
|
||||
int64 strtOffs;
|
||||
DEFiRet;
|
||||
int nProcessed = 0;
|
||||
+ regex_t *start_preg = NULL, *end_preg = NULL;
|
||||
|
||||
DBGPRINTF("pollFileReal enter, pStrm %p, name '%s'\n", act->pStrm, act->name);
|
||||
DBGPRINTF("pollFileReal enter, edge %p\n", act->edge);
|
||||
@@ -1432,15 +1436,18 @@ pollFileReal(act_obj_t *act, cstr_t **pCStr)
|
||||
CHKiRet(openFile(act)); /* open file */
|
||||
}
|
||||
|
||||
+ start_preg = (inst->startRegex == NULL) ? NULL : &inst->start_preg;
|
||||
+ end_preg = (inst->endRegex == NULL) ? NULL : &inst->end_preg;
|
||||
+
|
||||
/* loop below will be exited when strmReadLine() returns EOF */
|
||||
while(glbl.GetGlobalInputTermState() == 0) {
|
||||
if(inst->maxLinesAtOnce != 0 && nProcessed >= inst->maxLinesAtOnce)
|
||||
break;
|
||||
- if(inst->startRegex == NULL) {
|
||||
+ if((start_preg == NULL) && (end_preg == NULL)) {
|
||||
CHKiRet(strm.ReadLine(act->pStrm, pCStr, inst->readMode, inst->escapeLF,
|
||||
inst->trimLineOverBytes, &strtOffs));
|
||||
} else {
|
||||
- CHKiRet(strmReadMultiLine(act->pStrm, pCStr, &inst->end_preg,
|
||||
+ CHKiRet(strmReadMultiLine(act->pStrm, pCStr, start_preg, end_preg,
|
||||
inst->escapeLF, inst->discardTruncatedMsg, inst->msgDiscardingError, &strtOffs));
|
||||
}
|
||||
++nProcessed;
|
||||
@@ -1506,6 +1513,7 @@ createInstance(instanceConf_t **const pinst)
|
||||
inst->iPersistStateInterval = 0;
|
||||
inst->readMode = 0;
|
||||
inst->startRegex = NULL;
|
||||
+ inst->endRegex = NULL;
|
||||
inst->discardTruncatedMsg = 0;
|
||||
inst->msgDiscardingError = 1;
|
||||
inst->bRMStateOnDel = 1;
|
||||
@@ -1713,6 +1721,8 @@ CODESTARTnewInpInst
|
||||
inst->readMode = (sbool) pvals[i].val.d.n;
|
||||
} else if(!strcmp(inppblk.descr[i].name, "startmsg.regex")) {
|
||||
inst->startRegex = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
+ } else if(!strcmp(inppblk.descr[i].name, "endmsg.regex")) {
|
||||
+ inst->endRegex = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
} else if(!strcmp(inppblk.descr[i].name, "discardtruncatedmsg")) {
|
||||
inst->discardTruncatedMsg = (sbool) pvals[i].val.d.n;
|
||||
} else if(!strcmp(inppblk.descr[i].name, "msgdiscardingerror")) {
|
||||
@@ -1753,19 +1763,31 @@ CODESTARTnewInpInst
|
||||
"param '%s'\n", inppblk.descr[i].name);
|
||||
}
|
||||
}
|
||||
- if(inst->readMode != 0 && inst->startRegex != NULL) {
|
||||
+ i = (inst->readMode > 0) ? 1 : 0;
|
||||
+ i = (NULL != inst->startRegex) ? (i+1) : i;
|
||||
+ i = (NULL != inst->endRegex) ? (i+1) : i;
|
||||
+ if(i > 1) {
|
||||
LogError(0, RS_RET_PARAM_NOT_PERMITTED,
|
||||
- "readMode and startmsg.regex cannot be set "
|
||||
- "at the same time --- remove one of them");
|
||||
+ "only one of readMode or startmsg.regex or endmsg.regex can be set "
|
||||
+ "at the same time");
|
||||
ABORT_FINALIZE(RS_RET_PARAM_NOT_PERMITTED);
|
||||
}
|
||||
|
||||
if(inst->startRegex != NULL) {
|
||||
- const int errcode = regcomp(&inst->end_preg, (char*)inst->startRegex, REG_EXTENDED);
|
||||
+ const int errcode = regcomp(&inst->start_preg, (char*)inst->startRegex, REG_EXTENDED);
|
||||
+ if(errcode != 0) {
|
||||
+ char errbuff[512];
|
||||
+ regerror(errcode, &inst->start_preg, errbuff, sizeof(errbuff));
|
||||
+ parser_errmsg("imfile: error in startmsg.regex expansion: %s", errbuff);
|
||||
+ ABORT_FINALIZE(RS_RET_ERR);
|
||||
+ }
|
||||
+ }
|
||||
+ if(inst->endRegex != NULL) {
|
||||
+ const int errcode = regcomp(&inst->end_preg, (char*)inst->endRegex, REG_EXTENDED);
|
||||
if(errcode != 0) {
|
||||
char errbuff[512];
|
||||
regerror(errcode, &inst->end_preg, errbuff, sizeof(errbuff));
|
||||
- parser_errmsg("imfile: error in regex expansion: %s", errbuff);
|
||||
+ parser_errmsg("imfile: error in endmsg.regex expansion: %s", errbuff);
|
||||
ABORT_FINALIZE(RS_RET_ERR);
|
||||
}
|
||||
}
|
||||
@@ -1970,9 +1992,13 @@ CODESTARTfreeCnf
|
||||
free(inst->pszStateFile);
|
||||
free(inst->pszFileName_forOldStateFile);
|
||||
if(inst->startRegex != NULL) {
|
||||
- regfree(&inst->end_preg);
|
||||
+ regfree(&inst->start_preg);
|
||||
free(inst->startRegex);
|
||||
}
|
||||
+ if(inst->endRegex != NULL) {
|
||||
+ regfree(&inst->end_preg);
|
||||
+ free(inst->endRegex);
|
||||
+ }
|
||||
del = inst;
|
||||
inst = inst->next;
|
||||
free(del);
|
||||
diff --git a/plugins/imptcp/imptcp.c b/plugins/imptcp/imptcp.c
|
||||
index 9b6be0f40..a94b97f41 100644
|
||||
--- a/plugins/imptcp/imptcp.c
|
||||
+++ b/plugins/imptcp/imptcp.c
|
||||
@@ -162,7 +162,7 @@ struct instanceConf_s {
|
||||
int ratelimitInterval;
|
||||
int ratelimitBurst;
|
||||
uchar *startRegex;
|
||||
- regex_t end_preg; /* compiled version of startRegex */
|
||||
+ regex_t start_preg; /* compiled version of startRegex */
|
||||
struct instanceConf_s *next;
|
||||
};
|
||||
|
||||
@@ -961,7 +961,7 @@ processDataRcvd_regexFraming(ptcpsess_t *const __restrict__ pThis,
|
||||
if(c == '\n') {
|
||||
pThis->iCurrLine = pThis->iMsg;
|
||||
} else {
|
||||
- const int isMatch = !regexec(&inst->end_preg, (char*)pThis->pMsg+pThis->iCurrLine, 0, NULL, 0);
|
||||
+ const int isMatch = !regexec(&inst->start_preg, (char*)pThis->pMsg+pThis->iCurrLine, 0, NULL, 0);
|
||||
if(isMatch) {
|
||||
DBGPRINTF("regex match (%d), framing line: %s\n", pThis->iCurrLine, pThis->pMsg);
|
||||
strcpy((char*)pThis->pMsg_save, (char*) pThis->pMsg+pThis->iCurrLine);
|
||||
@@ -2188,10 +2188,10 @@ CODESTARTnewInpInst
|
||||
}
|
||||
|
||||
if(inst->startRegex != NULL) {
|
||||
- const int errcode = regcomp(&inst->end_preg, (char*)inst->startRegex, REG_EXTENDED);
|
||||
+ const int errcode = regcomp(&inst->start_preg, (char*)inst->startRegex, REG_EXTENDED);
|
||||
if(errcode != 0) {
|
||||
char errbuff[512];
|
||||
- regerror(errcode, &inst->end_preg, errbuff, sizeof(errbuff));
|
||||
+ regerror(errcode, &inst->start_preg, errbuff, sizeof(errbuff));
|
||||
parser_errmsg("imptcp: error in framing.delimiter.regex expansion: %s", errbuff);
|
||||
ABORT_FINALIZE(RS_RET_ERR);
|
||||
}
|
||||
@@ -2348,7 +2348,7 @@ CODESTARTfreeCnf
|
||||
free(inst->pszInputName);
|
||||
free(inst->dfltTZ);
|
||||
if(inst->startRegex != NULL) {
|
||||
- regfree(&inst->end_preg);
|
||||
+ regfree(&inst->start_preg);
|
||||
free(inst->startRegex);
|
||||
}
|
||||
del = inst;
|
||||
diff --git a/runtime/stream.c b/runtime/stream.c
|
||||
index 6b7e7028e..0f4197103 100644
|
||||
--- a/runtime/stream.c
|
||||
+++ b/runtime/stream.c
|
||||
@@ -942,12 +942,12 @@ strmReadMultiLine_isTimedOut(const strm_t *const __restrict__ pThis)
|
||||
|
||||
/* read a multi-line message from a strm file.
|
||||
* The multi-line message is terminated based on the user-provided
|
||||
- * startRegex (Posix ERE). For performance reasons, the regex
|
||||
+ * startRegex or endRegex (Posix ERE). For performance reasons, the regex
|
||||
* must already have been compiled by the user.
|
||||
* added 2015-05-12 rgerhards
|
||||
*/
|
||||
rsRetVal
|
||||
-strmReadMultiLine(strm_t *pThis, cstr_t **ppCStr, regex_t *preg, const sbool bEscapeLF,
|
||||
+strmReadMultiLine(strm_t *pThis, cstr_t **ppCStr, regex_t *start_preg, regex_t *end_preg, const sbool bEscapeLF,
|
||||
const sbool discardTruncatedMsg, const sbool msgDiscardingError, int64 *const strtOffs)
|
||||
{
|
||||
uchar c;
|
||||
@@ -979,9 +979,14 @@ strmReadMultiLine(strm_t *pThis, cstr_t **ppCStr, regex_t *preg, const sbool bEs
|
||||
cstrFinalize(thisLine);
|
||||
|
||||
/* we have a line, now let's assemble the message */
|
||||
- const int isMatch = !regexec(preg, (char*)rsCStrGetSzStrNoNULL(thisLine), 0, NULL, 0);
|
||||
-
|
||||
- if(isMatch) {
|
||||
+ const int isStartMatch = start_preg ?
|
||||
+ !regexec(start_preg, (char*)rsCStrGetSzStrNoNULL(thisLine), 0, NULL, 0) :
|
||||
+ 0;
|
||||
+ const int isEndMatch = end_preg ?
|
||||
+ !regexec(end_preg, (char*)rsCStrGetSzStrNoNULL(thisLine), 0, NULL, 0) :
|
||||
+ 0;
|
||||
+
|
||||
+ if(isStartMatch) {
|
||||
/* in this case, the *previous* message is complete and we are
|
||||
* at the start of a new one.
|
||||
*/
|
||||
@@ -1047,6 +1052,19 @@ strmReadMultiLine(strm_t *pThis, cstr_t **ppCStr, regex_t *preg, const sbool bEs
|
||||
}
|
||||
}
|
||||
}
|
||||
+ if(isEndMatch) {
|
||||
+ /* in this case, the *current* message is complete and we are
|
||||
+ * at the end of it.
|
||||
+ */
|
||||
+ if(pThis->ignoringMsg == 0) {
|
||||
+ if(pThis->prevMsgSegment != NULL) {
|
||||
+ finished = 1;
|
||||
+ *ppCStr = pThis->prevMsgSegment;
|
||||
+ pThis->prevMsgSegment= NULL;
|
||||
+ }
|
||||
+ }
|
||||
+ pThis->ignoringMsg = 0;
|
||||
+ }
|
||||
cstrDestruct(&thisLine);
|
||||
} while(finished == 0);
|
||||
|
||||
diff --git a/runtime/stream.h b/runtime/stream.h
|
||||
index 71596879e..7dc597ff5 100644
|
||||
--- a/runtime/stream.h
|
||||
+++ b/runtime/stream.h
|
||||
@@ -225,7 +225,7 @@ ENDinterface(strm)
|
||||
/* prototypes */
|
||||
PROTOTYPEObjClassInit(strm);
|
||||
rsRetVal strmMultiFileSeek(strm_t *pThis, unsigned int fileNum, off64_t offs, off64_t *bytesDel);
|
||||
-rsRetVal strmReadMultiLine(strm_t *pThis, cstr_t **ppCStr, regex_t *preg,
|
||||
+rsRetVal strmReadMultiLine(strm_t *pThis, cstr_t **ppCStr, regex_t *start_preg, regex_t *end_preg,
|
||||
sbool bEscapeLF, sbool discardTruncatedMsg, sbool msgDiscardingError, int64 *const strtOffs);
|
||||
int strmReadMultiLine_isTimedOut(const strm_t *const __restrict__ pThis);
|
||||
void strmDebugOutBuf(const strm_t *const pThis);
|
@ -0,0 +1,93 @@
|
||||
diff -up ./plugins/imjournal/imjournal.c.default-tag ./plugins/imjournal/imjournal.c
|
||||
--- ./plugins/imjournal/imjournal.c.default-tag 2018-05-17 08:50:11.416418022 -0400
|
||||
+++ ./plugins/imjournal/imjournal.c 2018-05-17 08:53:02.884418022 -0400
|
||||
@@ -78,6 +78,7 @@ static struct configSettings_s {
|
||||
int bUseJnlPID;
|
||||
char *usePid;
|
||||
int bWorkAroundJournalBug;
|
||||
+ char *dfltTag;
|
||||
} cs;
|
||||
|
||||
static rsRetVal facilityHdlr(uchar **pp, void *pVal);
|
||||
@@ -93,7 +94,8 @@ static struct cnfparamdescr modpdescr[]
|
||||
{ "defaultfacility", eCmdHdlrString, 0 },
|
||||
{ "usepidfromsystem", eCmdHdlrBinary, 0 },
|
||||
{ "usepid", eCmdHdlrString, 0 },
|
||||
- { "workaroundjournalbug", eCmdHdlrBinary, 0 }
|
||||
+ { "workaroundjournalbug", eCmdHdlrBinary, 0 },
|
||||
+ { "defaulttag", eCmdHdlrGetWord, 0 }
|
||||
};
|
||||
static struct cnfparamblk modpblk =
|
||||
{ CNFPARAMBLK_VERSION,
|
||||
@@ -104,6 +106,7 @@ static struct cnfparamblk modpblk =
|
||||
#define DFLT_persiststateinterval 10
|
||||
#define DFLT_SEVERITY pri2sev(LOG_NOTICE)
|
||||
#define DFLT_FACILITY pri2fac(LOG_USER)
|
||||
+#define DFLT_TAG "journal"
|
||||
|
||||
static int bLegacyCnfModGlobalsPermitted = 1;/* are legacy module-global config parameters permitted? */
|
||||
|
||||
@@ -268,7 +271,7 @@ readjournal(void)
|
||||
|
||||
/* Information from messages */
|
||||
char *message = NULL;
|
||||
- char *sys_iden;
|
||||
+ char *sys_iden = NULL;
|
||||
char *sys_iden_help = NULL;
|
||||
char *c = NULL;
|
||||
|
||||
@@ -331,7 +334,7 @@ readjournal(void)
|
||||
if (sd_journal_get_data(j, "SYSLOG_IDENTIFIER", &get, &length) >= 0) {
|
||||
CHKiRet(sanitizeValue(((const char *)get) + 18, length - 18, &sys_iden));
|
||||
} else {
|
||||
- CHKmalloc(sys_iden = strdup("journal"));
|
||||
+ CHKmalloc(sys_iden = strdup(cs.dfltTag));
|
||||
}
|
||||
|
||||
/* trying to get PID, default is "SYSLOG_PID" property */
|
||||
@@ -654,6 +657,11 @@ CODESTARTrunInput
|
||||
"\"usepidfromsystem\" is depricated, use \"usepid\" instead");
|
||||
}
|
||||
|
||||
+ if (cs.dfltTag == NULL) {
|
||||
+ cs.dfltTag = strdup(DFLT_TAG);
|
||||
+ }
|
||||
+
|
||||
+
|
||||
if (cs.usePid && (strcmp(cs.usePid, "system") == 0)) {
|
||||
pidFieldName = "_PID";
|
||||
bPidFallBack = 0;
|
||||
@@ -732,6 +740,7 @@ CODESTARTbeginCnfLoad
|
||||
cs.bUseJnlPID = -1;
|
||||
cs.usePid = NULL;
|
||||
cs.bWorkAroundJournalBug = 0;
|
||||
+ cs.dfltTag = NULL;
|
||||
ENDbeginCnfLoad
|
||||
|
||||
|
||||
@@ -754,6 +763,7 @@ BEGINfreeCnf
|
||||
CODESTARTfreeCnf
|
||||
free(cs.stateFile);
|
||||
free(cs.usePid);
|
||||
+ free(cs.dfltTag);
|
||||
statsobj.Destruct(&(statsCounter.stats));
|
||||
ENDfreeCnf
|
||||
|
||||
@@ -832,6 +842,8 @@ CODESTARTsetModCnf
|
||||
cs.usePid = (char *)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
} else if (!strcmp(modpblk.descr[i].name, "workaroundjournalbug")) {
|
||||
cs.bWorkAroundJournalBug = (int) pvals[i].val.d.n;
|
||||
+ } else if (!strcmp(modpblk.descr[i].name, "defaulttag")) {
|
||||
+ cs.dfltTag = (char *)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
} else {
|
||||
dbgprintf("imjournal: program error, non-handled "
|
||||
"param '%s' in beginCnfLoad\n", modpblk.descr[i].name);
|
||||
@@ -799,6 +820,8 @@ CODEmodInit_QueryRegCFSLineHdlr
|
||||
facilityHdlr, &cs.iDfltFacility, STD_LOADABLE_MODULE_ID));
|
||||
CHKiRet(omsdRegCFSLineHdlr((uchar *)"imjournalusepidfromsystem", 0, eCmdHdlrBinary,
|
||||
NULL, &cs.bUseJnlPID, STD_LOADABLE_MODULE_ID));
|
||||
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"imjournaldefaulttag", 0, eCmdHdlrGetWord,
|
||||
+ NULL, &cs.dfltTag, STD_LOADABLE_MODULE_ID));
|
||||
ENDmodInit
|
||||
/* vim:set ai:
|
||||
*/
|
368
SOURCES/rsyslog-8.37.0-rhbz1674471-imfile-log-rotation.patch
Normal file
368
SOURCES/rsyslog-8.37.0-rhbz1674471-imfile-log-rotation.patch
Normal file
@ -0,0 +1,368 @@
|
||||
From f85ef7aabcec84497a5eaf9670616b3402c79d9c Mon Sep 17 00:00:00 2001
|
||||
From: Rainer Gerhards <rgerhards@adiscon.com>
|
||||
Date: Sun, 23 Sep 2018 13:19:31 +0200
|
||||
Subject: File rotation with imfile broken
|
||||
|
||||
Previously, truncation was only detected at end of file. Especially with
|
||||
busy files that could cause loss of data and possibly also stall imfile
|
||||
reading. The new code now also checks during each read. Obviously, there
|
||||
is some additional overhead associated with that, but this is unavoidable.
|
||||
|
||||
It still is highly recommended NOT to turn on "reopenOnTruncate" in imfile.
|
||||
Note that there are also inherant reliability issues. There is no way to
|
||||
"fix" these, as they are caused by races between the process(es) who truncate
|
||||
and rsyslog reading the file. But with the new code, the "problem window"
|
||||
should be much smaller and, more importantly, imfile should not stall.
|
||||
|
||||
A change in the inode was not detected under all circumstances,
|
||||
most importantly not in some logrotate cases.
|
||||
|
||||
Includes new tests made by Andre Lorbach. They now use the
|
||||
logrotate tool natively to reproduce the issue.
|
||||
---
|
||||
runtime/rsyslog.h | 6 ++--
|
||||
plugins/imfile/imfile.c | 17 +++-
|
||||
runtime/stream.c | 122 ++++++++----
|
||||
runtime/stream.h | 7 ++
|
||||
4 files changed, 126 insertions(+), 36 deletions(-)
|
||||
|
||||
diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h
|
||||
index 61d0af623..22a1c46d1 100644
|
||||
--- a/runtime/rsyslog.h
|
||||
+++ b/runtime/rsyslog.h
|
||||
@@ -221,9 +221,9 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
|
||||
/* begin regular error codes */
|
||||
RS_RET_NOT_IMPLEMENTED = -7, /**< implementation is missing (probably internal error or lazyness ;)) */
|
||||
RS_RET_OUT_OF_MEMORY = -6, /**< memory allocation failed */
|
||||
- RS_RET_PROVIDED_BUFFER_TOO_SMALL = -50,
|
||||
-/*< the caller provided a buffer, but the called function sees the size of this buffer is too small -
|
||||
-operation not carried out */
|
||||
+ RS_RET_PROVIDED_BUFFER_TOO_SMALL = -50, /*< the caller provided a buffer, but the called function sees
|
||||
+ the size of this buffer is too small - operation not carried out */
|
||||
+ RS_RET_FILE_TRUNCATED = -51, /**< (input) file was truncated, not an error but a status */
|
||||
RS_RET_TRUE = -3, /**< to indicate a true state (can be used as TRUE, legacy) */
|
||||
RS_RET_FALSE = -2, /**< to indicate a false state (can be used as FALSE, legacy) */
|
||||
RS_RET_NO_IRET = -8, /**< This is a trick for the debuging system - it means no iRet is provided */
|
||||
diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c
|
||||
index f4a4ef9b7..6be8b2999 100644
|
||||
--- a/plugins/imfile/imfile.c
|
||||
+++ b/plugins/imfile/imfile.c
|
||||
@@ -740,8 +740,19 @@ detect_updates(fs_edge_t *const edge)
|
||||
act_obj_unlink(act);
|
||||
restart = 1;
|
||||
break;
|
||||
+ } else if(fileInfo.st_ino != act->ino) {
|
||||
+ DBGPRINTF("file '%s' inode changed from %llu to %llu, unlinking from "
|
||||
+ "internal lists\n", act->name, (long long unsigned) act->ino,
|
||||
+ (long long unsigned) fileInfo.st_ino);
|
||||
+ if(act->pStrm != NULL) {
|
||||
+ /* we do no need to re-set later, as act_obj_unlink
|
||||
+ * will destroy the strm obj */
|
||||
+ strmSet_checkRotation(act->pStrm, STRM_ROTATION_DO_NOT_CHECK);
|
||||
+ }
|
||||
+ act_obj_unlink(act);
|
||||
+ restart = 1;
|
||||
+ break;
|
||||
}
|
||||
- // TODO: add inode check for change notification!
|
||||
|
||||
}
|
||||
|
||||
@@ -993,10 +1004,10 @@ chk_active(const act_obj_t *act, const act_obj_t *const deleted)
|
||||
/* unlink act object from linked list and then
|
||||
* destruct it.
|
||||
*/
|
||||
-static void //ATTR_NONNULL()
|
||||
+static void ATTR_NONNULL()
|
||||
act_obj_unlink(act_obj_t *act)
|
||||
{
|
||||
- DBGPRINTF("act_obj_unlink %p: %s\n", act, act->name);
|
||||
+ DBGPRINTF("act_obj_unlink %p: %s, pStrm %p\n", act, act->name, act->pStrm);
|
||||
if(act->prev == NULL) {
|
||||
act->edge->active = act->next;
|
||||
} else {
|
||||
diff --git a/runtime/stream.c b/runtime/stream.c
|
||||
index 0f4197103..32a12b256 100644
|
||||
--- a/runtime/stream.c
|
||||
+++ b/runtime/stream.c
|
||||
@@ -400,6 +400,7 @@ static rsRetVal strmOpenFile(strm_t *pThis)
|
||||
CHKiRet(doPhysOpen(pThis));
|
||||
|
||||
pThis->iCurrOffs = 0;
|
||||
+ pThis->iBufPtrMax = 0;
|
||||
CHKiRet(getFileSize(pThis->pszCurrFName, &offset));
|
||||
if(pThis->tOperationsMode == STREAMMODE_WRITE_APPEND) {
|
||||
pThis->iCurrOffs = offset;
|
||||
@@ -636,6 +637,78 @@ strmHandleEOF(strm_t *pThis)
|
||||
RETiRet;
|
||||
}
|
||||
|
||||
+
|
||||
+/* helper to checkTruncation */
|
||||
+static rsRetVal ATTR_NONNULL()
|
||||
+rereadTruncated(strm_t *const pThis, const char *const reason)
|
||||
+{
|
||||
+ DEFiRet;
|
||||
+
|
||||
+ LogMsg(errno, RS_RET_FILE_TRUNCATED, LOG_WARNING, "file '%s': truncation detected, "
|
||||
+ "(%s) - re-start reading from beginning",
|
||||
+ pThis->pszCurrFName, reason);
|
||||
+ DBGPRINTF("checkTruncation, file %s last buffer CHANGED\n", pThis->pszCurrFName);
|
||||
+ CHKiRet(strmCloseFile(pThis));
|
||||
+ CHKiRet(strmOpenFile(pThis));
|
||||
+ iRet = RS_RET_FILE_TRUNCATED;
|
||||
+
|
||||
+finalize_it:
|
||||
+ RETiRet;
|
||||
+}
|
||||
+/* helper to read:
|
||||
+ * Check if file has been truncated since last read and, if so, re-set reading
|
||||
+ * to begin of file. To detect truncation, we try to re-read the last block.
|
||||
+ * If that does not succeed or different data than from the original read is
|
||||
+ * returned, truncation is assumed.
|
||||
+ * NOTE: this function must be called only if truncation is enabled AND
|
||||
+ * when the previous read buffer still is valid (aka "before the next read").
|
||||
+ * It is ok to call with a 0-size buffer, which we than assume as begin of
|
||||
+ * reading. In that case, no truncation will be detected.
|
||||
+ * rgerhards, 2018-09-20
|
||||
+ */
|
||||
+static rsRetVal ATTR_NONNULL()
|
||||
+checkTruncation(strm_t *const pThis)
|
||||
+{
|
||||
+ DEFiRet;
|
||||
+ int ret;
|
||||
+ off64_t backseek;
|
||||
+ assert(pThis->bReopenOnTruncate);
|
||||
+
|
||||
+ DBGPRINTF("checkTruncation, file %s, iBufPtrMax %zd\n", pThis->pszCurrFName, pThis->iBufPtrMax);
|
||||
+ if(pThis->iBufPtrMax == 0) {
|
||||
+ FINALIZE;
|
||||
+ }
|
||||
+
|
||||
+ int currpos = lseek64(pThis->fd, 0, SEEK_CUR);
|
||||
+ backseek = -1 * (off64_t) pThis->iBufPtrMax;
|
||||
+ dbgprintf("checkTruncation in actual processing, currpos %d, backseek is %d\n", (int)currpos, (int) backseek);
|
||||
+ ret = lseek64(pThis->fd, backseek, SEEK_CUR);
|
||||
+ if(ret < 0) {
|
||||
+ iRet = rereadTruncated(pThis, "cannot seek backward to begin of last block");
|
||||
+ FINALIZE;
|
||||
+ }
|
||||
+dbgprintf("checkTruncation seek backwrds: %d\n", ret);
|
||||
+currpos = lseek64(pThis->fd, 0, SEEK_CUR);
|
||||
+dbgprintf("checkTruncation in actual processing, NEW currpos %d, backseek is %d\n", (int)currpos, (int) backseek);
|
||||
+
|
||||
+ const ssize_t lenRead = read(pThis->fd, pThis->pIOBuf_truncation, pThis->iBufPtrMax);
|
||||
+ dbgprintf("checkTruncation proof-read: %d bytes\n", (int) lenRead);
|
||||
+ if(lenRead < 0) {
|
||||
+ iRet = rereadTruncated(pThis, "last block could not be re-read");
|
||||
+ FINALIZE;
|
||||
+ }
|
||||
+
|
||||
+ if(!memcmp(pThis->pIOBuf_truncation, pThis->pIOBuf, pThis->iBufPtrMax)) {
|
||||
+ DBGPRINTF("checkTruncation, file %s last buffer unchanged\n", pThis->pszCurrFName);
|
||||
+ } else {
|
||||
+ iRet = rereadTruncated(pThis, "last block data different");
|
||||
+ }
|
||||
+
|
||||
+finalize_it:
|
||||
+ RETiRet;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* read the next buffer from disk
|
||||
* rgerhards, 2008-02-13
|
||||
*/
|
||||
@@ -668,6 +741,13 @@ strmReadBuf(strm_t *pThis, int *padBytes)
|
||||
toRead = (size_t) bytesLeft;
|
||||
}
|
||||
}
|
||||
+ if(pThis->bReopenOnTruncate) {
|
||||
+ rsRetVal localRet = checkTruncation(pThis);
|
||||
+ if(localRet == RS_RET_FILE_TRUNCATED) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ CHKiRet(localRet);
|
||||
+ }
|
||||
iLenRead = read(pThis->fd, pThis->pIOBuf, toRead);
|
||||
DBGOPRINT((obj_t*) pThis, "file %d read %ld bytes\n", pThis->fd, iLenRead);
|
||||
/* end crypto */
|
||||
@@ -1184,6 +1264,7 @@ static rsRetVal strmConstructFinalize(strm_t *pThis)
|
||||
} else {
|
||||
/* we work synchronously, so we need to alloc a fixed pIOBuf */
|
||||
CHKmalloc(pThis->pIOBuf = (uchar*) MALLOC(pThis->sIOBufSize));
|
||||
+ CHKmalloc(pThis->pIOBuf_truncation = (char*) MALLOC(pThis->sIOBufSize));
|
||||
}
|
||||
|
||||
finalize_it:
|
||||
@@ -1231,6 +1312,7 @@ CODESTARTobjDestruct(strm)
|
||||
}
|
||||
} else {
|
||||
free(pThis->pIOBuf);
|
||||
+ free(pThis->pIOBuf_truncation);
|
||||
}
|
||||
|
||||
/* Finally, we can free the resources.
|
||||
diff --git a/runtime/stream.c b/runtime/stream.c
|
||||
index 2d494c612..5b52591ef 100644
|
||||
--- a/runtime/stream.c
|
||||
+++ b/runtime/stream.c
|
||||
@@ -360,8 +360,8 @@ CheckFileChange(strm_t *pThis)
|
||||
CHKiRet(strmSetCurrFName(pThis));
|
||||
if(stat((char*) pThis->pszCurrFName, &statName) == -1)
|
||||
ABORT_FINALIZE(RS_RET_IO_ERROR);
|
||||
- DBGPRINTF("stream/after deserialize checking for file change on '%s', "
|
||||
- "inode %u/%u, size/currOffs %llu/%llu\n",
|
||||
+ DBGPRINTF("CheckFileChange: stream/after deserialize checking for file change "
|
||||
+ "on '%s', inode %u/%u, size/currOffs %llu/%llu\n",
|
||||
pThis->pszCurrFName, (unsigned) pThis->inode,
|
||||
(unsigned) statName.st_ino,
|
||||
(long long unsigned) statName.st_size,
|
||||
@@ -574,8 +574,8 @@ strmNextFile(strm_t *pThis)
|
||||
* circumstances). So starting as of now, we only check the inode number and
|
||||
* a file change is detected only if the inode changes. -- rgerhards, 2011-01-10
|
||||
*/
|
||||
-static rsRetVal
|
||||
-strmHandleEOFMonitor(strm_t *pThis)
|
||||
+static rsRetVal ATTR_NONNULL()
|
||||
+strmHandleEOFMonitor(strm_t *const pThis)
|
||||
{
|
||||
DEFiRet;
|
||||
struct stat statName;
|
||||
@@ -611,8 +611,8 @@ strmHandleEOFMonitor(strm_t *pThis)
|
||||
* try to open the next one.
|
||||
* rgerhards, 2008-02-13
|
||||
*/
|
||||
-static rsRetVal
|
||||
-strmHandleEOF(strm_t *pThis)
|
||||
+static rsRetVal ATTR_NONNULL()
|
||||
+strmHandleEOF(strm_t *const pThis)
|
||||
{
|
||||
DEFiRet;
|
||||
|
||||
@@ -629,7 +629,13 @@ strmHandleEOF(strm_t *pThis)
|
||||
CHKiRet(strmNextFile(pThis));
|
||||
break;
|
||||
case STREAMTYPE_FILE_MONITOR:
|
||||
- CHKiRet(strmHandleEOFMonitor(pThis));
|
||||
+ DBGOPRINT((obj_t*) pThis, "file '%s' (%d) EOF, rotationCheck %d\n",
|
||||
+ pThis->pszCurrFName, pThis->fd, pThis->rotationCheck);
|
||||
+ if(pThis->rotationCheck == STRM_ROTATION_DO_CHECK) {
|
||||
+ CHKiRet(strmHandleEOFMonitor(pThis));
|
||||
+ } else {
|
||||
+ ABORT_FINALIZE(RS_RET_EOF);
|
||||
+ }
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -687,9 +693,6 @@ checkTruncation(strm_t *const pThis)
|
||||
iRet = rereadTruncated(pThis, "cannot seek backward to begin of last block");
|
||||
FINALIZE;
|
||||
}
|
||||
-dbgprintf("checkTruncation seek backwrds: %d\n", ret);
|
||||
-currpos = lseek64(pThis->fd, 0, SEEK_CUR);
|
||||
-dbgprintf("checkTruncation in actual processing, NEW currpos %d, backseek is %d\n", (int)currpos, (int) backseek);
|
||||
|
||||
const ssize_t lenRead = read(pThis->fd, pThis->pIOBuf_truncation, pThis->iBufPtrMax);
|
||||
dbgprintf("checkTruncation proof-read: %d bytes\n", (int) lenRead);
|
||||
@@ -861,7 +864,7 @@ static rsRetVal strmUnreadChar(strm_t *pThis, uchar c)
|
||||
* a line, but following lines that are indented are part of the same log entry
|
||||
*/
|
||||
static rsRetVal
|
||||
-strmReadLine(strm_t *pThis, cstr_t **ppCStr, uint8_t mode, sbool bEscapeLF,
|
||||
+strmReadLine(strm_t *const pThis, cstr_t **ppCStr, uint8_t mode, sbool bEscapeLF,
|
||||
uint32_t trimLineOverBytes, int64 *const strtOffs)
|
||||
{
|
||||
uchar c;
|
||||
@@ -2147,14 +2150,25 @@ DEFpropSetMeth(strm, cryprov, cryprov_if_t*)
|
||||
DEFpropSetMeth(strm, cryprovData, void*)
|
||||
|
||||
/* sets timeout in seconds */
|
||||
-void
|
||||
+void ATTR_NONNULL()
|
||||
strmSetReadTimeout(strm_t *const __restrict__ pThis, const int val)
|
||||
{
|
||||
+ ISOBJ_TYPE_assert(pThis, strm);
|
||||
pThis->readTimeout = val;
|
||||
}
|
||||
|
||||
-static rsRetVal strmSetbDeleteOnClose(strm_t *pThis, int val)
|
||||
+void ATTR_NONNULL()
|
||||
+strmSet_checkRotation(strm_t *const pThis, const int val) {
|
||||
+ ISOBJ_TYPE_assert(pThis, strm);
|
||||
+ assert(val == STRM_ROTATION_DO_CHECK || val == STRM_ROTATION_DO_NOT_CHECK);
|
||||
+ pThis->rotationCheck = val;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static rsRetVal ATTR_NONNULL()
|
||||
+strmSetbDeleteOnClose(strm_t *const pThis, const int val)
|
||||
{
|
||||
+ ISOBJ_TYPE_assert(pThis, strm);
|
||||
pThis->bDeleteOnClose = val;
|
||||
if(pThis->cryprov != NULL) {
|
||||
pThis->cryprov->SetDeleteOnClose(pThis->cryprovFileData, pThis->bDeleteOnClose);
|
||||
@@ -2162,15 +2176,19 @@ static rsRetVal strmSetbDeleteOnClose(strm_t *pThis, int val)
|
||||
return RS_RET_OK;
|
||||
}
|
||||
|
||||
-static rsRetVal strmSetiMaxFiles(strm_t *pThis, int iNewVal)
|
||||
+static rsRetVal ATTR_NONNULL()
|
||||
+strmSetiMaxFiles(strm_t *const pThis, const int iNewVal)
|
||||
{
|
||||
+ ISOBJ_TYPE_assert(pThis, strm);
|
||||
pThis->iMaxFiles = iNewVal;
|
||||
pThis->iFileNumDigits = getNumberDigits(iNewVal);
|
||||
return RS_RET_OK;
|
||||
}
|
||||
|
||||
-static rsRetVal strmSetFileNotFoundError(strm_t *pThis, int pFileNotFoundError)
|
||||
+static rsRetVal ATTR_NONNULL()
|
||||
+strmSetFileNotFoundError(strm_t *const pThis, const int pFileNotFoundError)
|
||||
{
|
||||
+ ISOBJ_TYPE_assert(pThis, strm);
|
||||
pThis->fileNotFoundError = pFileNotFoundError;
|
||||
return RS_RET_OK;
|
||||
}
|
||||
diff --git a/runtime/stream.h b/runtime/stream.h
|
||||
index 7dc597ff5..e3d6c2372 100644
|
||||
--- a/runtime/stream.h
|
||||
+++ b/runtime/stream.h
|
||||
@@ -124,6 +124,7 @@ typedef struct strm_s {
|
||||
ino_t inode; /* current inode for files being monitored (undefined else) */
|
||||
uchar *pszCurrFName; /* name of current file (if open) */
|
||||
uchar *pIOBuf; /* the iobuffer currently in use to gather data */
|
||||
+ char *pIOBuf_truncation; /* iobuffer used during trucation detection block re-reads */
|
||||
size_t iBufPtrMax; /* current max Ptr in Buffer (if partial read!) */
|
||||
size_t iBufPtr; /* pointer into current buffer */
|
||||
int iUngetC; /* char set via UngetChar() call or -1 if none set */
|
||||
|
||||
diff --git a/runtime/stream.h b/runtime/stream.h
|
||||
index e3d6c2372..f6f48378a 100644
|
||||
--- a/runtime/stream.h
|
||||
+++ b/runtime/stream.h
|
||||
@@ -91,6 +91,10 @@ typedef enum { /* when extending, do NOT change existing modes! */
|
||||
STREAMMODE_WRITE_APPEND = 4
|
||||
} strmMode_t;
|
||||
|
||||
+/* settings for stream rotation (applies not to all processing modes!) */
|
||||
+#define STRM_ROTATION_DO_CHECK 0
|
||||
+#define STRM_ROTATION_DO_NOT_CHECK 1
|
||||
+
|
||||
#define STREAM_ASYNC_NUMBUFS 2 /* must be a power of 2 -- TODO: make configurable */
|
||||
/* The strm_t data structure */
|
||||
typedef struct strm_s {
|
||||
@@ -114,6 +118,7 @@ typedef struct strm_s {
|
||||
sbool bDisabled; /* should file no longer be written to? (currently set only if omfile file size limit fails) */
|
||||
sbool bSync; /* sync this file after every write? */
|
||||
sbool bReopenOnTruncate;
|
||||
+ int rotationCheck; /* rotation check mode */
|
||||
size_t sIOBufSize;/* size of IO buffer */
|
||||
uchar *pszDir; /* Directory */
|
||||
int lenDir;
|
||||
@@ -234,5 +239,6 @@ void strmSetReadTimeout(strm_t *const __restrict__ pThis, const int val);
|
||||
const uchar * ATTR_NONNULL() strmGetPrevLineSegment(strm_t *const pThis);
|
||||
const uchar * ATTR_NONNULL() strmGetPrevMsgSegment(strm_t *const pThis);
|
||||
int ATTR_NONNULL() strmGetPrevWasNL(const strm_t *const pThis);
|
||||
+void ATTR_NONNULL() strmSet_checkRotation(strm_t *const pThis, const int val);
|
||||
|
||||
#endif /* #ifndef STREAM_H_INCLUDED */
|
@ -0,0 +1,86 @@
|
||||
From 1255a67fdec2fc44cd49b6ea8c463f4319910812 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Vymazal <jvymazal@redhat.com>
|
||||
Date: Wed, 27 Feb 2019 11:57:49 +0100
|
||||
Subject: [PATCH] Enlarged msg offset types for bigger structured messages
|
||||
|
||||
using a large enough (dozens of kBs) structured message
|
||||
it is possible to overflow the signed short type which leads
|
||||
to rsyslog crash.
|
||||
---
|
||||
runtime/msg.c | 12 ++++++------
|
||||
runtime/msg.h | 8 ++++----
|
||||
2 files changed, 10 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/runtime/msg.c b/runtime/msg.c
|
||||
index b82c38b9ee..96306bbeab 100644
|
||||
--- a/runtime/msg.c
|
||||
+++ b/runtime/msg.c
|
||||
@@ -839,7 +839,7 @@ msgBaseConstruct(smsg_t **ppThis)
|
||||
pM->iFacility = LOG_INVLD;
|
||||
pM->iLenPROGNAME = -1;
|
||||
pM->offAfterPRI = 0;
|
||||
- pM->offMSG = -1;
|
||||
+ pM->offMSG = 0;
|
||||
pM->iProtocolVersion = 0;
|
||||
pM->msgFlags = 0;
|
||||
pM->iLenRawMsg = 0;
|
||||
@@ -2167,7 +2167,7 @@ MsgSetFlowControlType(smsg_t * const pMsg, flowControl_t eFlowCtl)
|
||||
* rgerhards, 2009-06-16
|
||||
*/
|
||||
rsRetVal
|
||||
-MsgSetAfterPRIOffs(smsg_t * const pMsg, short offs)
|
||||
+MsgSetAfterPRIOffs(smsg_t * const pMsg, uint32_t offs)
|
||||
{
|
||||
assert(pMsg != NULL);
|
||||
pMsg->offAfterPRI = offs;
|
||||
@@ -2819,12 +2819,12 @@ void MsgSetHOSTNAME(smsg_t *pThis, const uchar* pszHOSTNAME, const int lenHOSTNA
|
||||
* (exactly by one). This can happen if we have a message that does not
|
||||
* contain any MSG part.
|
||||
*/
|
||||
-void MsgSetMSGoffs(smsg_t * const pMsg, short offs)
|
||||
+void MsgSetMSGoffs(smsg_t * const pMsg, uint32_t offs)
|
||||
{
|
||||
ISOBJ_TYPE_assert(pMsg, msg);
|
||||
pMsg->offMSG = offs;
|
||||
- if(offs > pMsg->iLenRawMsg) {
|
||||
- assert(offs - 1 == pMsg->iLenRawMsg);
|
||||
+ if(offs > (uint32_t)pMsg->iLenRawMsg) {
|
||||
+ assert((int)offs - 1 == pMsg->iLenRawMsg);
|
||||
pMsg->iLenMSG = 0;
|
||||
} else {
|
||||
pMsg->iLenMSG = pMsg->iLenRawMsg - offs;
|
||||
@@ -2920,7 +2920,7 @@ MsgSetRawMsg(smsg_t *const pThis, const char*const pszRawMsg, const size_t lenMs
|
||||
memcpy(pThis->pszRawMsg, pszRawMsg, pThis->iLenRawMsg);
|
||||
pThis->pszRawMsg[pThis->iLenRawMsg] = '\0'; /* this also works with truncation! */
|
||||
/* correct other information */
|
||||
- if(pThis->iLenRawMsg > pThis->offMSG)
|
||||
+ if((uint32_t)pThis->iLenRawMsg > pThis->offMSG)
|
||||
pThis->iLenMSG += deltaSize;
|
||||
else
|
||||
pThis->iLenMSG = 0;
|
||||
diff --git a/runtime/msg.h b/runtime/msg.h
|
||||
index 74439275b1..722cca6e8a 100644
|
||||
--- a/runtime/msg.h
|
||||
+++ b/runtime/msg.h
|
||||
@@ -67,8 +67,8 @@ struct msg {
|
||||
sbool bParseSuccess; /* set to reflect state of last executed higher level parser */
|
||||
unsigned short iSeverity;/* the severity */
|
||||
unsigned short iFacility;/* Facility code */
|
||||
- short offAfterPRI; /* offset, at which raw message WITHOUT PRI part starts in pszRawMsg */
|
||||
- short offMSG; /* offset at which the MSG part starts in pszRawMsg */
|
||||
+ uint32_t offAfterPRI; /* offset, at which raw message WITHOUT PRI part starts in pszRawMsg */
|
||||
+ uint32_t offMSG; /* offset at which the MSG part starts in pszRawMsg */
|
||||
short iProtocolVersion;/* protocol version of message received 0 - legacy, 1 syslog-protocol) */
|
||||
int msgFlags; /* flags associated with this message */
|
||||
int iLenRawMsg; /* length of raw message */
|
||||
@@ -194,8 +194,8 @@ void MsgSetRcvFromStr(smsg_t *const pMsg, const uchar* pszRcvFrom, const int, pr
|
||||
rsRetVal MsgSetRcvFromIP(smsg_t *pMsg, prop_t*);
|
||||
rsRetVal MsgSetRcvFromIPStr(smsg_t *const pThis, const uchar *psz, const int len, prop_t **ppProp);
|
||||
void MsgSetHOSTNAME(smsg_t *pMsg, const uchar* pszHOSTNAME, const int lenHOSTNAME);
|
||||
-rsRetVal MsgSetAfterPRIOffs(smsg_t *pMsg, short offs);
|
||||
-void MsgSetMSGoffs(smsg_t *pMsg, short offs);
|
||||
+rsRetVal MsgSetAfterPRIOffs(smsg_t *pMsg, uint32_t offs);
|
||||
+void MsgSetMSGoffs(smsg_t *pMsg, uint32_t offs);
|
||||
void MsgSetRawMsgWOSize(smsg_t *pMsg, char* pszRawMsg);
|
||||
void ATTR_NONNULL() MsgSetRawMsg(smsg_t *const pThis, const char*const pszRawMsg, const size_t lenMsg);
|
||||
rsRetVal MsgReplaceMSG(smsg_t *pThis, const uchar* pszMSG, int lenMSG);
|
60
SOURCES/rsyslog-8.37.0-rhbz1716867-imjournal-memleak.patch
Normal file
60
SOURCES/rsyslog-8.37.0-rhbz1716867-imjournal-memleak.patch
Normal file
@ -0,0 +1,60 @@
|
||||
From 920c28ff705aac74f389b4613815b14b9482e497 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Vymazal <jvymazal@redhat.com>
|
||||
Date: Mon, 21 Jan 2019 10:58:03 +0100
|
||||
Subject: [PATCH] Added missing free() calls of received journal cursor
|
||||
|
||||
---
|
||||
plugins/imjournal/imjournal.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/plugins/imjournal/imjournal.c b/plugins/imjournal/imjournal.c
|
||||
index a85e521003..f5c2be4b6e 100644
|
||||
--- a/plugins/imjournal/imjournal.c
|
||||
+++ b/plugins/imjournal/imjournal.c
|
||||
@@ -442,8 +437,7 @@ readjournal(void)
|
||||
|
||||
if (cs.bWorkAroundJournalBug) {
|
||||
/* save journal cursor (at this point we can be sure it is valid) */
|
||||
- sd_journal_get_cursor(j, &c);
|
||||
- if (c) {
|
||||
+ if (!sd_journal_get_cursor(j, &c)) {
|
||||
free(last_cursor);
|
||||
last_cursor = c;
|
||||
}
|
||||
@@ -470,6 +471,7 @@ persistJournalState(void)
|
||||
}
|
||||
} else {
|
||||
int ret;
|
||||
+ free(last_cursor);
|
||||
if ((ret = sd_journal_get_cursor(j, &last_cursor))) {
|
||||
LogError(-ret, RS_RET_ERR, "imjournal: sd_journal_get_cursor() failed");
|
||||
ABORT_FINALIZE(RS_RET_ERR);
|
||||
@@ -630,6 +632,7 @@ loadJournalState(void)
|
||||
iRet = RS_RET_ERR;
|
||||
}
|
||||
}
|
||||
+ free(tmp_cursor);
|
||||
}
|
||||
} else {
|
||||
LogError(0, RS_RET_IO_ERROR, "imjournal: "
|
||||
@@ -843,6 +846,7 @@ BEGINfreeCnf
|
||||
free(cs.stateFile);
|
||||
free(cs.usePid);
|
||||
free(cs.dfltTag);
|
||||
+ free(last_cursor);
|
||||
statsobj.Destruct(&(statsCounter.stats));
|
||||
ENDfreeCnf
|
||||
|
||||
diff --git a/plugins/imjournal/imjournal.c b/plugins/imjournal/imjournal.c
|
||||
index f5c2be4b6e..7225fae1ab 100644
|
||||
--- a/plugins/imjournal/imjournal.c
|
||||
+++ b/plugins/imjournal/imjournal.c
|
||||
@@ -474,6 +474,7 @@ persistJournalState(void)
|
||||
free(last_cursor);
|
||||
if ((ret = sd_journal_get_cursor(j, &last_cursor))) {
|
||||
LogError(-ret, RS_RET_ERR, "imjournal: sd_journal_get_cursor() failed");
|
||||
+ last_cursor = NULL;
|
||||
ABORT_FINALIZE(RS_RET_ERR);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,136 @@
|
||||
From 9c22b31cd639911a2faffad02f2ed9f7cc10b9e1 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Vymazal <jvymazal@redhat.com>
|
||||
Date: Fri, 15 Mar 2019 09:29:04 +0100
|
||||
Subject: [PATCH] Fetching journal cursor only for valid journal
|
||||
|
||||
The sd_journal_get_cursor() got called regradless of previous
|
||||
retcodes from other jorunal calls which flooded logs with journald
|
||||
errors. Now skipping the call in case of previous journal call
|
||||
non-zero result. Fixed success checking of get_cursor() call
|
||||
to eliminate double-free possibility.
|
||||
|
||||
Also, making WorkAroundJournalBug true by default, as there were no
|
||||
confirmed performance regressions for a quite long time.
|
||||
---
|
||||
plugins/imjournal/imjournal.c | 43 ++++++++++++++++++++++------------
|
||||
1 file changed, 28 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/plugins/imjournal/imjournal.c b/plugins/imjournal/imjournal.c
|
||||
index 7225fae1ab..5419762cf1 100644
|
||||
--- a/plugins/imjournal/imjournal.c
|
||||
+++ b/plugins/imjournal/imjournal.c
|
||||
@@ -135,7 +135,7 @@ static char *last_cursor = NULL;
|
||||
|
||||
#define J_PROCESS_PERIOD 1024 /* Call sd_journal_process() every 1,024 records */
|
||||
|
||||
-static rsRetVal persistJournalState(void);
|
||||
+static rsRetVal persistJournalState(int trySave);
|
||||
static rsRetVal loadJournalState(void);
|
||||
|
||||
static rsRetVal openJournal(void) {
|
||||
@@ -158,9 +158,9 @@ static rsRetVal openJournal(void) {
|
||||
RETiRet;
|
||||
}
|
||||
|
||||
-static void closeJournal(void) {
|
||||
+static void closeJournal(int trySave) {
|
||||
if (cs.stateFile) { /* can't persist without a state file */
|
||||
- persistJournalState();
|
||||
+ persistJournalState(trySave);
|
||||
}
|
||||
sd_journal_close(j);
|
||||
j_inotify_fd = 0;
|
||||
@@ -461,7 +461,7 @@ readjournal(void)
|
||||
/* This function gets journal cursor and saves it into state file
|
||||
*/
|
||||
static rsRetVal
|
||||
-persistJournalState(void)
|
||||
+persistJournalState(int trySave)
|
||||
{
|
||||
DEFiRet;
|
||||
FILE *sf; /* state file */
|
||||
@@ -469,7 +470,7 @@ persistJournalState(void)
|
||||
if (!last_cursor) {
|
||||
ABORT_FINALIZE(RS_RET_OK);
|
||||
}
|
||||
- } else {
|
||||
+ } else if (trySave) {
|
||||
int ret;
|
||||
free(last_cursor);
|
||||
if ((ret = sd_journal_get_cursor(j, &last_cursor))) {
|
||||
@@ -477,6 +478,8 @@ persistJournalState(void)
|
||||
last_cursor = NULL;
|
||||
ABORT_FINALIZE(RS_RET_ERR);
|
||||
}
|
||||
+ } else { /* not trying to get cursor out of invalid journal state */
|
||||
+ ABORT_FINALIZE(RS_RET_OK);
|
||||
}
|
||||
|
||||
/* we create a temporary name by adding a ".tmp"
|
||||
@@ -535,14 +535,24 @@ pollJournal(void)
|
||||
err = sd_journal_wait(j, POLL_TIMEOUT);
|
||||
if (err == SD_JOURNAL_INVALIDATE) {
|
||||
STATSCOUNTER_INC(statsCounter.ctrRotations, statsCounter.mutCtrRotations);
|
||||
- closeJournal();
|
||||
+ closeJournal(0);
|
||||
|
||||
iRet = openJournal();
|
||||
if (iRet != RS_RET_OK) {
|
||||
ABORT_FINALIZE(RS_RET_ERR);
|
||||
}
|
||||
|
||||
- if (cs.stateFile) {
|
||||
+ /* If we have locally saved cursor there is no need to read it from state file */
|
||||
+ if (cs.bWorkAroundJournalBug && last_cursor)
|
||||
+ {
|
||||
+ if (sd_journal_seek_cursor(j, last_cursor) != 0) {
|
||||
+ LogError(0, RS_RET_ERR, "imjournal: "
|
||||
+ "couldn't seek to cursor `%s'\n", last_cursor);
|
||||
+ iRet = RS_RET_ERR;
|
||||
+ }
|
||||
+ sd_journal_next(j);
|
||||
+ }
|
||||
+ else if (cs.stateFile) {
|
||||
iRet = loadJournalState();
|
||||
}
|
||||
LogMsg(0, RS_RET_OK, LOG_NOTICE, "imjournal: journal reloaded...");
|
||||
@@ -668,10 +680,9 @@ loadJournalState(void)
|
||||
|
||||
static void
|
||||
tryRecover(void) {
|
||||
- LogMsg(0, RS_RET_OK, LOG_INFO, "imjournal: trying to recover from unexpected "
|
||||
- "journal error");
|
||||
+ LogMsg(0, RS_RET_OK, LOG_INFO, "imjournal: trying to recover from journal error");
|
||||
STATSCOUNTER_INC(statsCounter.ctrRecoveryAttempts, statsCounter.mutCtrRecoveryAttempts);
|
||||
- closeJournal();
|
||||
+ closeJournal(0);
|
||||
srSleep(10, 0); // do not hammer machine with too-frequent retries
|
||||
openJournal();
|
||||
}
|
||||
@@ -768,7 +779,7 @@ CODESTARTrunInput
|
||||
if (cs.stateFile) { /* can't persist without a state file */
|
||||
/* TODO: This could use some finer metric. */
|
||||
if ((count % cs.iPersistStateInterval) == 0) {
|
||||
- persistJournalState();
|
||||
+ persistJournalState(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -790,7 +801,7 @@ CODESTARTbeginCnfLoad
|
||||
cs.iDfltFacility = DFLT_FACILITY;
|
||||
cs.bUseJnlPID = -1;
|
||||
cs.usePid = NULL;
|
||||
- cs.bWorkAroundJournalBug = 0;
|
||||
+ cs.bWorkAroundJournalBug = 1;
|
||||
cs.dfltTag = NULL;
|
||||
ENDbeginCnfLoad
|
||||
|
||||
@@ -860,7 +871,7 @@ ENDwillRun
|
||||
/* close journal */
|
||||
BEGINafterRun
|
||||
CODESTARTafterRun
|
||||
- closeJournal();
|
||||
+ closeJournal(1);
|
||||
ratelimitDestruct(ratelimiter);
|
||||
ENDafterRun
|
||||
|
28
SOURCES/rsyslog-8.37.0-rhbz1724218-imrelp-old-syntax.patch
Normal file
28
SOURCES/rsyslog-8.37.0-rhbz1724218-imrelp-old-syntax.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From f53977817f352ef1c67178687cbfcee849f667fc Mon Sep 17 00:00:00 2001
|
||||
From: Andre Lorbach <alorbach@adiscon.com>
|
||||
Date: Tue, 9 Oct 2018 14:31:52 +0200
|
||||
Subject: [PATCH] imrelp: Fixed issue with oldstyle configuration caused by
|
||||
commit:
|
||||
|
||||
https://github.com/rsyslog/rsyslog/commit/32b71daa8aadb8f16fe0ca2945e54d593f47a824
|
||||
|
||||
Fixed by setting bEnableLstn in addInstance().
|
||||
|
||||
Closes https://github.com/rsyslog/rsyslog/issues/3106
|
||||
---
|
||||
plugins/imrelp/imrelp.c | 2 ++
|
||||
1 files changed, 2 insertions(+)
|
||||
|
||||
diff --git a/plugins/imrelp/imrelp.c b/plugins/imrelp/imrelp.c
|
||||
index c2134e5165..076dd64900 100644
|
||||
--- a/plugins/imrelp/imrelp.c
|
||||
+++ b/plugins/imrelp/imrelp.c
|
||||
@@ -346,6 +346,8 @@ static rsRetVal addInstance(void __attribute__((unused)) *pVal, uchar *pNewVal)
|
||||
CHKmalloc(inst->pszBindRuleset = ustrdup(cs.pszBindRuleset));
|
||||
}
|
||||
inst->pBindRuleset = NULL;
|
||||
+
|
||||
+ inst->bEnableLstn = -1; /* all ok, ready to start up */
|
||||
finalize_it:
|
||||
free(pNewVal);
|
||||
RETiRet;
|
618
SOURCES/rsyslog-8.37.0-rhbz1733244-TLS-CC-compatibility.patch
Normal file
618
SOURCES/rsyslog-8.37.0-rhbz1733244-TLS-CC-compatibility.patch
Normal file
@ -0,0 +1,618 @@
|
||||
From b15e6ab7242b25311a9e0dcf14187d21a80a44a6 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Vymazal <jvymazal@redhat.com>
|
||||
Date: Fri, 16 Aug 2019 15:01:11 +0200
|
||||
Subject: [PATCH] Stricter GnuTLS operation
|
||||
|
||||
This commit adds to new flags which can be set to allow
|
||||
1) checking of extendedKeyUsage certificate field
|
||||
2) stricter checking of certificate name/adresses
|
||||
---
|
||||
plugins/imtcp/imtcp.c | 12 +++++++
|
||||
runtime/netstrm.c | 22 +++++++++++++
|
||||
runtime/netstrm.h | 5 ++-
|
||||
runtime/netstrms.c | 47 +++++++++++++++++++++++++++
|
||||
runtime/netstrms.h | 6 ++++
|
||||
runtime/nsd.h | 7 ++--
|
||||
runtime/nsd_gtls.c | 74 ++++++++++++++++++++++++++++++++++++++++---
|
||||
runtime/nsd_gtls.h | 12 +++++++
|
||||
runtime/nsd_ossl.c | 36 +++++++++++++++++++++
|
||||
runtime/nsd_ptcp.c | 35 ++++++++++++++++++++
|
||||
runtime/tcpsrv.c | 24 ++++++++++++++
|
||||
runtime/tcpsrv.h | 7 +++-
|
||||
tools/omfwd.c | 12 +++++++
|
||||
13 files changed, 291 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c
|
||||
index 55245842d5..6b3401f8fe 100644
|
||||
--- a/plugins/imtcp/imtcp.c
|
||||
+++ b/plugins/imtcp/imtcp.c
|
||||
@@ -131,6 +131,8 @@ struct modConfData_s {
|
||||
int iTCPSessMax; /* max number of sessions */
|
||||
int iTCPLstnMax; /* max number of sessions */
|
||||
int iStrmDrvrMode; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */
|
||||
+ int iStrmDrvrExtendedCertCheck; /* verify also purpose OID in certificate extended field */
|
||||
+ int iStrmDrvrSANPreference; /* ignore CN when any SAN set */
|
||||
int iAddtlFrameDelim; /* addtl frame delimiter, e.g. for netscreen, default none */
|
||||
int maxFrameSize;
|
||||
int bSuppOctetFram;
|
||||
@@ -170,6 +172,8 @@ static struct cnfparamdescr modpdescr[] = {
|
||||
{ "streamdriver.mode", eCmdHdlrNonNegInt, 0 },
|
||||
{ "streamdriver.authmode", eCmdHdlrString, 0 },
|
||||
{ "streamdriver.name", eCmdHdlrString, 0 },
|
||||
+ { "streamdriver.CheckExtendedKeyPurpose", eCmdHdlrBinary, 0 },
|
||||
+ { "streamdriver.PrioritizeSAN", eCmdHdlrBinary, 0 },
|
||||
{ "permittedpeer", eCmdHdlrArray, 0 },
|
||||
{ "keepalive", eCmdHdlrBinary, 0 },
|
||||
{ "keepalive.probes", eCmdHdlrPositiveInt, 0 },
|
||||
@@ -368,6 +372,8 @@ addListner(modConfData_t *modConf, instanceConf_t *inst)
|
||||
CHKiRet(tcpsrv.SetSessMax(pOurTcpsrv, modConf->iTCPSessMax));
|
||||
CHKiRet(tcpsrv.SetLstnMax(pOurTcpsrv, modConf->iTCPLstnMax));
|
||||
CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, modConf->iStrmDrvrMode));
|
||||
+ CHKiRet(tcpsrv.SetDrvrCheckExtendedKeyUsage(pOurTcpsrv, modConf->iStrmDrvrExtendedCertCheck));
|
||||
+ CHKiRet(tcpsrv.SetDrvrPrioritizeSAN(pOurTcpsrv, modConf->iStrmDrvrSANPreference));
|
||||
CHKiRet(tcpsrv.SetUseFlowControl(pOurTcpsrv, modConf->bUseFlowControl));
|
||||
CHKiRet(tcpsrv.SetAddtlFrameDelim(pOurTcpsrv, modConf->iAddtlFrameDelim));
|
||||
CHKiRet(tcpsrv.SetMaxFrameSize(pOurTcpsrv, modConf->maxFrameSize));
|
||||
@@ -479,6 +485,8 @@ CODESTARTbeginCnfLoad
|
||||
loadModConf->iTCPLstnMax = 20;
|
||||
loadModConf->bSuppOctetFram = 1;
|
||||
loadModConf->iStrmDrvrMode = 0;
|
||||
+ loadModConf->iStrmDrvrExtendedCertCheck = 0;
|
||||
+ loadModConf->iStrmDrvrSANPreference = 0;
|
||||
loadModConf->bUseFlowControl = 1;
|
||||
loadModConf->bKeepAlive = 0;
|
||||
loadModConf->iKeepAliveIntvl = 0;
|
||||
@@ -560,6 +568,10 @@ CODESTARTsetModCnf
|
||||
loadModConf->gnutlsPriorityString = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
} else if(!strcmp(modpblk.descr[i].name, "streamdriver.mode")) {
|
||||
loadModConf->iStrmDrvrMode = (int) pvals[i].val.d.n;
|
||||
+ } else if(!strcmp(modpblk.descr[i].name, "streamdriver.CheckExtendedKeyPurpose")) {
|
||||
+ loadModConf->iStrmDrvrExtendedCertCheck = (int) pvals[i].val.d.n;
|
||||
+ } else if(!strcmp(modpblk.descr[i].name, "streamdriver.PrioritizeSAN")) {
|
||||
+ loadModConf->iStrmDrvrSANPreference = (int) pvals[i].val.d.n;
|
||||
} else if(!strcmp(modpblk.descr[i].name, "streamdriver.authmode")) {
|
||||
loadModConf->pszStrmDrvrAuthMode = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
} else if(!strcmp(modpblk.descr[i].name, "streamdriver.name")) {
|
||||
diff --git a/runtime/netstrm.c b/runtime/netstrm.c
|
||||
index e1df83edee..59aa135997 100644
|
||||
--- a/runtime/netstrm.c
|
||||
+++ b/runtime/netstrm.c
|
||||
@@ -221,6 +221,26 @@ SetDrvrPermPeers(netstrm_t *pThis, permittedPeers_t *pPermPeers)
|
||||
RETiRet;
|
||||
}
|
||||
|
||||
+/* Mandate also verification of Extended key usage / purpose field */
|
||||
+static rsRetVal
|
||||
+SetDrvrCheckExtendedKeyUsage(netstrm_t *pThis, int ChkExtendedKeyUsage)
|
||||
+{
|
||||
+ DEFiRet;
|
||||
+ ISOBJ_TYPE_assert(pThis, netstrm);
|
||||
+ iRet = pThis->Drvr.SetCheckExtendedKeyUsage(pThis->pDrvrData, ChkExtendedKeyUsage);
|
||||
+ RETiRet;
|
||||
+}
|
||||
+
|
||||
+/* Mandate stricter name checking per RFC 6125 - ignoce CN if any SAN present */
|
||||
+static rsRetVal
|
||||
+SetDrvrPrioritizeSAN(netstrm_t *pThis, int prioritizeSan)
|
||||
+{
|
||||
+ DEFiRet;
|
||||
+ ISOBJ_TYPE_assert(pThis, netstrm);
|
||||
+ iRet = pThis->Drvr.SetPrioritizeSAN(pThis->pDrvrData, prioritizeSan);
|
||||
+ RETiRet;
|
||||
+}
|
||||
+
|
||||
|
||||
/* End of methods to shuffle autentication settings to the driver.
|
||||
* -------------------------------------------------------------------------- */
|
||||
@@ -405,6 +425,8 @@ CODESTARTobjQueryInterface(netstrm)
|
||||
pIf->SetKeepAliveTime = SetKeepAliveTime;
|
||||
pIf->SetKeepAliveIntvl = SetKeepAliveIntvl;
|
||||
pIf->SetGnutlsPriorityString = SetGnutlsPriorityString;
|
||||
+ pIf->SetDrvrCheckExtendedKeyUsage = SetDrvrCheckExtendedKeyUsage;
|
||||
+ pIf->SetDrvrPrioritizeSAN = SetDrvrPrioritizeSAN;
|
||||
finalize_it:
|
||||
ENDobjQueryInterface(netstrm)
|
||||
|
||||
diff --git a/runtime/netstrm.h b/runtime/netstrm.h
|
||||
index 113585d0a5..08b58fd119 100644
|
||||
--- a/runtime/netstrm.h
|
||||
+++ b/runtime/netstrm.h
|
||||
@@ -78,8 +78,11 @@ BEGINinterface(netstrm) /* name must also be changed in ENDinterface macro! */
|
||||
rsRetVal (*SetKeepAliveTime)(netstrm_t *pThis, int keepAliveTime);
|
||||
rsRetVal (*SetKeepAliveIntvl)(netstrm_t *pThis, int keepAliveIntvl);
|
||||
rsRetVal (*SetGnutlsPriorityString)(netstrm_t *pThis, uchar *priorityString);
|
||||
+ /* v12 -- two new binary flags added to gtls driver enabling stricter operation */
|
||||
+ rsRetVal (*SetDrvrCheckExtendedKeyUsage)(netstrm_t *pThis, int ChkExtendedKeyUsage);
|
||||
+ rsRetVal (*SetDrvrPrioritizeSAN)(netstrm_t *pThis, int prioritizeSan);
|
||||
ENDinterface(netstrm)
|
||||
-#define netstrmCURR_IF_VERSION 10 /* increment whenever you change the interface structure! */
|
||||
+#define netstrmCURR_IF_VERSION 12 /* increment whenever you change the interface structure! */
|
||||
/* interface version 3 added GetRemAddr()
|
||||
* interface version 4 added EnableKeepAlive() -- rgerhards, 2009-06-02
|
||||
* interface version 5 changed return of CheckConnection from void to rsRetVal -- alorbach, 2012-09-06
|
||||
diff --git a/runtime/netstrms.c b/runtime/netstrms.c
|
||||
index bd6a06bd7f..a8c342b76b 100644
|
||||
--- a/runtime/netstrms.c
|
||||
+++ b/runtime/netstrms.c
|
||||
@@ -279,6 +279,49 @@ GetDrvrMode(netstrms_t *pThis)
|
||||
}
|
||||
|
||||
|
||||
+/* set the driver cert extended key usage check setting -- jvymazal, 2019-08-16 */
|
||||
+static rsRetVal
|
||||
+SetDrvrCheckExtendedKeyUsage(netstrms_t *pThis, int ChkExtendedKeyUsage)
|
||||
+{
|
||||
+ DEFiRet;
|
||||
+ ISOBJ_TYPE_assert(pThis, netstrms);
|
||||
+ pThis->DrvrChkExtendedKeyUsage = ChkExtendedKeyUsage;
|
||||
+ RETiRet;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* return the driver cert extended key usage check setting
|
||||
+ * jvymazal, 2019-08-16
|
||||
+ */
|
||||
+static int
|
||||
+GetDrvrCheckExtendedKeyUsage(netstrms_t *pThis)
|
||||
+{
|
||||
+ ISOBJ_TYPE_assert(pThis, netstrms);
|
||||
+ return pThis->DrvrChkExtendedKeyUsage;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* set the driver name checking policy -- jvymazal, 2019-08-16 */
|
||||
+static rsRetVal
|
||||
+SetDrvrPrioritizeSAN(netstrms_t *pThis, int prioritizeSan)
|
||||
+{
|
||||
+ DEFiRet;
|
||||
+ ISOBJ_TYPE_assert(pThis, netstrms);
|
||||
+ pThis->DrvrPrioritizeSan = prioritizeSan;
|
||||
+ RETiRet;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* return the driver name checking policy
|
||||
+ * jvymazal, 2019-08-16
|
||||
+ */
|
||||
+static int
|
||||
+GetDrvrPrioritizeSAN(netstrms_t *pThis)
|
||||
+{
|
||||
+ ISOBJ_TYPE_assert(pThis, netstrms);
|
||||
+ return pThis->DrvrPrioritizeSan;
|
||||
+}
|
||||
+
|
||||
/* create an instance of a netstrm object. It is initialized with default
|
||||
* values. The current driver is used. The caller may set netstrm properties
|
||||
* and must call ConstructFinalize().
|
||||
@@ -337,6 +380,10 @@ CODESTARTobjQueryInterface(netstrms)
|
||||
pIf->GetDrvrGnutlsPriorityString = GetDrvrGnutlsPriorityString;
|
||||
pIf->SetDrvrPermPeers = SetDrvrPermPeers;
|
||||
pIf->GetDrvrPermPeers = GetDrvrPermPeers;
|
||||
+ pIf->SetDrvrCheckExtendedKeyUsage = SetDrvrCheckExtendedKeyUsage;
|
||||
+ pIf->GetDrvrCheckExtendedKeyUsage = GetDrvrCheckExtendedKeyUsage;
|
||||
+ pIf->SetDrvrPrioritizeSAN = SetDrvrPrioritizeSAN;
|
||||
+ pIf->GetDrvrPrioritizeSAN = GetDrvrPrioritizeSAN;
|
||||
finalize_it:
|
||||
ENDobjQueryInterface(netstrms)
|
||||
|
||||
diff --git a/runtime/netstrms.h b/runtime/netstrms.h
|
||||
index 440beb20c9..f21bd6a8e2 100644
|
||||
--- a/runtime/netstrms.h
|
||||
+++ b/runtime/netstrms.h
|
||||
@@ -33,6 +33,8 @@ struct netstrms_s {
|
||||
uchar *pDrvrName; /**< full base driver name (set when driver is loaded) */
|
||||
int iDrvrMode; /**< current default driver mode */
|
||||
uchar *pszDrvrAuthMode; /**< current driver authentication mode */
|
||||
+ int DrvrChkExtendedKeyUsage; /**< if true, verify extended key usage in certs */
|
||||
+ int DrvrPrioritizeSan; /**< if true, perform stricter checking of names in certs */
|
||||
uchar *gnutlsPriorityString; /**< priorityString for connection */
|
||||
permittedPeers_t *pPermPeers;/**< current driver's permitted peers */
|
||||
|
||||
@@ -58,6 +60,10 @@ BEGINinterface(netstrms) /* name must also be changed in ENDinterface macro! */
|
||||
permittedPeers_t* (*GetDrvrPermPeers)(netstrms_t *pThis);
|
||||
rsRetVal (*SetDrvrGnutlsPriorityString)(netstrms_t *pThis, uchar*);
|
||||
uchar* (*GetDrvrGnutlsPriorityString)(netstrms_t *pThis);
|
||||
+ rsRetVal (*SetDrvrCheckExtendedKeyUsage)(netstrms_t *pThis, int ChkExtendedKeyUsage);
|
||||
+ int (*GetDrvrCheckExtendedKeyUsage)(netstrms_t *pThis);
|
||||
+ rsRetVal (*SetDrvrPrioritizeSAN)(netstrms_t *pThis, int prioritizeSan);
|
||||
+ int (*GetDrvrPrioritizeSAN)(netstrms_t *pThis);
|
||||
ENDinterface(netstrms)
|
||||
#define netstrmsCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
|
||||
|
||||
diff --git a/runtime/nsd.h b/runtime/nsd.h
|
||||
index eab53ad6ae..f0cb5bd1aa 100644
|
||||
--- a/runtime/nsd.h
|
||||
+++ b/runtime/nsd.h
|
||||
@@ -85,8 +85,11 @@ BEGINinterface(nsd) /* name must also be changed in ENDinterface macro! */
|
||||
rsRetVal (*SetKeepAliveProbes)(nsd_t *pThis, int keepAliveProbes);
|
||||
rsRetVal (*SetKeepAliveTime)(nsd_t *pThis, int keepAliveTime);
|
||||
rsRetVal (*SetGnutlsPriorityString)(nsd_t *pThis, uchar *gnutlsPriorityString);
|
||||
+ /* v13 -- two new binary flags added to gtls driver enabling stricter operation */
|
||||
+ rsRetVal (*SetCheckExtendedKeyUsage)(nsd_t *pThis, int ChkExtendedKeyUsage);
|
||||
+ rsRetVal (*SetPrioritizeSAN)(nsd_t *pThis, int prioritizeSan);
|
||||
ENDinterface(nsd)
|
||||
-#define nsdCURR_IF_VERSION 11 /* increment whenever you change the interface structure! */
|
||||
+#define nsdCURR_IF_VERSION 13 /* increment whenever you change the interface structure! */
|
||||
/* interface version 4 added GetRemAddr()
|
||||
* interface version 5 added EnableKeepAlive() -- rgerhards, 2009-06-02
|
||||
* interface version 6 changed return of CheckConnection from void to rsRetVal -- alorbach, 2012-09-06
|
||||
diff --git a/runtime/nsd_gtls.c b/runtime/nsd_gtls.c
|
||||
index 56238b9cb4..a3662bedf4 100644
|
||||
--- a/runtime/nsd_gtls.c
|
||||
+++ b/runtime/nsd_gtls.c
|
||||
@@ -1004,6 +1004,7 @@ gtlsChkPeerName(nsd_gtls_t *pThis, gnutls_x509_crt_t *pCert)
|
||||
int iAltName;
|
||||
size_t szAltNameLen;
|
||||
int bFoundPositiveMatch;
|
||||
+ int bHaveSAN = 0;
|
||||
cstr_t *pStr = NULL;
|
||||
cstr_t *pstrCN = NULL;
|
||||
int gnuRet;
|
||||
@@ -1023,6 +1024,7 @@ gtlsChkPeerName(nsd_gtls_t *pThis, gnutls_x509_crt_t *pCert)
|
||||
if(gnuRet < 0)
|
||||
break;
|
||||
else if(gnuRet == GNUTLS_SAN_DNSNAME) {
|
||||
+ bHaveSAN = 1;
|
||||
dbgprintf("subject alt dnsName: '%s'\n", szAltName);
|
||||
snprintf((char*)lnBuf, sizeof(lnBuf), "DNSname: %s; ", szAltName);
|
||||
CHKiRet(rsCStrAppendStr(pStr, lnBuf));
|
||||
@@ -1032,8 +1034,8 @@ gtlsChkPeerName(nsd_gtls_t *pThis, gnutls_x509_crt_t *pCert)
|
||||
++iAltName;
|
||||
}
|
||||
|
||||
- if(!bFoundPositiveMatch) {
|
||||
- /* if we did not succeed so far, we try the CN part of the DN... */
|
||||
+ /* Check also CN only if not configured per stricter RFC 6125 or no SAN present*/
|
||||
+ if(!bFoundPositiveMatch && (!pThis->bSANpriority || !bHaveSAN)) {
|
||||
CHKiRet(gtlsGetCN(pCert, &pstrCN));
|
||||
if(pstrCN != NULL) { /* NULL if there was no CN present */
|
||||
dbgprintf("gtls now checking auth for CN '%s'\n", cstrGetSzStrNoNULL(pstrCN));
|
||||
@@ -1044,7 +1044,19 @@ gtlsChkPeerCertValidity(nsd_gtls_t *pThis)
|
||||
ABORT_FINALIZE(RS_RET_TLS_NO_CERT);
|
||||
}
|
||||
|
||||
- CHKgnutls(gnutls_certificate_verify_peers2(pThis->sess, &stateCert));
|
||||
+ if (pThis->dataTypeCheck == GTLS_NONE) {
|
||||
+ CHKgnutls(gnutls_certificate_verify_peers2(pThis->sess, &stateCert));
|
||||
+ } else { /* we have configured data to check in addition to cert */
|
||||
+ gnutls_typed_vdata_st data;
|
||||
+ data.type = GNUTLS_DT_KEY_PURPOSE_OID;
|
||||
+ if (pThis->bIsInitiator) { /* client mode */
|
||||
+ data.data = (uchar *)GNUTLS_KP_TLS_WWW_SERVER;
|
||||
+ } else { /* server mode */
|
||||
+ data.data = (uchar *)GNUTLS_KP_TLS_WWW_CLIENT;
|
||||
+ }
|
||||
+ data.size = ustrlen(data.data);
|
||||
+ CHKgnutls(gnutls_certificate_verify_peers(pThis->sess, &data, 1, &stateCert));
|
||||
+ }
|
||||
|
||||
if(stateCert & GNUTLS_CERT_INVALID) {
|
||||
/* provide error details if we have them */
|
||||
@@ -1188,6 +1205,8 @@ gtlsChkPeerCertValidity(nsd_gtls_t *pThis)
|
||||
pszErrCause = "insecure algorithm";
|
||||
} else if(stateCert & GNUTLS_CERT_REVOKED) {
|
||||
pszErrCause = "certificate revoked";
|
||||
+ } else if(stateCert & GNUTLS_CERT_PURPOSE_MISMATCH) {
|
||||
+ pszErrCause = "key purpose OID does not match";
|
||||
} else {
|
||||
pszErrCause = "GnuTLS returned no specific reason";
|
||||
dbgprintf("GnuTLS returned no specific reason for GNUTLS_CERT_INVALID, certificate "
|
||||
@@ -1499,6 +1516,53 @@ SetGnutlsPriorityString(nsd_t *pNsd, uchar *gnutlsPriorityString)
|
||||
RETiRet;
|
||||
}
|
||||
|
||||
+/* Set the driver cert extended key usage check setting
|
||||
+ * 0 - ignore contents of extended key usage
|
||||
+ * 1 - verify that cert contents is compatible with appropriate OID
|
||||
+ * jvymazal, 2019-08-16
|
||||
+ */
|
||||
+static rsRetVal
|
||||
+SetCheckExtendedKeyUsage(nsd_t *pNsd, int ChkExtendedKeyUsage)
|
||||
+{
|
||||
+ DEFiRet;
|
||||
+ nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
|
||||
+
|
||||
+ ISOBJ_TYPE_assert((pThis), nsd_gtls);
|
||||
+ if(ChkExtendedKeyUsage != 0 && ChkExtendedKeyUsage != 1) {
|
||||
+ LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver ChkExtendedKeyUsage %d "
|
||||
+ "not supported by gtls netstream driver", ChkExtendedKeyUsage);
|
||||
+ ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED);
|
||||
+ }
|
||||
+
|
||||
+ pThis->dataTypeCheck = ChkExtendedKeyUsage;
|
||||
+
|
||||
+finalize_it:
|
||||
+ RETiRet;
|
||||
+}
|
||||
+
|
||||
+/* Set the driver name checking strictness
|
||||
+ * 0 - less strict per RFC 5280, section 4.1.2.6 - either SAN or CN match is good
|
||||
+ * 1 - more strict per RFC 6125 - if any SAN present it must match (CN is ignored)
|
||||
+ * jvymazal, 2019-08-16
|
||||
+ */
|
||||
+static rsRetVal
|
||||
+SetPrioritizeSAN(nsd_t *pNsd, int prioritizeSan)
|
||||
+{
|
||||
+ DEFiRet;
|
||||
+ nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
|
||||
+
|
||||
+ ISOBJ_TYPE_assert((pThis), nsd_gtls);
|
||||
+ if(prioritizeSan != 0 && prioritizeSan != 1) {
|
||||
+ LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver prioritizeSan %d "
|
||||
+ "not supported by gtls netstream driver", prioritizeSan);
|
||||
+ ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED);
|
||||
+ }
|
||||
+
|
||||
+ pThis->bSANpriority = prioritizeSan;
|
||||
+
|
||||
+finalize_it:
|
||||
+ RETiRet;
|
||||
+}
|
||||
|
||||
/* Provide access to the underlying OS socket. This is primarily
|
||||
* useful for other drivers (like nsd_gtls) who utilize ourselfs
|
||||
@@ -2124,6 +2188,8 @@ CODESTARTobjQueryInterface(nsd_gtls)
|
||||
pIf->SetKeepAliveProbes = SetKeepAliveProbes;
|
||||
pIf->SetKeepAliveTime = SetKeepAliveTime;
|
||||
pIf->SetGnutlsPriorityString = SetGnutlsPriorityString;
|
||||
+ pIf->SetCheckExtendedKeyUsage = SetCheckExtendedKeyUsage;
|
||||
+ pIf->SetPrioritizeSAN = SetPrioritizeSAN;
|
||||
finalize_it:
|
||||
ENDobjQueryInterface(nsd_gtls)
|
||||
|
||||
diff --git a/runtime/nsd_gtls.h b/runtime/nsd_gtls.h
|
||||
index 80a86f21d7..d73c0e6a4d 100644
|
||||
--- a/runtime/nsd_gtls.h
|
||||
+++ b/runtime/nsd_gtls.h
|
||||
@@ -54,6 +54,11 @@ struct nsd_gtls_s {
|
||||
GTLS_AUTH_CERTVALID = 2,
|
||||
GTLS_AUTH_CERTANON = 3
|
||||
} authMode;
|
||||
+ enum {
|
||||
+ GTLS_NONE = 0,
|
||||
+ GTLS_PURPOSE = 1
|
||||
+ } dataTypeCheck;
|
||||
+ int bSANpriority; /* if true, we do stricter checking (if any SAN present we do not cehck CN) */
|
||||
gtlsRtryCall_t rtryCall;/**< what must we retry? */
|
||||
int bIsInitiator; /**< 0 if socket is the server end (listener), 1 if it is the initiator */
|
||||
gnutls_session_t sess;
|
||||
diff --git a/runtime/nsd_ossl.c b/runtime/nsd_ossl.c
|
||||
index 0a474fd744..419e0e97ef 100644
|
||||
--- a/runtime/nsd_ossl.c
|
||||
+++ b/runtime/nsd_ossl.c
|
||||
@@ -1864,6 +1864,40 @@ SetGnutlsPriorityString(__attribute__((unused)) nsd_t *pNsd, __attribute__((unus
|
||||
RETiRet;
|
||||
}
|
||||
|
||||
+/* Set the driver cert extended key usage check setting, for now it is empty wrapper.
|
||||
+ * TODO: implement openSSL version
|
||||
+ * jvymazal, 2019-08-16
|
||||
+ */
|
||||
+static rsRetVal
|
||||
+SetCheckExtendedKeyUsage(nsd_t __attribute__((unused)) *pNsd, int ChkExtendedKeyUsage)
|
||||
+{
|
||||
+ DEFiRet;
|
||||
+ if(ChkExtendedKeyUsage != 0) {
|
||||
+ LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver ChkExtendedKeyUsage %d "
|
||||
+ "not supported by ossl netstream driver", ChkExtendedKeyUsage);
|
||||
+ ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED);
|
||||
+ }
|
||||
+finalize_it:
|
||||
+ RETiRet;
|
||||
+}
|
||||
+
|
||||
+/* Set the driver name checking strictness, for now it is empty wrapper.
|
||||
+ * TODO: implement openSSL version
|
||||
+ * jvymazal, 2019-08-16
|
||||
+ */
|
||||
+static rsRetVal
|
||||
+SetPrioritizeSAN(nsd_t __attribute__((unused)) *pNsd, int prioritizeSan)
|
||||
+{
|
||||
+ DEFiRet;
|
||||
+ if(prioritizeSan != 0) {
|
||||
+ LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver prioritizeSan %d "
|
||||
+ "not supported by ossl netstream driver", prioritizeSan);
|
||||
+ ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED);
|
||||
+ }
|
||||
+finalize_it:
|
||||
+ RETiRet;
|
||||
+}
|
||||
+
|
||||
/* queryInterface function */
|
||||
BEGINobjQueryInterface(nsd_ossl)
|
||||
CODESTARTobjQueryInterface(nsd_ossl)
|
||||
@@ -1898,6 +1932,8 @@ CODESTARTobjQueryInterface(nsd_ossl)
|
||||
pIf->SetKeepAliveProbes = SetKeepAliveProbes;
|
||||
pIf->SetKeepAliveTime = SetKeepAliveTime;
|
||||
pIf->SetGnutlsPriorityString = SetGnutlsPriorityString; /* we don't NEED this interface! */
|
||||
+ pIf->SetCheckExtendedKeyUsage = SetCheckExtendedKeyUsage; /* we don't NEED this interface! */
|
||||
+ pIf->SetPrioritizeSAN = SetPrioritizeSAN; /* we don't NEED this interface! */
|
||||
|
||||
finalize_it:
|
||||
ENDobjQueryInterface(nsd_ossl)
|
||||
diff --git a/runtime/nsd_ptcp.c b/runtime/nsd_ptcp.c
|
||||
index 68bed5b9ea..60c40ad444 100644
|
||||
--- a/runtime/nsd_ptcp.c
|
||||
+++ b/runtime/nsd_ptcp.c
|
||||
@@ -150,6 +150,37 @@ SetMode(nsd_t __attribute__((unused)) *pNsd, int mode)
|
||||
RETiRet;
|
||||
}
|
||||
|
||||
+/* Set the driver cert extended key usage check setting, not supported in ptcp.
|
||||
+ * jvymazal, 2019-08-16
|
||||
+ */
|
||||
+static rsRetVal
|
||||
+SetCheckExtendedKeyUsage(nsd_t __attribute__((unused)) *pNsd, int ChkExtendedKeyUsage)
|
||||
+{
|
||||
+ DEFiRet;
|
||||
+ if(ChkExtendedKeyUsage != 0) {
|
||||
+ LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver ChkExtendedKeyUsage %d "
|
||||
+ "not supported by ptcp netstream driver", ChkExtendedKeyUsage);
|
||||
+ ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED);
|
||||
+ }
|
||||
+finalize_it:
|
||||
+ RETiRet;
|
||||
+}
|
||||
+
|
||||
+/* Set the driver name checking strictness, not supported in ptcp.
|
||||
+ * jvymazal, 2019-08-16
|
||||
+ */
|
||||
+static rsRetVal
|
||||
+SetPrioritizeSAN(nsd_t __attribute__((unused)) *pNsd, int prioritizeSan)
|
||||
+{
|
||||
+ DEFiRet;
|
||||
+ if(prioritizeSan != 0) {
|
||||
+ LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver prioritizeSan %d "
|
||||
+ "not supported by ptcp netstream driver", prioritizeSan);
|
||||
+ ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED);
|
||||
+ }
|
||||
+finalize_it:
|
||||
+ RETiRet;
|
||||
+}
|
||||
|
||||
/* Set the authentication mode. For us, the following is supported:
|
||||
* anon - no certificate checks whatsoever (discouraged, but supported)
|
||||
@@ -613,6 +644,8 @@ LstnInit(netstrms_t *pNS, void *pUsr, rsRetVal(*fAddLstn)(void*,netstrm_t*),
|
||||
CHKiRet(pNS->Drvr.Construct(&pNewNsd));
|
||||
CHKiRet(pNS->Drvr.SetSock(pNewNsd, sock));
|
||||
CHKiRet(pNS->Drvr.SetMode(pNewNsd, netstrms.GetDrvrMode(pNS)));
|
||||
+ CHKiRet(pNS->Drvr.SetCheckExtendedKeyUsage(pNewNsd, netstrms.GetDrvrCheckExtendedKeyUsage(pNS)));
|
||||
+ CHKiRet(pNS->Drvr.SetPrioritizeSAN(pNewNsd, netstrms.GetDrvrPrioritizeSAN(pNS)));
|
||||
CHKiRet(pNS->Drvr.SetAuthMode(pNewNsd, netstrms.GetDrvrAuthMode(pNS)));
|
||||
CHKiRet(pNS->Drvr.SetPermPeers(pNewNsd, netstrms.GetDrvrPermPeers(pNS)));
|
||||
CHKiRet(pNS->Drvr.SetGnutlsPriorityString(pNewNsd, netstrms.GetDrvrGnutlsPriorityString(pNS)));
|
||||
@@ -963,6 +996,8 @@ CODESTARTobjQueryInterface(nsd_ptcp)
|
||||
pIf->SetKeepAliveIntvl = SetKeepAliveIntvl;
|
||||
pIf->SetKeepAliveProbes = SetKeepAliveProbes;
|
||||
pIf->SetKeepAliveTime = SetKeepAliveTime;
|
||||
+ pIf->SetCheckExtendedKeyUsage = SetCheckExtendedKeyUsage;
|
||||
+ pIf->SetPrioritizeSAN = SetPrioritizeSAN;
|
||||
finalize_it:
|
||||
ENDobjQueryInterface(nsd_ptcp)
|
||||
|
||||
diff --git a/runtime/tcpsrv.c b/runtime/tcpsrv.c
|
||||
index d7ea2f9f00..43a6687b4a 100644
|
||||
--- a/runtime/tcpsrv.c
|
||||
+++ b/runtime/tcpsrv.c
|
||||
@@ -1013,6 +1013,8 @@ tcpsrvConstructFinalize(tcpsrv_t *pThis)
|
||||
if(pThis->pszDrvrName != NULL)
|
||||
CHKiRet(netstrms.SetDrvrName(pThis->pNS, pThis->pszDrvrName));
|
||||
CHKiRet(netstrms.SetDrvrMode(pThis->pNS, pThis->iDrvrMode));
|
||||
+ CHKiRet(netstrms.SetDrvrCheckExtendedKeyUsage(pThis->pNS, pThis->DrvrChkExtendedKeyUsage));
|
||||
+ CHKiRet(netstrms.SetDrvrPrioritizeSAN(pThis->pNS, pThis->DrvrPrioritizeSan));
|
||||
if(pThis->pszDrvrAuthMode != NULL)
|
||||
CHKiRet(netstrms.SetDrvrAuthMode(pThis->pNS, pThis->pszDrvrAuthMode));
|
||||
if(pThis->pPermPeers != NULL)
|
||||
@@ -1405,6 +1407,26 @@ SetDrvrPermPeers(tcpsrv_t *pThis, permittedPeers_t *pPermPeers)
|
||||
RETiRet;
|
||||
}
|
||||
|
||||
+/* set the driver cert extended key usage check setting -- jvymazal, 2019-08-16 */
|
||||
+static rsRetVal
|
||||
+SetDrvrCheckExtendedKeyUsage(tcpsrv_t *pThis, int ChkExtendedKeyUsage)
|
||||
+{
|
||||
+ DEFiRet;
|
||||
+ ISOBJ_TYPE_assert(pThis, tcpsrv);
|
||||
+ pThis->DrvrChkExtendedKeyUsage = ChkExtendedKeyUsage;
|
||||
+ RETiRet;
|
||||
+}
|
||||
+
|
||||
+/* set the driver name checking policy -- jvymazal, 2019-08-16 */
|
||||
+static rsRetVal
|
||||
+SetDrvrPrioritizeSAN(tcpsrv_t *pThis, int prioritizeSan)
|
||||
+{
|
||||
+ DEFiRet;
|
||||
+ ISOBJ_TYPE_assert(pThis, tcpsrv);
|
||||
+ pThis->DrvrPrioritizeSan = prioritizeSan;
|
||||
+ RETiRet;
|
||||
+}
|
||||
+
|
||||
|
||||
/* End of methods to shuffle autentication settings to the driver.;
|
||||
|
||||
@@ -1522,6 +1544,8 @@ CODESTARTobjQueryInterface(tcpsrv)
|
||||
pIf->SetLinuxLikeRatelimiters = SetLinuxLikeRatelimiters;
|
||||
pIf->SetNotificationOnRemoteClose = SetNotificationOnRemoteClose;
|
||||
pIf->SetPreserveCase = SetPreserveCase;
|
||||
+ pIf->SetDrvrCheckExtendedKeyUsage = SetDrvrCheckExtendedKeyUsage;
|
||||
+ pIf->SetDrvrPrioritizeSAN = SetDrvrPrioritizeSAN;
|
||||
|
||||
finalize_it:
|
||||
ENDobjQueryInterface(tcpsrv)
|
||||
diff --git a/runtime/tcpsrv.h b/runtime/tcpsrv.h
|
||||
index 55aa8e9922..79b659013d 100644
|
||||
--- a/runtime/tcpsrv.h
|
||||
+++ b/runtime/tcpsrv.h
|
||||
@@ -61,6 +61,8 @@ struct tcpsrv_s {
|
||||
int iKeepAliveTime; /**< socket layer KEEPALIVE timeout */
|
||||
netstrms_t *pNS; /**< pointer to network stream subsystem */
|
||||
int iDrvrMode; /**< mode of the stream driver to use */
|
||||
+ int DrvrChkExtendedKeyUsage; /**< if true, verify extended key usage in certs */
|
||||
+ int DrvrPrioritizeSan; /**< if true, perform stricter checking of names in certs */
|
||||
uchar *gnutlsPriorityString; /**< priority string for gnutls */
|
||||
uchar *pszDrvrAuthMode; /**< auth mode of the stream driver to use */
|
||||
uchar *pszDrvrName; /**< name of stream driver to use */
|
||||
@@ -185,8 +187,11 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */
|
||||
rsRetVal (*SetGnutlsPriorityString)(tcpsrv_t*, uchar*);
|
||||
/* added v21 -- Preserve case in fromhost, 2018-08-16 */
|
||||
rsRetVal (*SetPreserveCase)(tcpsrv_t *pThis, int bPreserveCase);
|
||||
+ /* added v23 -- Options for stricter driver behavior, 2019-08-16 */
|
||||
+ rsRetVal (*SetDrvrCheckExtendedKeyUsage)(tcpsrv_t *pThis, int ChkExtendedKeyUsage);
|
||||
+ rsRetVal (*SetDrvrPrioritizeSAN)(tcpsrv_t *pThis, int prioritizeSan);
|
||||
ENDinterface(tcpsrv)
|
||||
-#define tcpsrvCURR_IF_VERSION 21 /* increment whenever you change the interface structure! */
|
||||
+#define tcpsrvCURR_IF_VERSION 23 /* increment whenever you change the interface structure! */
|
||||
/* change for v4:
|
||||
* - SetAddtlFrameDelim() added -- rgerhards, 2008-12-10
|
||||
* - SetInputName() added -- rgerhards, 2008-12-10
|
||||
diff --git a/tools/omfwd.c b/tools/omfwd.c
|
||||
index cdb74b8d22..96fa68752c 100644
|
||||
--- a/tools/omfwd.c
|
||||
+++ b/tools/omfwd.c
|
||||
@@ -83,6 +83,8 @@ typedef struct _instanceData {
|
||||
uchar *pszStrmDrvrAuthMode;
|
||||
permittedPeers_t *pPermPeers;
|
||||
int iStrmDrvrMode;
|
||||
+ int iStrmDrvrExtendedCertCheck; /* verify also purpose OID in certificate extended field */
|
||||
+ int iStrmDrvrSANPreference; /* ignore CN when any SAN set */
|
||||
char *target;
|
||||
char *address;
|
||||
char *device;
|
||||
@@ -189,6 +191,8 @@ static struct cnfparamdescr actpdescr[] = {
|
||||
{ "streamdrivermode", eCmdHdlrInt, 0 },
|
||||
{ "streamdriverauthmode", eCmdHdlrGetWord, 0 },
|
||||
{ "streamdriverpermittedpeers", eCmdHdlrGetWord, 0 },
|
||||
+ { "streamdriver.CheckExtendedKeyPurpose", eCmdHdlrBinary, 0 },
|
||||
+ { "streamdriver.PrioritizeSAN", eCmdHdlrBinary, 0 },
|
||||
{ "resendlastmsgonreconnect", eCmdHdlrBinary, 0 },
|
||||
{ "udp.sendtoall", eCmdHdlrBinary, 0 },
|
||||
{ "udp.senddelay", eCmdHdlrInt, 0 },
|
||||
@@ -748,6 +752,8 @@ static rsRetVal TCPSendInit(void *pvData)
|
||||
CHKiRet(netstrms.CreateStrm(pWrkrData->pNS, &pWrkrData->pNetstrm));
|
||||
CHKiRet(netstrm.ConstructFinalize(pWrkrData->pNetstrm));
|
||||
CHKiRet(netstrm.SetDrvrMode(pWrkrData->pNetstrm, pData->iStrmDrvrMode));
|
||||
+ CHKiRet(netstrm.SetDrvrCheckExtendedKeyUsage(pWrkrData->pNetstrm, pData->iStrmDrvrExtendedCertCheck));
|
||||
+ CHKiRet(netstrm.SetDrvrPrioritizeSAN(pWrkrData->pNetstrm, pData->iStrmDrvrSANPreference));
|
||||
/* now set optional params, but only if they were actually configured */
|
||||
if(pData->pszStrmDrvrAuthMode != NULL) {
|
||||
CHKiRet(netstrm.SetDrvrAuthMode(pWrkrData->pNetstrm, pData->pszStrmDrvrAuthMode));
|
||||
@@ -1119,6 +1125,8 @@ setInstParamDefaults(instanceData *pData)
|
||||
pData->pszStrmDrvr = NULL;
|
||||
pData->pszStrmDrvrAuthMode = NULL;
|
||||
pData->iStrmDrvrMode = 0;
|
||||
+ pData->iStrmDrvrExtendedCertCheck = 0;
|
||||
+ pData->iStrmDrvrSANPreference = 0;
|
||||
pData->iRebindInterval = 0;
|
||||
pData->bKeepAlive = 0;
|
||||
pData->iKeepAliveProbes = 0;
|
||||
@@ -1220,6 +1228,10 @@ CODESTARTnewActInst
|
||||
pData->pszStrmDrvr = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
} else if(!strcmp(actpblk.descr[i].name, "streamdrivermode")) {
|
||||
pData->iStrmDrvrMode = pvals[i].val.d.n;
|
||||
+ } else if(!strcmp(actpblk.descr[i].name, "streamdriver.CheckExtendedKeyPurpose")) {
|
||||
+ pData->iStrmDrvrExtendedCertCheck = pvals[i].val.d.n;
|
||||
+ } else if(!strcmp(actpblk.descr[i].name, "streamdriver.PrioritizeSAN")) {
|
||||
+ pData->iStrmDrvrSANPreference = pvals[i].val.d.n;
|
||||
} else if(!strcmp(actpblk.descr[i].name, "streamdriverauthmode")) {
|
||||
pData->pszStrmDrvrAuthMode = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||
} else if(!strcmp(actpblk.descr[i].name, "streamdriverpermittedpeers")) {
|
79
SOURCES/rsyslog.conf
Normal file
79
SOURCES/rsyslog.conf
Normal file
@ -0,0 +1,79 @@
|
||||
# rsyslog configuration file
|
||||
|
||||
# For more information see /usr/share/doc/rsyslog-*/rsyslog_conf.html
|
||||
# or latest version online at http://www.rsyslog.com/doc/rsyslog_conf.html
|
||||
# If you experience problems, see http://www.rsyslog.com/doc/troubleshoot.html
|
||||
|
||||
#### MODULES ####
|
||||
|
||||
module(load="imuxsock" # provides support for local system logging (e.g. via logger command)
|
||||
SysSock.Use="off") # Turn off message reception via local log socket;
|
||||
# local messages are retrieved through imjournal now.
|
||||
module(load="imjournal" # provides access to the systemd journal
|
||||
StateFile="imjournal.state") # File to store the position in the journal
|
||||
#module(load="imklog") # reads kernel messages (the same are read from journald)
|
||||
#module(load"immark") # provides --MARK-- message capability
|
||||
|
||||
# Provides UDP syslog reception
|
||||
# for parameters see http://www.rsyslog.com/doc/imudp.html
|
||||
#module(load="imudp") # needs to be done just once
|
||||
#input(type="imudp" port="514")
|
||||
|
||||
# Provides TCP syslog reception
|
||||
# for parameters see http://www.rsyslog.com/doc/imtcp.html
|
||||
#module(load="imtcp") # needs to be done just once
|
||||
#input(type="imtcp" port="514")
|
||||
|
||||
#### GLOBAL DIRECTIVES ####
|
||||
|
||||
# Where to place auxiliary files
|
||||
global(workDirectory="/var/lib/rsyslog")
|
||||
|
||||
# Use default timestamp format
|
||||
module(load="builtin:omfile" Template="RSYSLOG_TraditionalFileFormat")
|
||||
|
||||
# Include all config files in /etc/rsyslog.d/
|
||||
include(file="/etc/rsyslog.d/*.conf" mode="optional")
|
||||
|
||||
#### RULES ####
|
||||
|
||||
# Log all kernel messages to the console.
|
||||
# Logging much else clutters up the screen.
|
||||
#kern.* /dev/console
|
||||
|
||||
# Log anything (except mail) of level info or higher.
|
||||
# Don't log private authentication messages!
|
||||
*.info;mail.none;authpriv.none;cron.none /var/log/messages
|
||||
|
||||
# The authpriv file has restricted access.
|
||||
authpriv.* /var/log/secure
|
||||
|
||||
# Log all the mail messages in one place.
|
||||
mail.* -/var/log/maillog
|
||||
|
||||
|
||||
# Log cron stuff
|
||||
cron.* /var/log/cron
|
||||
|
||||
# Everybody gets emergency messages
|
||||
*.emerg :omusrmsg:*
|
||||
|
||||
# Save news errors of level crit and higher in a special file.
|
||||
uucp,news.crit /var/log/spooler
|
||||
|
||||
# Save boot messages also to boot.log
|
||||
local7.* /var/log/boot.log
|
||||
|
||||
|
||||
# ### sample forwarding rule ###
|
||||
#action(type="omfwd"
|
||||
# An on-disk queue is created for this action. If the remote host is
|
||||
# down, messages are spooled to disk and sent when it is up again.
|
||||
#queue.filename="fwdRule1" # unique name prefix for spool files
|
||||
#queue.maxdiskspace="1g" # 1gb space limit (use as much as possible)
|
||||
#queue.saveonshutdown="on" # save messages to disk on shutdown
|
||||
#queue.type="LinkedList" # run asynchronously
|
||||
#action.resumeRetryCount="-1" # infinite retries if host is down
|
||||
# Remote Logging (we use TCP for reliable delivery)
|
||||
# remote_host is: name/ip, e.g. 192.168.0.1, port optional e.g. 10514
|
||||
#Target="remote_host" Port="XXX" Protocol="tcp")
|
12
SOURCES/rsyslog.log
Normal file
12
SOURCES/rsyslog.log
Normal file
@ -0,0 +1,12 @@
|
||||
/var/log/cron
|
||||
/var/log/maillog
|
||||
/var/log/messages
|
||||
/var/log/secure
|
||||
/var/log/spooler
|
||||
{
|
||||
missingok
|
||||
sharedscripts
|
||||
postrotate
|
||||
/usr/bin/systemctl kill -s HUP rsyslog.service >/dev/null 2>&1 || true
|
||||
endscript
|
||||
}
|
5
SOURCES/rsyslog.sysconfig
Normal file
5
SOURCES/rsyslog.sysconfig
Normal file
@ -0,0 +1,5 @@
|
||||
# Options for rsyslogd
|
||||
# Syslogd options are deprecated since rsyslog v3.
|
||||
# If you want to use them, switch to compatibility mode 2 by "-c 2"
|
||||
# See rsyslogd(8) for more details
|
||||
SYSLOGD_OPTIONS=""
|
574
SPECS/rsyslog.spec
Normal file
574
SPECS/rsyslog.spec
Normal file
@ -0,0 +1,574 @@
|
||||
%define rsyslog_statedir %{_sharedstatedir}/%{name}
|
||||
%define rsyslog_pkidir %{_sysconfdir}/pki/%{name}
|
||||
%define rsyslog_docdir %{_docdir}/%{name}
|
||||
|
||||
|
||||
Summary: Enhanced system logging and kernel message trapping daemon
|
||||
Name: rsyslog
|
||||
Version: 8.37.0
|
||||
Release: 13%{?dist}
|
||||
License: (GPLv3+ and ASL 2.0)
|
||||
Group: System Environment/Daemons
|
||||
ExcludeArch: i686
|
||||
URL: http://www.rsyslog.com/
|
||||
Source0: http://www.rsyslog.com/files/download/rsyslog/%{name}-%{version}.tar.gz
|
||||
Source1: http://www.rsyslog.com/files/download/rsyslog/%{name}-doc-%{version}.tar.gz
|
||||
Source2: rsyslog.conf
|
||||
Source3: rsyslog.sysconfig
|
||||
Source4: rsyslog.log
|
||||
|
||||
BuildRequires: autoconf
|
||||
BuildRequires: automake
|
||||
BuildRequires: bison
|
||||
BuildRequires: flex
|
||||
BuildRequires: libcurl-devel
|
||||
BuildRequires: libgcrypt-devel
|
||||
BuildRequires: libfastjson-devel >= 0.99.8
|
||||
BuildRequires: libestr-devel >= 0.1.9
|
||||
BuildRequires: libtool
|
||||
BuildRequires: libuuid-devel
|
||||
BuildRequires: pkgconfig
|
||||
BuildRequires: python3-docutils
|
||||
# it depens on rhbz#1419228
|
||||
BuildRequires: systemd-devel >= 219-39
|
||||
BuildRequires: zlib-devel
|
||||
|
||||
Requires: logrotate >= 3.5.2
|
||||
Requires: bash >= 2.0
|
||||
Requires: libestr >= 0.1.9
|
||||
Requires(post): systemd
|
||||
Requires(preun): systemd
|
||||
Requires(postun): systemd
|
||||
|
||||
Provides: syslog
|
||||
Obsoletes: sysklogd < 1.5-11
|
||||
|
||||
# tweak the upstream service file to honour configuration from /etc/sysconfig/rsyslog
|
||||
Patch0: rsyslog-8.32.0-service.patch
|
||||
# imjournal: adds "journal" when tag/process name is missing
|
||||
Patch1: rsyslog-8.37.0-rhbz1659898-imjournal-default-tag.patch
|
||||
Patch2: rsyslog-8.37.0-rhbz1614179-imfile-symlink-support.patch
|
||||
Patch3: rsyslog-8.37.0-rhbz1622768-kubernetes-404-handling.patch
|
||||
Patch4: rsyslog-8.37.0-rhbz1627941-imfile-support-for-endmsg.regex.patch
|
||||
Patch5: rsyslog-8.37.0-rhbz1674471-imfile-log-rotation.patch
|
||||
Patch6: rsyslog-8.37.0-rhbz1677037-short-offMsg-overrun-crash.patch
|
||||
Patch7: rsyslog-8.37.0-rhbz1614181-imtcp-imudp-preservecase-option.patch
|
||||
Patch8: rsyslog-8.37.0-rhbz1716867-imjournal-memleak.patch
|
||||
Patch9: rsyslog-8.37.0-rhbz1722165-imjournal-flooding-errors.patch
|
||||
Patch10: rsyslog-8.37.0-rhbz1724218-imrelp-old-syntax.patch
|
||||
Patch11: rsyslog-8.37.0-rhbz1733244-TLS-CC-compatibility.patch
|
||||
|
||||
%package crypto
|
||||
Summary: Encryption support
|
||||
Group: System Environment/Daemons
|
||||
Requires: %name = %version-%release
|
||||
|
||||
%package doc
|
||||
Summary: HTML Documentation for rsyslog
|
||||
Group: Documentation
|
||||
#no reason to have arched documentation
|
||||
BuildArch: noarch
|
||||
|
||||
%package elasticsearch
|
||||
Summary: ElasticSearch output module for rsyslog
|
||||
Group: System Environment/Daemons
|
||||
Requires: %name = %version-%release
|
||||
|
||||
%package gnutls
|
||||
Summary: TLS protocol support for rsyslog
|
||||
Group: System Environment/Daemons
|
||||
Requires: %name = %version-%release
|
||||
BuildRequires: gnutls-devel
|
||||
|
||||
%package gssapi
|
||||
Summary: GSSAPI authentication and encryption support for rsyslog
|
||||
Group: System Environment/Daemons
|
||||
Requires: %name = %version-%release
|
||||
BuildRequires: krb5-devel
|
||||
|
||||
%package kafka
|
||||
Summary: Provides kafka support for rsyslog
|
||||
Group: System Environment/Daemons
|
||||
Requires: %name = %version-%release
|
||||
BuildRequires: librdkafka-devel
|
||||
|
||||
%package mmaudit
|
||||
Summary: Message modification module supporting Linux audit format
|
||||
Group: System Environment/Daemons
|
||||
Requires: %name = %version-%release
|
||||
|
||||
%package mmjsonparse
|
||||
Summary: JSON enhanced logging support
|
||||
Group: System Environment/Daemons
|
||||
Requires: %name = %version-%release
|
||||
|
||||
%package mmkubernetes
|
||||
Summary: Provides the mmkubernetes module
|
||||
Group: System Environment/Daemons
|
||||
Requires: %name = %version-%release
|
||||
|
||||
%package mmnormalize
|
||||
Summary: Log normalization support for rsyslog
|
||||
Group: System Environment/Daemons
|
||||
Requires: %name = %version-%release
|
||||
BuildRequires: liblognorm-devel
|
||||
|
||||
%package mmsnmptrapd
|
||||
Summary: Message modification module for snmptrapd generated messages
|
||||
Group: System Environment/Daemons
|
||||
Requires: %name = %version-%release
|
||||
|
||||
%package mysql
|
||||
Summary: MySQL support for rsyslog
|
||||
Group: System Environment/Daemons
|
||||
Requires: %name = %version-%release
|
||||
BuildRequires: mariadb-connector-c-devel
|
||||
|
||||
%package pgsql
|
||||
Summary: PostgresSQL support for rsyslog
|
||||
Group: System Environment/Daemons
|
||||
Requires: %name = %version-%release
|
||||
BuildRequires: postgresql-devel
|
||||
|
||||
%package relp
|
||||
Summary: RELP protocol support for rsyslog
|
||||
Group: System Environment/Daemons
|
||||
Requires: %name = %version-%release
|
||||
Requires: librelp >= 1.0.3
|
||||
BuildRequires: librelp-devel >= 1.2.16
|
||||
|
||||
%package snmp
|
||||
Summary: SNMP protocol support for rsyslog
|
||||
Group: System Environment/Daemons
|
||||
Requires: %name = %version-%release
|
||||
BuildRequires: net-snmp-devel
|
||||
|
||||
%description
|
||||
Rsyslog is an enhanced, multi-threaded syslog daemon. It supports MySQL,
|
||||
syslog/TCP, RFC 3195, permitted sender lists, filtering on any message part,
|
||||
and fine grain output format control. It is compatible with stock sysklogd
|
||||
and can be used as a drop-in replacement. Rsyslog is simple to set up, with
|
||||
advanced features suitable for enterprise-class, encryption-protected syslog
|
||||
relay chains.
|
||||
|
||||
%description crypto
|
||||
This package contains a module providing log file encryption and a
|
||||
command line tool to process encrypted logs.
|
||||
|
||||
%description doc
|
||||
This subpackage contains documentation for rsyslog.
|
||||
|
||||
%description elasticsearch
|
||||
This module provides the capability for rsyslog to feed logs directly into
|
||||
Elasticsearch.
|
||||
|
||||
%description gnutls
|
||||
The rsyslog-gnutls package contains the rsyslog plugins that provide the
|
||||
ability to receive syslog messages via upcoming syslog-transport-tls
|
||||
IETF standard protocol.
|
||||
|
||||
%description gssapi
|
||||
The rsyslog-gssapi package contains the rsyslog plugins which support GSSAPI
|
||||
authentication and secure connections. GSSAPI is commonly used for Kerberos
|
||||
authentication.
|
||||
|
||||
%description kafka
|
||||
The rsyslog-kafka package provides modules for Apache Kafka input and output.
|
||||
|
||||
%description mmaudit
|
||||
This module provides message modification supporting Linux audit format
|
||||
in various settings.
|
||||
|
||||
%description mmjsonparse
|
||||
This module provides the capability to recognize and parse JSON enhanced
|
||||
syslog messages.
|
||||
|
||||
%description mmkubernetes
|
||||
The rsyslog-mmkubernetes package provides module for adding kubernetes
|
||||
container metadata.
|
||||
|
||||
%description mmnormalize
|
||||
This module provides the capability to normalize log messages via liblognorm.
|
||||
|
||||
%description mmsnmptrapd
|
||||
This message modification module takes messages generated from snmptrapd and
|
||||
modifies them so that they look like they originated from the read originator.
|
||||
|
||||
%description mysql
|
||||
The rsyslog-mysql package contains a dynamic shared object that will add
|
||||
MySQL database support to rsyslog.
|
||||
|
||||
%description pgsql
|
||||
The rsyslog-pgsql package contains a dynamic shared object that will add
|
||||
PostgreSQL database support to rsyslog.
|
||||
|
||||
%description relp
|
||||
The rsyslog-relp package contains the rsyslog plugins that provide
|
||||
the ability to receive syslog messages via the reliable RELP
|
||||
protocol.
|
||||
|
||||
%description snmp
|
||||
The rsyslog-snmp package contains the rsyslog plugin that provides the
|
||||
ability to send syslog messages as SNMPv1 and SNMPv2c traps.
|
||||
|
||||
%prep
|
||||
# set up rsyslog-doc sources
|
||||
%setup -q -a 1 -T -c
|
||||
|
||||
#regenerate the docs
|
||||
|
||||
#mv build/searchindex.js searchindex_backup.js
|
||||
#sphinx-build -b html source build
|
||||
#clean up
|
||||
#mv searchindex_backup.js build/searchindex.js
|
||||
|
||||
rm -r LICENSE README.md source build/objects.inv
|
||||
mv build doc
|
||||
|
||||
# set up rsyslog sources
|
||||
%setup -q -D
|
||||
|
||||
%patch0 -p1 -b .service
|
||||
%patch1 -p1 -b .default-tag
|
||||
%patch2 -p1 -b .imfile-symlink
|
||||
%patch3 -p1 -b .mmkubernetes-404
|
||||
%patch4 -p1 -b .endmsg-regex
|
||||
%patch5 -p1 -b .rotation-detection
|
||||
%patch6 -p1 -b .short-offmsg-crash
|
||||
%patch7 -p1 -b .preservecase-option
|
||||
%patch8 -p1 -b .imjournal-memleak
|
||||
%patch9 -p1 -b .imjournal-err-flood
|
||||
%patch10 -p1 -b .imrelp-old-syntax
|
||||
%patch11 -p1 -b .tls-CC
|
||||
|
||||
%build
|
||||
%ifarch sparc64
|
||||
#sparc64 need big PIE
|
||||
export CFLAGS="$RPM_OPT_FLAGS -fPIE"
|
||||
%else
|
||||
export CFLAGS="$RPM_OPT_FLAGS -fpie"
|
||||
%endif
|
||||
export LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now"
|
||||
|
||||
sed -i 's/%{version}/%{version}-%{release}/g' configure.ac
|
||||
autoreconf -if
|
||||
%configure \
|
||||
--prefix=/usr \
|
||||
--disable-static \
|
||||
--disable-testbench \
|
||||
--enable-elasticsearch \
|
||||
--enable-generate-man-pages \
|
||||
--enable-gnutls \
|
||||
--enable-gssapi-krb5 \
|
||||
--enable-imdiag \
|
||||
--enable-imfile \
|
||||
--enable-imjournal \
|
||||
--enable-imkafka \
|
||||
--enable-impstats \
|
||||
--enable-imptcp \
|
||||
--enable-mail \
|
||||
--enable-mmanon \
|
||||
--enable-mmaudit \
|
||||
--enable-mmcount \
|
||||
--enable-mmjsonparse \
|
||||
--enable-mmkubernetes \
|
||||
--enable-mmnormalize \
|
||||
--enable-mmsnmptrapd \
|
||||
--enable-mmutf8fix \
|
||||
--enable-mysql \
|
||||
--enable-omjournal \
|
||||
--enable-omkafka \
|
||||
--enable-omprog \
|
||||
--enable-omstdout \
|
||||
--enable-omuxsock \
|
||||
--enable-pgsql \
|
||||
--enable-pmaixforwardedfrom \
|
||||
--enable-pmcisconames \
|
||||
--enable-pmlastmsg \
|
||||
--enable-pmsnare \
|
||||
--enable-relp \
|
||||
--enable-snmp \
|
||||
--enable-unlimited-select \
|
||||
--enable-usertools
|
||||
|
||||
make
|
||||
|
||||
%install
|
||||
make DESTDIR=%{buildroot} install
|
||||
|
||||
install -d -m 755 %{buildroot}%{_sysconfdir}/sysconfig
|
||||
install -d -m 755 %{buildroot}%{_sysconfdir}/logrotate.d
|
||||
install -d -m 755 %{buildroot}%{_sysconfdir}/rsyslog.d
|
||||
install -d -m 700 %{buildroot}%{rsyslog_statedir}
|
||||
install -d -m 700 %{buildroot}%{rsyslog_pkidir}
|
||||
install -d -m 755 %{buildroot}%{rsyslog_docdir}/html
|
||||
|
||||
install -p -m 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/rsyslog.conf
|
||||
install -p -m 644 %{SOURCE3} %{buildroot}%{_sysconfdir}/sysconfig/rsyslog
|
||||
install -p -m 644 %{SOURCE4} %{buildroot}%{_sysconfdir}/logrotate.d/syslog
|
||||
install -p -m 644 plugins/ommysql/createDB.sql %{buildroot}%{rsyslog_docdir}/mysql-createDB.sql
|
||||
install -p -m 644 plugins/ompgsql/createDB.sql %{buildroot}%{rsyslog_docdir}/pgsql-createDB.sql
|
||||
install -p -m 644 contrib/mmkubernetes/*.rulebase %{buildroot}%{rsyslog_docdir}
|
||||
# extract documentation
|
||||
cp -r doc/* %{buildroot}%{rsyslog_docdir}/html
|
||||
# get rid of libtool libraries
|
||||
rm -f %{buildroot}%{_libdir}/rsyslog/*.la
|
||||
# get rid of socket activation by default
|
||||
sed -i '/^Alias/s/^/;/;/^Requires=syslog.socket/s/^/;/' %{buildroot}%{_unitdir}/rsyslog.service
|
||||
|
||||
# convert line endings from "\r\n" to "\n"
|
||||
cat tools/recover_qi.pl | tr -d '\r' > %{buildroot}%{_bindir}/rsyslog-recover-qi.pl
|
||||
|
||||
%post
|
||||
for n in /var/log/{messages,secure,maillog,spooler}
|
||||
do
|
||||
[ -f $n ] && continue
|
||||
umask 066 && touch $n
|
||||
done
|
||||
%systemd_post rsyslog.service
|
||||
|
||||
%preun
|
||||
%systemd_preun rsyslog.service
|
||||
|
||||
%postun
|
||||
%systemd_postun_with_restart rsyslog.service
|
||||
|
||||
%files
|
||||
%doc AUTHORS COPYING* ChangeLog
|
||||
%exclude %{rsyslog_docdir}/html
|
||||
%exclude %{rsyslog_docdir}/mysql-createDB.sql
|
||||
%exclude %{rsyslog_docdir}/pgsql-createDB.sql
|
||||
%dir %{_libdir}/rsyslog
|
||||
%dir %{_sysconfdir}/rsyslog.d
|
||||
%dir %{rsyslog_statedir}
|
||||
%dir %{rsyslog_pkidir}
|
||||
%{_sbindir}/rsyslogd
|
||||
%attr(755,root,root) %{_bindir}/rsyslog-recover-qi.pl
|
||||
%{_mandir}/man5/rsyslog.conf.5.gz
|
||||
%{_mandir}/man8/rsyslogd.8.gz
|
||||
%{_unitdir}/rsyslog.service
|
||||
%config(noreplace) %{_sysconfdir}/rsyslog.conf
|
||||
%config(noreplace) %{_sysconfdir}/sysconfig/rsyslog
|
||||
%config(noreplace) %{_sysconfdir}/logrotate.d/syslog
|
||||
# plugins
|
||||
%{_libdir}/rsyslog/fmhash.so
|
||||
%{_libdir}/rsyslog/fmhttp.so
|
||||
%{_libdir}/rsyslog/imdiag.so
|
||||
%{_libdir}/rsyslog/imfile.so
|
||||
%{_libdir}/rsyslog/imjournal.so
|
||||
%{_libdir}/rsyslog/imklog.so
|
||||
%{_libdir}/rsyslog/immark.so
|
||||
%{_libdir}/rsyslog/impstats.so
|
||||
%{_libdir}/rsyslog/imptcp.so
|
||||
%{_libdir}/rsyslog/imtcp.so
|
||||
%{_libdir}/rsyslog/imudp.so
|
||||
%{_libdir}/rsyslog/imuxsock.so
|
||||
%{_libdir}/rsyslog/lmnet.so
|
||||
%{_libdir}/rsyslog/lmnetstrms.so
|
||||
%{_libdir}/rsyslog/lmnsd_ptcp.so
|
||||
%{_libdir}/rsyslog/lmregexp.so
|
||||
%{_libdir}/rsyslog/lmstrmsrv.so
|
||||
%{_libdir}/rsyslog/lmtcpclt.so
|
||||
%{_libdir}/rsyslog/lmtcpsrv.so
|
||||
%{_libdir}/rsyslog/lmzlibw.so
|
||||
%{_libdir}/rsyslog/mmanon.so
|
||||
%{_libdir}/rsyslog/mmcount.so
|
||||
%{_libdir}/rsyslog/mmexternal.so
|
||||
%{_libdir}/rsyslog/mmutf8fix.so
|
||||
%{_libdir}/rsyslog/omjournal.so
|
||||
%{_libdir}/rsyslog/ommail.so
|
||||
%{_libdir}/rsyslog/omprog.so
|
||||
%{_libdir}/rsyslog/omstdout.so
|
||||
%{_libdir}/rsyslog/omtesting.so
|
||||
%{_libdir}/rsyslog/omuxsock.so
|
||||
%{_libdir}/rsyslog/pmaixforwardedfrom.so
|
||||
%{_libdir}/rsyslog/pmcisconames.so
|
||||
%{_libdir}/rsyslog/pmlastmsg.so
|
||||
%{_libdir}/rsyslog/pmsnare.so
|
||||
|
||||
%files crypto
|
||||
%{_bindir}/rscryutil
|
||||
%{_mandir}/man1/rscryutil.1.gz
|
||||
%{_libdir}/rsyslog/lmcry_gcry.so
|
||||
|
||||
%files doc
|
||||
%doc %{rsyslog_docdir}/html
|
||||
|
||||
%files elasticsearch
|
||||
%{_libdir}/rsyslog/omelasticsearch.so
|
||||
|
||||
%files gssapi
|
||||
%{_libdir}/rsyslog/lmgssutil.so
|
||||
%{_libdir}/rsyslog/imgssapi.so
|
||||
%{_libdir}/rsyslog/omgssapi.so
|
||||
|
||||
%files gnutls
|
||||
%{_libdir}/rsyslog/lmnsd_gtls.so
|
||||
|
||||
%files kafka
|
||||
%{_libdir}/rsyslog/imkafka.so
|
||||
%{_libdir}/rsyslog/omkafka.so
|
||||
|
||||
%files mmaudit
|
||||
%{_libdir}/rsyslog/mmaudit.so
|
||||
|
||||
%files mmjsonparse
|
||||
%{_libdir}/rsyslog/mmjsonparse.so
|
||||
|
||||
%files mmkubernetes
|
||||
%{_libdir}/rsyslog/mmkubernetes.so
|
||||
%doc %{rsyslog_docdir}/k8s_filename.rulebase
|
||||
%doc %{rsyslog_docdir}/k8s_container_name.rulebase
|
||||
|
||||
%files mmnormalize
|
||||
%{_libdir}/rsyslog/mmnormalize.so
|
||||
|
||||
%files mmsnmptrapd
|
||||
%{_libdir}/rsyslog/mmsnmptrapd.so
|
||||
|
||||
%files mysql
|
||||
%doc %{rsyslog_docdir}/mysql-createDB.sql
|
||||
%{_libdir}/rsyslog/ommysql.so
|
||||
|
||||
%files pgsql
|
||||
%doc %{rsyslog_docdir}/pgsql-createDB.sql
|
||||
%{_libdir}/rsyslog/ompgsql.so
|
||||
|
||||
%files relp
|
||||
%{_libdir}/rsyslog/imrelp.so
|
||||
%{_libdir}/rsyslog/omrelp.so
|
||||
|
||||
%files snmp
|
||||
%{_libdir}/rsyslog/omsnmp.so
|
||||
|
||||
|
||||
%changelog
|
||||
* Fri Aug 30 2019 Jiri Vymazal <jvymazal@redhat.com> - 8.37.0-13
|
||||
RHEL 8.1.0 ERRATUM
|
||||
- added patch enabling stricter TLS certs checking conforming to
|
||||
common criteria requirements
|
||||
resolves: rhbz#1733244
|
||||
|
||||
* Mon Jul 22 2019 Jiri Vymazal <jvymazal@redhat.com> - 8.37.0-12
|
||||
RHEL 8.1.0 ERRATUM
|
||||
- edited imjournal memleak patch to not cause double-free crash
|
||||
resolves: rhbz#1729995
|
||||
- added patch calling journald API only when there are no
|
||||
preceeding errors
|
||||
resolves: rhbz#1722165
|
||||
- added patch fixing imrelp module when invoked with old syntax
|
||||
resolves: rhbz#1724218
|
||||
|
||||
* Wed Jun 05 2019 Jiri Vymazal <jvymazal@redhat.com> - 8.37.0-11
|
||||
RHEL 8.1.0 ERRATUM
|
||||
- fixed memory leak in imjournal by proper cursor releasing
|
||||
resolves: rhbz#1716867
|
||||
|
||||
* Fri May 10 2019 Jiri Vymazal <jvymazal@redhat.com> - 8.37.0-10
|
||||
RHEL 8.1.0 ERRATUM
|
||||
- added option for imfile endmsg.regex
|
||||
resolves: rhbz#1627941
|
||||
- added patch enhancing imfile rotation detection
|
||||
resolves: rhbz#1674471
|
||||
- added patch fixing msgOffset datatype preventing crash on
|
||||
message with too long other fields
|
||||
resolves: rhbz#1677037
|
||||
- added patch introducing "preservecase" option for imudp/imtcp
|
||||
resolves: rhbz#1614181
|
||||
|
||||
* Mon Dec 17 2018 Jiri Vymazal <jvymazal@redhat.com> - 8.37.0-9
|
||||
RHEL 8.0.0 ERRATUM
|
||||
- added back legacy option for imjournal default tag
|
||||
resolves: rhbz#1659898
|
||||
|
||||
* Fri Dec 14 2018 Jiri Vymazal <jvymazal@redhat.com> - 8.37.0-8
|
||||
RHEL 8.0.0 ERRATUM
|
||||
- fixes mmkubenetes handling 404 and 429 errors
|
||||
resolves: rhbz#1622768
|
||||
|
||||
* Fri Oct 19 2018 Jiri Vymazal <jvymazal@redhat.com> - 8.37.0-7
|
||||
- removed version from docdir macro
|
||||
resolves: rhbz#1638023
|
||||
|
||||
* Mon Aug 27 2018 Jiri Vymazal <jvymazal@redhat.com> - 8.37.0-6
|
||||
- updated patch for enhanced imfile symlink support
|
||||
resolves: rhbz#1614179
|
||||
|
||||
* Fri Aug 10 2018 Jiri Vymazal <jvymazal@redhat.com> - 8.37.0-5
|
||||
- rebuild for rebased dependencies
|
||||
- dependency cleanup and sorted sub-packages in spec
|
||||
resolves: rhbz#1613880
|
||||
|
||||
* Fri Aug 10 2018 Jiri Vymazal <jvymazal@redhat.com> - 8.37.0-4
|
||||
- enabled mmkubernetes module
|
||||
resolves: rhbz#1614432
|
||||
resolves: rhbz#1614441
|
||||
|
||||
* Thu Aug 09 2018 Josef Ridky <jridky@redhat.com> - 8.37.0-3
|
||||
- Rebuild for Net-SNMP
|
||||
|
||||
* Thu Aug 09 2018 Jiri Vymazal <jvymazal@redhat.com> - 8.37.0-2
|
||||
- added patch for enhanced imfile symlink support
|
||||
resolves: rhbz#1614179
|
||||
|
||||
* Wed Aug 08 2018 Jiri Vymazal <jvymazal@redhat.com> - 8.37.0-1
|
||||
- rebase to 8.37.0
|
||||
resolves: rhbz#1613880
|
||||
resolves: rhbz#1564054
|
||||
resolves: rhbz#1598218
|
||||
- dropped invalid statefile patch - upstreamed
|
||||
- dropped imjournal duplicates patch - upstreamed
|
||||
resolves: rhbz#1544394
|
||||
- renumbered default tag patch and fitted onto rebased version
|
||||
|
||||
* Fri Aug 03 2018 Jiri Vymazal <jvymazal@redhat.com> - 8.36.0-4
|
||||
- removed dependency on libee
|
||||
resolves: rhbz#1612032
|
||||
|
||||
* Wed Aug 01 2018 Jiri Vymazal <jvymazal@redhat.com> - 8.36.0-3
|
||||
- dropped json_nonoverwrite patch as there is no reason for
|
||||
keeping it
|
||||
- renumbered rest of patches
|
||||
- added release number to AC_INIT to have it in package error logs
|
||||
|
||||
* Mon Jul 16 2018 Charalampos Stratakis <cstratak@redhat.com> - 8.36.0-2
|
||||
- Depend on python3-docutils
|
||||
|
||||
* Mon Jul 02 2018 Jiri Vymazal <jvymazal@redhat.com> - 8.36.0-1
|
||||
- changed PID file name to follow upstream
|
||||
- removed config option to disable stdlog as it is now
|
||||
disabled by default
|
||||
|
||||
* Thu Jun 28 2018 Jiri Vymazal <jvymazal@redhat.com> - 8.36.0-1
|
||||
- rebase to 8.36
|
||||
- removed hiredis module
|
||||
- removed omudpspoof module
|
||||
resolves: rhbz#1593762
|
||||
- finished converting config to new-style syntax
|
||||
|
||||
* Mon May 21 2018 Jiri Vymazal <jvymazal@redhat.com> - 8.35.0-1
|
||||
- spec file cleanup
|
||||
- enabled kafka and hiredis modules
|
||||
resolves: rhbz#1542497
|
||||
resolves: rhbz#1542504
|
||||
- renamed patch fixing imjournal duplicating messages
|
||||
resolves: rhbz#1544394
|
||||
|
||||
* Thu May 17 2018 Marek Tamaskovic <mtamasko@redhat.com> - 8.35.0-1
|
||||
- rebase to 8.35
|
||||
- rebased patches from 8.32 to 8.35
|
||||
- fixed imjournal-duplicates
|
||||
- fixed imjournal-default-tag
|
||||
- fixed service patch
|
||||
- fixed in upstream deserialize-property-name
|
||||
|
||||
* Fri Mar 23 2018 Radovan Sroka <rsroka@redhat.com> - 8.32.0-2
|
||||
- rebuild, bumped release number
|
||||
|
||||
* Tue Feb 06 2018 Radovan Sroka <rsroka@redhat.com> - 8.32.0-1
|
||||
- initial clean build with plugins from rhel7
|
||||
- removed plugins:
|
||||
- libdbi
|
||||
- omruleset
|
||||
- pmrfc3164sd
|
||||
- imported from fedora26
|
Loading…
Reference in New Issue
Block a user