Merge branch 'v5-devel'

Conflicts:
	tools/omfile.c
This commit is contained in:
Rainer Gerhards 2011-04-26 18:45:12 +02:00
commit df5c3b8cdd
5 changed files with 54 additions and 34 deletions

View File

@ -158,7 +158,15 @@ expected that interfaces, even new ones, break during the initial
[ported from v4]
---------------------------------------------------------------------------
Version 5.9.0 [V5-DEVEL] (rgerhards), 2011-03-??
- bugfix: do not open files with full privileges, if privs will be dropped
This make the privilege drop code more bulletproof, but breaks Ubuntu's
work-around for log files created by external programs with the wrong
user and/or group. Note that it was long said that this "functionality"
would break once we go for serious privilege drop code, so hopefully
nobody still depends on it (and, if so, they lost...).
- bugfix: pipes not opened in full priv mode when privs are to be dropped
- this begins a new devel branch for v5
- added support for user-level PRI provided via systemd
- added new config directive $InputTCPFlowControl to select if tcp
received messages shall be flagged as light delayable or not.
- enhanced omhdfs to support batching mode. This permits to increase

View File

@ -8,7 +8,10 @@
<h2>$omfileForceChown</h2>
<p><b>Type:</b> global configuration directive</p>
<p><b>Parameter Values:</b> boolean (on/off, yes/no)</p>
<p><b>Available since:</b> 4.7.0+, 5.3.0+</p>
<p><b>Available:</b> 4.7.0+, 5.3.0-5.8.x, <b>NOT</b> available in 5.9.x or higher</p>
<p><b>Note: this directive has been removed and is no longer available. The
documentation is currently being retained for historical reaons.</b> Expect
it to go away at some later stage as well.
<p><b>Default:</b> off</p>
<p><b>Description:</b></p>
<p>Forces rsyslogd to change the ownership for output files that already exist. Please note

View File

