summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2007-07-17 12:53:50 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2007-07-17 12:53:50 +0000
commit648370956683f65c8d60ba71ca158bf68d27db9a (patch)
tree2786e35006a14c91c3164c458cf6e63ca07a8778
parent73e4c2a0c637a16b19a54a04b04625e94b3ee4eb (diff)
downloadrsyslog-648370956683f65c8d60ba71ca158bf68d27db9a.tar.gz
rsyslog-648370956683f65c8d60ba71ca158bf68d27db9a.tar.xz
rsyslog-648370956683f65c8d60ba71ca158bf68d27db9a.zip
added config directives: $FileOwner, $FileGroup, $DirOwner, $DirGroup
-rw-r--r--ChangeLog4
-rwxr-xr-xsrUtils.c20
-rwxr-xr-xsrUtils.h2
-rw-r--r--syslogd-types.h4
-rw-r--r--syslogd.c141
5 files changed, 152 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 80624cf4..291b90d7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,10 @@ Version 1.16.1 (RGer), 2007-07-17
- added $CreateDirs config parameter
- added $DebugPrintTemplateList config parameter
- added $ResetConfigVariables config parameter
+- added $FileOwner config parameter
+- added $FileGroup config parameter
+- added $DirOwner config parameter
+- added $DirGroup config parameter
- added regular expression support to the filter engine
thanks to Michel Samia for providing the patch!
- enhanced $AllowedSender functionality. Credits to mildew@gmail.com for
diff --git a/srUtils.c b/srUtils.c
index 686346cd..2b819ca5 100755
--- a/srUtils.c
+++ b/srUtils.c
@@ -111,11 +111,13 @@ uchar *srUtilStrDup(uchar *pOld, size_t len)
* Param "mode" holds the mode that all non-existing directories
* are to be created with.
*/
-int makeFileParentDirs(uchar *szFile, size_t lenFile, mode_t mode)
+int makeFileParentDirs(uchar *szFile, size_t lenFile, mode_t mode,
+ uid_t uid, gid_t gid)
{
uchar *p;
uchar *pszWork;
size_t len;
+ int bErr = 0;
assert(szFile != NULL);
assert(len > 0);
@@ -128,14 +130,26 @@ int makeFileParentDirs(uchar *szFile, size_t lenFile, mode_t mode)
if(*p == '/') {
/* temporarily terminate string, create dir and go on */
*p = '\0';
- if(access(pszWork, F_OK))
- if(mkdir(pszWork, mode) != 0) {
+ if(access(pszWork, F_OK)) {
+ if(mkdir(pszWork, mode) == 0) {
+ if(uid != -1 || gid != -1) {
+ /* we need to set owner/group */
+ if(chown(pszWork, uid, gid) != 0)
+ bErr = 1;
+ }
+ } else
+ bErr = 1;
+ if(bErr) {
int eSave = errno;
free(pszWork);
errno = eSave;
return -1;
}
+ }
*p = '/';
}
free(pszWork);
}
+/*
+ * vi:set ai:
+ */
diff --git a/srUtils.h b/srUtils.h
index 33fd2030..cf679272 100755
--- a/srUtils.h
+++ b/srUtils.h
@@ -59,5 +59,5 @@ unsigned char *srUtilStrDup(unsigned char *pOld, size_t len);
* for it.
* added 2007-07-17 by rgerhards
*/
-int makeFileParentDirs(uchar *szFile, size_t lenFile, mode_t mode);
+int makeFileParentDirs(uchar *szFile, size_t lenFile, mode_t mode, uid_t uid, gid_t gid);
#endif
diff --git a/syslogd-types.h b/syslogd-types.h
index 23dc706a..a803fc08 100644
--- a/syslogd-types.h
+++ b/syslogd-types.h
@@ -253,6 +253,10 @@ struct filed {
int fCreateMode; /* file creation mode for open() */
int fDirCreateMode; /* creation mode for mkdir() */
int bCreateDirs; /* auto-create directories? */
+ uid_t fileUID; /* IDs for creation */
+ uid_t dirUID;
+ gid_t fileGID;
+ gid_t dirGID;
int iCurrElt; /* currently active cache element (-1 = none) */
int iCurrCacheSize; /* currently cache size (1-based) */
int iDynaFileCacheSize; /* size of file handle cache */
diff --git a/syslogd.c b/syslogd.c
index b1fdcc31..d340ea44 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -153,6 +153,8 @@
#include <setjmp.h>
#include <stdarg.h>
#include <time.h>
+#include <pwd.h>
+#include <grp.h>
#define SYSLOG_NAMES
#include <sys/syslog.h>
@@ -638,7 +640,12 @@ static struct code FacNames[] = {
{NULL, -1},
};
+/* global variables for config file state */
static int Debug; /* debug flag - read-only after startup */
+static uid_t fileUID; /* UID to be used for newly created files */
+static uid_t fileGID; /* GID to be used for newly created files */
+static uid_t dirUID; /* UID to be used for newly created directories */
+static uid_t dirGID; /* GID to be used for newly created directories */
static int bDebugPrintTemplateList;/* output template list in debug mode? */
static int bCreateDirs; /* auto-create directories for dynaFiles: 0 - no, 1 - yes */
static int bDropMalPTRMsgs = 0;/* Drop messages which have malicious PTR records during DNS lookup */
@@ -649,6 +656,8 @@ static int logEveryMsg = 0;/* no repeat message processing - read-only after st
* 0 - suppress duplicate messages
* 1 - do NOT suppress duplicate messages
*/
+/* end global config file state variables */
+
static char LocalHostName[MAXHOSTNAMELEN+1];/* our hostname - read-only after startup */
static char *LocalDomain; /* our local domain name - read-only after startup */
static int *finet = NULL; /* Internet datagram sockets, first element is nbr of elements
@@ -679,7 +688,6 @@ static int Initialized = 0; /* set when we have initialized ourselves
extern int errno;
-
/* support for simple textual representatio of FIOP names
* rgerhards, 2005-09-27
*/
@@ -712,6 +720,10 @@ static char* getFIOPName(unsigned iFIOP)
*/
static void resetConfigVariables(void)
{
+ fileUID = -1;
+ fileGID = -1;
+ dirUID = -1;
+ dirGID = -1;
iDynaFileCacheSize = 10;
fCreateMode = 0644;
fDirCreateMode = 0644;
@@ -6248,21 +6260,44 @@ static int prepareDynFile(selector_t *f)
}
/* Ok, we finally can open the file */
- f->f_file = open((char*) newFileName, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY,
- f->f_un.f_file.fCreateMode);
-
- if(f->f_file == -1 && f->f_un.f_file.bCreateDirs) {
- /* on first failure, we try to create parent directories and then
- * retry the open. Only if that fails, we give up. We do not report
- * any errors here ourselfs but let the code fall through to error
- * handler below.
- */
- if(makeFileParentDirs(newFileName, strlen(newFileName),
- f->f_un.f_file.fDirCreateMode) == 0) {
- f->f_file = open((char*) newFileName, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY,
- f->f_un.f_file.fCreateMode);
+ if(access(newFileName, F_OK) == 0) {
+ /* file already exists */
+ f->f_file = open((char*) newFileName, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY,
+ f->f_un.f_file.fCreateMode);
+ } else {
+ /* file does not exist, create it (and eventually parent directories */
+ if(f->f_un.f_file.bCreateDirs) {
+ /* we fist need to create parent dirs if they are missing
+ * We do not report any errors here ourselfs but let the code
+ * fall through to error handler below.
+ */
+ if(makeFileParentDirs(newFileName, strlen(newFileName),
+ f->f_un.f_file.fDirCreateMode, f->f_un.f_file.dirUID,
+ f->f_un.f_file.dirGID) == 0) {
+ f->f_file = open((char*) newFileName, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY,
+ f->f_un.f_file.fCreateMode);
+ if(f->f_file != -1) {
+ /* check and set uid/gid */
+ if(f->f_un.f_file.fileUID != -1 || f->f_un.f_file.fileGID != -1) {
+ /* we need to set owner/group */
+ if(fchown(f->f_file, f->f_un.f_file.fileUID,
+ f->f_un.f_file.fileGID) != 0) {
+ /* we fail in this case - later we could
+ * possibly control this via a user-defined
+ * option.
+ */
+ int eSave = errno;
+ close(f->f_file);
+ f->f_file = -1;
+ errno = eSave;
+ }
+ }
+ }
+ }
}
}
+
+ /* file is either open now or an error state set */
if(f->f_file == -1) {
/* do not report anything if the message is an internally-generated
* message. Otherwise, we could run into a never-ending loop. The bad
@@ -7457,6 +7492,70 @@ static void doBinaryOptionLine(uchar **pp, int *pVal)
}
+/* extract a groupname and return its gid.
+ * rgerhards, 2007-07-17
+ */
+static void doGetGID(uchar **pp, gid_t *pGid)
+{
+ struct group *pgBuf;
+ struct group gBuf;
+ uchar szName[256];
+ uchar stringBuf[2048]; /* I hope this is large enough... */
+
+ assert(pp != NULL);
+ assert(*pp != NULL);
+ assert(pGid != NULL);
+
+ if(getSubString(pp, (char*) szName, sizeof(szName) / sizeof(uchar), ' ') != 0) {
+ logerror("could not extract group name");
+ return;
+ }
+
+ getgrnam_r(szName, &gBuf, stringBuf, sizeof(stringBuf), &pgBuf);
+
+ if(pgBuf == NULL) {
+ logerrorSz("ID for group '%s' could not be found or error", szName);
+ } else {
+ *pGid = pgBuf->gr_gid;
+ dprintf("gid %d obtained for group '%s'\n", *pGid, szName);
+ }
+
+ skipWhiteSpace(pp); /* skip over any whitespace */
+}
+
+
+/* extract a username and return its uid.
+ * rgerhards, 2007-07-17
+ */
+static void doGetUID(uchar **pp, uid_t *pUid)
+{
+ struct passwd *ppwBuf;
+ struct passwd pwBuf;
+ uchar szName[256];
+ uchar stringBuf[2048]; /* I hope this is large enough... */
+
+ assert(pp != NULL);
+ assert(*pp != NULL);
+ assert(pUid != NULL);
+
+ if(getSubString(pp, (char*) szName, sizeof(szName) / sizeof(uchar), ' ') != 0) {
+ logerror("could not extract user name");
+ return;
+ }
+
+ getpwnam_r(szName, &pwBuf, stringBuf, sizeof(stringBuf), &ppwBuf);
+
+ if(ppwBuf == NULL) {
+ logerrorSz("ID for user '%s' could not be found or error", szName);
+ } else {
+ *pUid = ppwBuf->pw_uid;
+ dprintf("uid %d obtained for user '%s'\n", *pUid, szName);
+ }
+
+ skipWhiteSpace(pp); /* skip over any whitespace */
+}
+
+
/* parse the control character escape prefix and store it.
* added 2007-07-17 by rgerhards
*/
@@ -7640,6 +7739,14 @@ void cfsysline(uchar *p)
doFileCreateModeUmaskLine(&p, DIR_FILECREATEMODE);
} else if(!strcasecmp((char*) szCmd, "umask")) {
doFileCreateModeUmaskLine(&p, DIR_UMASK);
+ } else if(!strcasecmp((char*) szCmd, "dirowner")) {
+ doGetUID(&p, &dirUID);
+ } else if(!strcasecmp((char*) szCmd, "dirgroup")) {
+ doGetGID(&p, &dirGID);
+ } else if(!strcasecmp((char*) szCmd, "fileowner")) {
+ doGetUID(&p, &fileUID);
+ } else if(!strcasecmp((char*) szCmd, "filegroup")) {
+ doGetGID(&p, &fileGID);
} else if(!strcasecmp((char*) szCmd, "dynafilecachesize")) {
doDynaFileCacheSizeLine(&p, DIR_DYNAFILECACHESIZE);
} else if(!strcasecmp((char*) szCmd, "repeatedmsgreduction")) {
@@ -8922,7 +9029,11 @@ static rsRetVal cfline(char *line, register selector_t *f)
f->f_un.f_file.iCurrElt = -1; /* no current element */
f->f_un.f_file.fCreateMode = fCreateMode; /* freeze current setting */
f->f_un.f_file.fDirCreateMode = fDirCreateMode; /* preserve current setting */
- f->f_un.f_file.bCreateDirs = bCreateDirs; /* preserve current setting */
+ f->f_un.f_file.bCreateDirs = bCreateDirs;
+ f->f_un.f_file.fileUID = fileUID;
+ f->f_un.f_file.fileGID = fileGID;
+ f->f_un.f_file.dirUID = dirUID;
+ f->f_un.f_file.dirGID = dirGID;
f->f_un.f_file.iDynaFileCacheSize = iDynaFileCacheSize; /* freeze current setting */
/* we now allocate the cache table. We use calloc() intentionally, as we
* need all pointers to be initialized to NULL pointers.