Blob Blame History Raw
From c661a2917d065339e00d7588320a653ba29792ea Mon Sep 17 00:00:00 2001
From: Tomas Heinrich <theinric@redhat.com>
Date: Mon, 27 Jun 2016 20:10:31 +0200
Subject: [PATCH] Allow multiple rulesets in imrelp

Disable legacy module config directives if new style was used
---
 plugins/imrelp/imrelp.c | 140 ++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 113 insertions(+), 27 deletions(-)

diff --git a/plugins/imrelp/imrelp.c b/plugins/imrelp/imrelp.c
index 5e0ae55..203e7cb 100644
--- a/plugins/imrelp/imrelp.c
+++ b/plugins/imrelp/imrelp.c
@@ -75,6 +75,8 @@ static struct configSettings_s {
 struct instanceConf_s {
 	uchar *pszBindPort;		/* port to bind to */
 	struct instanceConf_s *next;
+	uchar *pszBindRuleset;          /* name of ruleset to bind to */
+	ruleset_t *pBindRuleset;        /* ruleset to bind listener to */
 };
 
 
@@ -88,9 +90,20 @@ struct modConfData_s {
 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 */
 
+/* module-global parameters */
+static struct cnfparamdescr modpdescr[] = {
+       { "ruleset", eCmdHdlrGetWord, 0 },
+};
+static struct cnfparamblk modpblk =
+       { CNFPARAMBLK_VERSION,
+         sizeof(modpdescr)/sizeof(struct cnfparamdescr),
+         modpdescr
+       };
+
 /* input instance parameters */
 static struct cnfparamdescr inppdescr[] = {
-	{ "port", eCmdHdlrString, CNFPARAM_REQUIRED }
+	{ "port", eCmdHdlrString, CNFPARAM_REQUIRED },
+	{ "ruleset", eCmdHdlrGetWord, 0 }
 };
 static struct cnfparamblk inppblk =
 	{ CNFPARAMBLK_VERSION,
@@ -99,6 +112,9 @@ static struct cnfparamblk inppblk =
 	};
 
 
+#include "im-helper.h" /* must be included AFTER the type definitions! */
+static int bLegacyCnfModGlobalsPermitted;/* are legacy module-global config parameters permitted? */
+
 
 /* ------------------------------ callbacks ------------------------------ */
 
@@ -113,17 +129,18 @@ static struct cnfparamblk inppblk =
  * we will only see the hostname (twice). -- rgerhards, 2009-10-14
  */
 static relpRetVal
-onSyslogRcv(uchar *pHostname, uchar *pIP, uchar *msg, size_t lenMsg)
+onSyslogRcv(void *pUsr, uchar *pHostname, uchar *pIP, uchar *msg, size_t lenMsg)
 {
 	prop_t *pProp = NULL;
 	msg_t *pMsg;
+	instanceConf_t *inst = (instanceConf_t*) pUsr;
 	DEFiRet;
 
 	CHKiRet(msgConstruct(&pMsg));
 	MsgSetInputName(pMsg, pInputName);
 	MsgSetRawMsg(pMsg, (char*)msg, lenMsg);
 	MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY);
-	MsgSetRuleset(pMsg, runModConf->pBindRuleset);
+	MsgSetRuleset(pMsg, inst->pBindRuleset);
 	pMsg->msgFlags  = PARSE_HOSTNAME | NEEDS_PARSING;
 
 	/* TODO: optimize this, we can store it inside the session, requires
@@ -155,6 +172,8 @@ createInstance(instanceConf_t **pinst)
 	inst->next = NULL;
 
 	inst->pszBindPort = NULL;
+	inst->pszBindRuleset = NULL;
+	inst->pBindRuleset = NULL;
 
 	/* node created, let's add to config */
 	if(loadModConf->tail == NULL) {
@@ -174,8 +193,10 @@ finalize_it:
 static inline void
 std_checkRuleset_genErrMsg(modConfData_t *modConf, __attribute__((unused)) instanceConf_t *inst)
 {
-	errmsg.LogError(0, NO_ERRCODE, "imrelp: ruleset '%s' not found - "
-			"using default ruleset instead", modConf->pszBindRuleset);
+	errmsg.LogError(0, NO_ERRCODE, "imrelp[%s]: ruleset '%s' not found - "
+			"using default ruleset instead",
+			inst->pszBindPort, inst->pszBindRuleset);
+
 }
 
 
@@ -196,6 +217,14 @@ static rsRetVal addInstance(void __attribute__((unused)) *pVal, uchar *pNewVal)
 	}
 	inst->pszBindPort = pNewVal;
 
+	if((cs.pszBindRuleset == NULL) || (cs.pszBindRuleset[0] == '\0')) {
+		inst->pszBindRuleset = NULL;
+	} else {
+		CHKmalloc(inst->pszBindRuleset = ustrdup(cs.pszBindRuleset));
+	}
+	inst->pBindRuleset = NULL;
+
+
 finalize_it:
 	RETiRet;
 }
@@ -205,18 +234,33 @@ static rsRetVal
 addListner(modConfData_t __attribute__((unused)) *modConf, instanceConf_t *inst)
 {
 	DEFiRet;
+	relpSrv_t *pSrv;
+	int relpRet;
+
 	if(pRelpEngine == NULL) {
 		CHKiRet(relpEngineConstruct(&pRelpEngine));
 		CHKiRet(relpEngineSetDbgprint(pRelpEngine, dbgprintf));
 		CHKiRet(relpEngineSetFamily(pRelpEngine, glbl.GetDefPFFamily()));
 		CHKiRet(relpEngineSetEnableCmd(pRelpEngine, (uchar*) "syslog", eRelpCmdState_Required));
-		CHKiRet(relpEngineSetSyslogRcv(pRelpEngine, onSyslogRcv));
+		CHKiRet(relpEngineSetSyslogRcv2(pRelpEngine, onSyslogRcv));
 		if (!glbl.GetDisableDNS()) {
 			CHKiRet(relpEngineSetDnsLookupMode(pRelpEngine, 1));
 		}
 	}
 
-	CHKiRet(relpEngineAddListner(pRelpEngine, inst->pszBindPort));
+	CHKiRet(relpEngineListnerConstruct(pRelpEngine, &pSrv));
+	CHKiRet(relpSrvSetLstnPort(pSrv, inst->pszBindPort));
+
+	relpSrvSetUsrPtr(pSrv, inst);
+
+	relpRet = relpEngineListnerConstructFinalize(pRelpEngine, pSrv);
+	if(relpRet != RELP_RET_OK) {
+		errmsg.LogError(0, RS_RET_RELP_ERR,
+				"imrelp: could not activate relp listner, code %d", relpRet);
+		ABORT_FINALIZE(RS_RET_RELP_ERR);
+	}
+
+	resetConfigVariables(NULL,NULL);
 
 finalize_it:
 	RETiRet;
@@ -249,6 +293,8 @@ CODESTARTnewInpInst
 			continue;
 		if(!strcmp(inppblk.descr[i].name, "port")) {
 			inst->pszBindPort = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
+		} else if(!strcmp(inppblk.descr[i].name, "ruleset")) {
+			inst->pszBindRuleset = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
 		} else {
 			dbgprintf("imrelp: program error, non-handled "
 			  "param '%s'\n", inppblk.descr[i].name);
@@ -264,41 +310,76 @@ BEGINbeginCnfLoad
 CODESTARTbeginCnfLoad
 	loadModConf = pModConf;
 	pModConf->pConf = pConf;
+	pModConf->pszBindRuleset = NULL;
 	/* init legacy config variables */
 	cs.pszBindRuleset = NULL;
+	bLegacyCnfModGlobalsPermitted = 1;
 ENDbeginCnfLoad
 
+BEGINsetModCnf
+	struct cnfparamvals *pvals = NULL;
+	int i;
+CODESTARTsetModCnf
+	pvals = nvlstGetParams(lst, &modpblk, NULL);
+	if(pvals == NULL) {
+		errmsg.LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing module "
+				"config parameters [module(...)]");
+		ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS);
+	}
+
+	if(Debug) {
+		dbgprintf("module (global) param blk for imrelp:\n");
+		cnfparamsPrint(&modpblk, pvals);
+	}
+
+	for(i = 0 ; i < modpblk.nParams ; ++i) {
+		if(!pvals[i].bUsed)
+			continue;
+		if(!strcmp(modpblk.descr[i].name, "ruleset")) {
+			loadModConf->pszBindRuleset = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
+		} else {
+			dbgprintf("imrelp: program error, non-handled "
+			  "param '%s' in beginCnfLoad\n", modpblk.descr[i].name);
+		}
+	}
+	/* remove all of our legacy module handlers, as they can not used in addition
+	 * the the new-style config method.
+	 */
+	bLegacyCnfModGlobalsPermitted = 0;
+finalize_it:
+	if(pvals != NULL)
+		cnfparamvalsDestruct(pvals, &modpblk);
+ENDsetModCnf
 
 BEGINendCnfLoad
 CODESTARTendCnfLoad
-	if((cs.pszBindRuleset == NULL) || (cs.pszBindRuleset[0] == '\0')) {
-		loadModConf->pszBindRuleset = NULL;
+	if(loadModConf->pszBindRuleset == NULL) {
+		if((cs.pszBindRuleset == NULL) || (cs.pszBindRuleset[0] == '\0')) {
+			loadModConf->pszBindRuleset = NULL;
+		} else {
+			CHKmalloc(loadModConf->pszBindRuleset = ustrdup(cs.pszBindRuleset));
+		}
 	} else {
-		CHKmalloc(loadModConf->pszBindRuleset = ustrdup(cs.pszBindRuleset));
+		if((cs.pszBindRuleset != NULL) && (cs.pszBindRuleset[0] != '\0')) {
+			errmsg.LogError(0, RS_RET_DUP_PARAM, "imrelp: warning: ruleset "
+				       "set via legacy directive ignored");
+		}
 	}
-	loadModConf->pBindRuleset = NULL;
 finalize_it:
 	free(cs.pszBindRuleset);
+	cs.pszBindRuleset = NULL;
 	loadModConf = NULL; /* done loading */
 ENDendCnfLoad
 
 
 BEGINcheckCnf
-	rsRetVal localRet;
-	ruleset_t *pRuleset;
+	instanceConf_t *inst;
 CODESTARTcheckCnf
-	/* we emulate the standard "ruleset query" code provided by the framework
-	 * for *instances* (which we can currently not support due to librelp).
-	 */
-	if(pModConf->pszBindRuleset == NULL) {
-		pModConf->pBindRuleset = NULL;
-	} else {
-		localRet = ruleset.GetRuleset(pModConf->pConf, &pRuleset, pModConf->pszBindRuleset);
-		if(localRet == RS_RET_NOT_FOUND) {
-			std_checkRuleset_genErrMsg(pModConf, NULL);
+	for(inst = pModConf->root ; inst != NULL ; inst = inst->next) {
+		if(inst->pszBindRuleset == NULL && pModConf->pszBindRuleset != NULL) {
+			CHKmalloc(inst->pszBindRuleset = ustrdup(pModConf->pszBindRuleset));
 		}
-		CHKiRet(localRet);
-		pModConf->pBindRuleset = pRuleset;
+		std_checkRuleset(pModConf, inst);
 	}
 finalize_it:
 ENDcheckCnf
@@ -311,8 +392,10 @@ CODESTARTactivateCnfPrePrivDrop
 	for(inst = runModConf->root ; inst != NULL ; inst = inst->next) {
 		addListner(pModConf, inst);
 	}
-	if(pRelpEngine == NULL)
+	if(pRelpEngine == NULL) {
+		errmsg.LogError(0, RS_RET_NO_LSTN_DEFINED, "imrelp: no RELP listener defined, module ca  n not run.");
 		ABORT_FINALIZE(RS_RET_NO_RUN);
+	}
 finalize_it:
 ENDactivateCnfPrePrivDrop
 
@@ -326,10 +409,12 @@ BEGINfreeCnf
 CODESTARTfreeCnf
 	for(inst = pModConf->root ; inst != NULL ; ) {
 		free(inst->pszBindPort);
+		free(inst->pszBindRuleset);
 		del = inst;
 		inst = inst->next;
 		free(del);
 	}
+	free(pModConf->pszBindRuleset);
 ENDfreeCnf
 
 /* This is used to terminate the plugin. Note that the signal handler blocks
@@ -420,6 +505,7 @@ CODEqueryEtryPt_STD_IMOD_QUERIES
 CODEqueryEtryPt_STD_CONF2_QUERIES
 CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES
 CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES
+CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES
 CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES
 ENDqueryEtryPt
 
@@ -437,8 +523,8 @@ CODEmodInit_QueryRegCFSLineHdlr
 	CHKiRet(objUse(ruleset, CORE_COMPONENT));
 
 	/* register config file handlers */
-	CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputrelpserverbindruleset", 0, eCmdHdlrGetWord,
-		NULL, &cs.pszBindRuleset, STD_LOADABLE_MODULE_ID));
+	CHKiRet(regCfSysLineHdlr2((uchar*)"inputrelpserverbindruleset", 0, eCmdHdlrGetWord,
+				   NULL, &cs.pszBindRuleset, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
 	CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputrelpserverrun", 0, eCmdHdlrGetWord,
 				   addInstance, NULL, STD_LOADABLE_MODULE_ID));
 	CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
-- 
2.5.5