logging: change ownership of application log if needed

When running with privilege dropping, the application log file
is opened before privileges are dropped resulting in Suricata
failing to re-open the file for file rotation.

If needed, chown the application to the run-as user/group after
opening.

Ticker #4523
pull/6854/head
Jason Ish 4 years ago committed by Victor Julien
parent 08518df373
commit 59ac1fe277

@ -1075,9 +1075,9 @@ static void SCInstanceInit(SCInstance *suri, const char *progname)
suri->group_name = NULL;
suri->do_setuid = FALSE;
suri->do_setgid = FALSE;
#endif /* OS_WIN32 */
suri->userid = 0;
suri->groupid = 0;
#endif /* OS_WIN32 */
suri->delayed_detect = 0;
suri->daemon = 0;
suri->offline = 0;
@ -2887,7 +2887,7 @@ int SuricataMain(int argc, char **argv)
/* Since our config is now loaded we can finish configurating the
* logging module. */
SCLogLoadConfig(suricata.daemon, suricata.verbose);
SCLogLoadConfig(suricata.daemon, suricata.verbose, suricata.userid, suricata.groupid);
LogVersion(&suricata);
UtilCpuPrintSummary();

@ -137,9 +137,9 @@ typedef struct SCInstance_ {
const char *group_name;
uint8_t do_setuid;
uint8_t do_setgid;
#endif /* OS_WIN32 */
uint32_t userid;
uint32_t groupid;
#endif /* OS_WIN32 */
bool system;
bool set_logdir;

@ -727,10 +727,8 @@ static inline SCLogOPIfaceCtx *SCLogAllocLogOPIfaceCtx(void)
* \retval iface_ctx Pointer to the file output interface context created
* \initonly
*/
static inline SCLogOPIfaceCtx *SCLogInitFileOPIface(const char *file,
const char *log_format,
int log_level,
SCLogOPType type)
static inline SCLogOPIfaceCtx *SCLogInitFileOPIface(const char *file, uint32_t userid,
uint32_t groupid, const char *log_format, int log_level, SCLogOPType type)
{
SCLogOPIfaceCtx *iface_ctx = SCLogAllocLogOPIfaceCtx();
@ -751,6 +749,15 @@ static inline SCLogOPIfaceCtx *SCLogInitFileOPIface(const char *file,
goto error;
}
#ifndef OS_WIN32
if (userid != 0 || groupid != 0) {
if (chown(file, userid, groupid) == -1) {
SCLogWarning(SC_WARN_CHOWN, "Failed to change ownership of file %s: %s", file,
strerror(errno));
}
}
#endif
if ((iface_ctx->file = SCStrdup(file)) == NULL) {
goto error;
}
@ -1070,11 +1077,11 @@ static inline void SCLogSetOPIface(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
if (s == NULL) {
char *str = SCLogGetLogFilename(SC_LOG_DEF_LOG_FILE);
if (str != NULL) {
op_ifaces_ctx = SCLogInitFileOPIface(str, NULL, SC_LOG_LEVEL_MAX,0);
op_ifaces_ctx = SCLogInitFileOPIface(str, 0, 0, NULL, SC_LOG_LEVEL_MAX, 0);
SCFree(str);
}
} else {
op_ifaces_ctx = SCLogInitFileOPIface(s, NULL, SC_LOG_LEVEL_MAX,0);
op_ifaces_ctx = SCLogInitFileOPIface(s, 0, 0, NULL, SC_LOG_LEVEL_MAX, 0);
}
break;
case SC_LOG_OP_IFACE_SYSLOG:
@ -1272,7 +1279,7 @@ SCLogOPIfaceCtx *SCLogInitOPIfaceCtx(const char *iface_name,
case SC_LOG_OP_IFACE_CONSOLE:
return SCLogInitConsoleOPIface(log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
case SC_LOG_OP_IFACE_FILE:
return SCLogInitFileOPIface(arg, log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
return SCLogInitFileOPIface(arg, 0, 0, log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
case SC_LOG_OP_IFACE_SYSLOG:
return SCLogInitSyslogOPIface(SCMapEnumNameToValue(arg, SCSyslogGetFacilityMap()),
log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
@ -1326,7 +1333,7 @@ void SCLogInitLogModule(SCLogInitData *sc_lid)
return;
}
void SCLogLoadConfig(int daemon, int verbose)
void SCLogLoadConfig(int daemon, int verbose, uint32_t userid, uint32_t groupid)
{
ConfNode *outputs;
SCLogInitData *sc_lid;
@ -1437,7 +1444,7 @@ void SCLogLoadConfig(int daemon, int verbose)
if (path == NULL)
FatalError(SC_ERR_FATAL, "failed to setup output to file");
have_logging = 1;
op_iface_ctx = SCLogInitFileOPIface(path, format, level, type);
op_iface_ctx = SCLogInitFileOPIface(path, userid, groupid, format, level, type);
SCFree(path);
}
else if (strcmp(output->name, "syslog") == 0) {

@ -573,7 +573,7 @@ int SCLogDebugEnabled(void);
void SCLogRegisterTests(void);
void SCLogLoadConfig(int daemon, int verbose);
void SCLogLoadConfig(int daemon, int verbose, uint32_t userid, uint32_t groupid);
SCLogLevel SCLogGetLogLevel(void);

@ -386,6 +386,7 @@ const char * SCErrorToString(SCError err)
CASE_CODE(SC_ERR_DPDK_CONF);
CASE_CODE(SC_WARN_DPDK_CONF);
CASE_CODE(SC_ERR_SIGNAL);
CASE_CODE(SC_WARN_CHOWN);
CASE_CODE (SC_ERR_MAX);
}

@ -376,6 +376,7 @@ typedef enum {
SC_ERR_DPDK_CONF,
SC_WARN_DPDK_CONF,
SC_ERR_SIGNAL,
SC_WARN_CHOWN,
SC_ERR_MAX
} SCError;

@ -31,7 +31,7 @@
int ListKeywords(const char *keyword_info)
{
SCLogLoadConfig(0, 0);
SCLogLoadConfig(0, 0, 0, 0);
MpmTableSetup();
SpmTableSetup();
AppLayerSetup();
@ -42,7 +42,7 @@ int ListKeywords(const char *keyword_info)
int ListAppLayerProtocols(const char *conf_filename)
{
if (ConfYamlLoadFile(conf_filename) != -1)
SCLogLoadConfig(0, 0);
SCLogLoadConfig(0, 0, 0, 0);
MpmTableSetup();
SpmTableSetup();
AppLayerSetup();

Loading…
Cancel
Save