@ -186,12 +186,28 @@ rsRetVal imklogLogIntMsg(int priority, char *fmt, ...)
rsRetVal Syslog(int priority, uchar *pMsg)
{
DEFiRet;
int pri = -1;
rsRetVal localRet;
/* Output using syslog */
localRet = parsePRI(&pMsg, &priority);
if(localRet != RS_RET_INVALID_PRI && localRet != RS_RET_OK)
FINALIZE;
/* first check if we have two PRIs. This can happen in case of systemd,
* in which case the second PRI is the rigth one.
* TODO: added kernel timestamp support to this PoC. -- rgerhards, 2011-03-18
*/
if(pMsg[3] == '<') { /* could be a pri... */
uchar *pMsgTmp = pMsg + 3;
localRet = parsePRI(&pMsgTmp, &pri);
if(localRet == RS_RET_OK && pri >= 8 && pri <= 192) {
/* *this* is our PRI */
DBGPRINTF("imklog detected secondary PRI in klog msg\n");
pMsg = pMsgTmp;
priority = pri;
}
}
if(pri == -1) {
localRet = parsePRI(&pMsg, &priority);
if(localRet != RS_RET_INVALID_PRI && localRet != RS_RET_OK)
FINALIZE;
}
/* if we don't get the pri, we use whatever we were supplied */
/* ignore non-kernel messages if not permitted */

View File

@ -125,7 +125,6 @@ typedef struct s_dynaFileCacheEntry dynaFileCacheEntry;
#define USE_ASYNCWRITER_DFLT 0 /* default buffer use async writer */
#define FLUSHONTX_DFLT 1 /* default for flush on TX end */
#define DFLT_bForceChown 0
typedef struct _instanceData {
uchar f_fname[MAXFNAME];/* file or template name (display only) */
@ -136,7 +135,6 @@ typedef struct _instanceData {
int fDirCreateMode; /* creation mode for mkdir() */
int bCreateDirs; /* auto-create directories? */
int bSyncFile; /* should the file by sync()'ed? 1- yes, 0- no */
sbool bForceChown; /* force chown() on existing files? */
uid_t fileUID; /* IDs for creation */
uid_t dirUID;
gid_t fileGID;
@ -165,7 +163,6 @@ typedef struct configSettings_s {
int fCreateMode; /* mode to use when creating files */
int fDirCreateMode; /* mode to use when creating files */
int bFailOnChown; /* fail if chown fails? */
int bForceChown; /* Force chown() on existing files? */
uid_t fileUID; /* UID to be used for newly created files */
uid_t fileGID; /* GID to be used for newly created files */
uid_t dirUID; /* UID to be used for newly created directories */
@ -212,7 +209,6 @@ CODESTARTdbgPrintInstInfo
dbgprintf("\tfile cache size=%d\n", pData->iDynaFileCacheSize);
dbgprintf("\tcreate directories: %s\n", pData->bCreateDirs ? "yes" : "no");
dbgprintf("\tfile owner %d, group %d\n", (int) pData->fileUID, (int) pData->fileGID);
dbgprintf("\tforce chown() for all files: %s\n", pData->bForceChown ? "yes" : "no");
dbgprintf("\tdirectory owner %d, group %d\n", (int) pData->dirUID, (int) pData->dirGID);
dbgprintf("\tdir create mode 0%3.3o, file create mode 0%3.3o\n",
pData->fDirCreateMode, pData->fCreateMode);
@ -400,22 +396,7 @@ prepareFile(instanceData *pData, uchar *newFileName)
int fd;
DEFiRet;
if(access((char*)newFileName, F_OK) == 0) {
if(pData->bForceChown) {
/* Try to fix wrong ownership set by someone else. Note that this code
* will no longer work once we have made the $PrivDrop code fully secure.
* This change is based on an idea of Michael Terry, provided as part of
* the effort to make rsyslogd the Ubuntu default syslogd.
* rgerhards, 2009-09-11
*/
if(chown((char*)newFileName, pData->fileUID, pData->fileGID) != 0) {
if(pData->bFailOnChown) {
int eSave = errno;
errno = eSave;
}
}
}
} else {
if(access((char*)newFileName, F_OK) != 0) {
/* file does not exist, create it (and eventually parent directories */
if(pData->bCreateDirs) {
/* We first need to create parent dirs if they are missing.
@ -435,7 +416,7 @@ prepareFile(instanceData *pData, uchar *newFileName)
pData->fCreateMode);
if(fd != -1) {
/* check and set uid/gid */
if(pData->bForceChown || pData->fileUID != (uid_t)-1 || pData->fileGID != (gid_t) -1) {
if(pData->fileUID != (uid_t)-1 || pData->fileGID != (gid_t) -1) {
/* we need to set owner/group */
if(fchown(fd, pData->fileUID, pData->fileGID) != 0) {
if(pData->bFailOnChown) {
@ -485,6 +466,9 @@ prepareFile(instanceData *pData, uchar *newFileName)
CHKiRet(strm.ConstructFinalize(pData->pStrm));
finalize_it:
if(pData->pStrm == NULL) {
DBGPRINTF("Error opening log file: %s\n", pData->f_fname);
}
RETiRet;
}
@ -659,6 +643,9 @@ writeFile(uchar **ppString, unsigned iMsgOpts, instanceData *pData)
} else { /* "regular", non-dynafile */
if(pData->pStrm == NULL) {
CHKiRet(prepareFile(pData, pData->f_fname));
if(pData->pStrm == NULL) {
errmsg.LogError(0, RS_RET_NO_FILE_ACCESS, "Could no open output file '%s'", pData->f_fname);
}
}
}
@ -802,7 +789,6 @@ CODESTARTparseSelectorAct
pData->fDirCreateMode = cs.fDirCreateMode;
pData->bCreateDirs = cs.bCreateDirs;
pData->bFailOnChown = cs.bFailOnChown;
pData->bForceChown = cs.bForceChown;
pData->fileUID = cs.fileUID;
pData->fileGID = cs.fileGID;
pData->dirUID = cs.dirUID;
@ -838,7 +824,6 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a
cs.dirUID = -1;
cs.dirGID = -1;
cs.bFailOnChown = 1;
cs.bForceChown = DFLT_bForceChown;
cs.iDynaFileCacheSize = 10;
cs.fCreateMode = 0644;
cs.fDirCreateMode = 0700;
@ -912,7 +897,7 @@ SCOPINGmodInit
CHKiRet(omsdRegCFSLineHdlr((uchar *)"filecreatemode", 0, eCmdHdlrFileCreateMode, NULL, &cs.fCreateMode, STD_LOADABLE_MODULE_ID, eConfObjAction));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"createdirs", 0, eCmdHdlrBinary, NULL, &cs.bCreateDirs, STD_LOADABLE_MODULE_ID, eConfObjAction));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"failonchownfailure", 0, eCmdHdlrBinary, NULL, &cs.bFailOnChown, STD_LOADABLE_MODULE_ID, eConfObjAction));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileForceChown", 0, eCmdHdlrBinary, NULL, &cs.bForceChown, STD_LOADABLE_MODULE_ID, eConfObjAction));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileForceChown", 0, eCmdHdlrGoneAway, NULL, NULL, STD_LOADABLE_MODULE_ID, eConfObjAction));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionfileenablesync", 0, eCmdHdlrBinary, NULL, &cs.bEnableSync, STD_LOADABLE_MODULE_ID, eConfObjAction));
CHKiRet(regCfSysLineHdlr((uchar *)"actionfiledefaulttemplate", 0, eCmdHdlrGetWord, NULL, &cs.pszFileDfltTplName, NULL, eConfObjAction));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID, eConfObjAction));

View File

@ -72,6 +72,7 @@ DEFobjCurrIf(errmsg)
typedef struct _instanceData {
uchar f_fname[MAXFNAME];/* pipe or template name (display only) */
short fd; /* pipe descriptor for (current) pipe */
sbool bHadError; /* did we already have/report an error on this pipe? */
} instanceData;
typedef struct configSettings_s {
@ -111,6 +112,17 @@ preparePipe(instanceData *pData)
{
DEFiRet;
pData->fd = open((char*) pData->f_fname, O_RDWR|O_NONBLOCK|O_CLOEXEC);
if(pData->fd < 0 ) {
pData->fd = -1;
if(!pData->bHadError) {
char errStr[1024];
rs_strerror_r(errno, errStr, sizeof(errStr));
errmsg.LogError(0, RS_RET_NO_FILE_ACCESS, "Could no open output pipe '%s': %s",
pData->f_fname, errStr);
pData->bHadError = 1;
}
DBGPRINTF("Error opening log pipe: %s\n", pData->f_fname);
}
RETiRet;
}
@ -160,6 +172,7 @@ finalize_it:
BEGINcreateInstance
CODESTARTcreateInstance
pData->fd = -1;
pData->bHadError = 0;
ENDcreateInstance
@ -214,11 +227,6 @@ CODESTARTparseSelectorAct
*/
preparePipe(pData);
if(pData->fd < 0 ) {
pData->fd = -1;
DBGPRINTF("Error opening log pipe: %s\n", pData->f_fname);
errmsg.LogError(0, RS_RET_NO_FILE_ACCESS, "Could no open output pipe '%s'", pData->f_fname);
}
CODE_STD_FINALIZERparseSelectorAct
ENDparseSelectorAct