From: Jason Ish Date: Thu, 20 Jan 2022 18:08:33 +0000 (-0600) Subject: logging: change ownership of application log if needed X-Git-Tag: suricata-6.0.5~78 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e3638cfd04b16ef1cb49e83b9e633a9c95b953a2;p=thirdparty%2Fsuricata.git 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 (cherry picked from commit 59ac1fe277b0dc2fc2b6c1739c10eb58a0d48cba) --- diff --git a/src/suricata.c b/src/suricata.c index e85e1c9184..73bfe0a70a 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -1008,9 +1008,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; @@ -2804,7 +2804,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(); diff --git a/src/suricata.h b/src/suricata.h index 43bb8ab0c5..4b4eafee02 100644 --- a/src/suricata.h +++ b/src/suricata.h @@ -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; diff --git a/src/util-debug.c b/src/util-debug.c index 60322b95a9..4303f828cb 100644 --- a/src/util-debug.c +++ b/src/util-debug.c @@ -733,10 +733,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(); @@ -757,6 +755,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; } @@ -1076,11 +1083,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: @@ -1280,7 +1287,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); @@ -1334,7 +1341,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; @@ -1445,7 +1452,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) { diff --git a/src/util-debug.h b/src/util-debug.h index 8d92d8bf89..c14501bbbe 100644 --- a/src/util-debug.h +++ b/src/util-debug.h @@ -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); diff --git a/src/util-error.c b/src/util-error.c index 64b4555c33..b170d1ac8f 100644 --- a/src/util-error.c +++ b/src/util-error.c @@ -377,6 +377,7 @@ const char * SCErrorToString(SCError err) CASE_CODE (SC_ERR_PLUGIN); CASE_CODE(SC_ERR_LOG_OUTPUT); CASE_CODE(SC_ERR_RULE_INVALID_UTF8); + CASE_CODE(SC_WARN_CHOWN); CASE_CODE (SC_ERR_MAX); } diff --git a/src/util-error.h b/src/util-error.h index 54b320a07c..8b5edc27d3 100644 --- a/src/util-error.h +++ b/src/util-error.h @@ -367,6 +367,7 @@ typedef enum { SC_ERR_PLUGIN, SC_ERR_LOG_OUTPUT, SC_ERR_RULE_INVALID_UTF8, + SC_WARN_CHOWN, SC_ERR_MAX } SCError; diff --git a/src/util-running-modes.c b/src/util-running-modes.c index b4f52ea6da..7f1ab999ab 100644 --- a/src/util-running-modes.c +++ b/src/util-running-modes.c @@ -31,7 +31,7 @@ int ListKeywords(const char *keyword_info) { - SCLogLoadConfig(0, 0); + SCLogLoadConfig(0, 0, 0, 0); MpmTableSetup(); SpmTableSetup(); AppLayerSetup(); @@ -43,7 +43,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();