diff --git a/.gitignore b/.gitignore index 449a04a..63934f0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ -# epel8-playground (split configuration) -/proftpd-1.3.7rc4.tar.gz +# master/epel8-playground (split configuration) +/proftpd-1.3.7.tar.gz /v0.9.5.tar.gz -# master/f32/f31/epel8 (split configuration) +# f32/f31/epel8 (split configuration) /proftpd-1.3.6e.tar.gz /v0.9.5.tar.gz # el7 (monolithic configuration) diff --git a/0001-Move-definition-of-recvd_signal_flags-for-API-tests.patch b/0001-Move-definition-of-recvd_signal_flags-for-API-tests.patch deleted file mode 100644 index 58ff5fd..0000000 --- a/0001-Move-definition-of-recvd_signal_flags-for-API-tests.patch +++ /dev/null @@ -1,43 +0,0 @@ ---- a/contrib/mod_auth_otp/t/api/tests.h -+++ b/contrib/mod_auth_otp/t/api/tests.h -@@ -45,10 +45,10 @@ Suite *tests_get_base32_suite(void); - Suite *tests_get_hotp_suite(void); - Suite *tests_get_totp_suite(void); - --/* Temporary hack/placement for this variable, until we get to testing -- * the Signals API. -+/* Temporary hack/placement (in stubs.c) for this variable, -+ * until we get to testing the Signals API. - */ --unsigned int recvd_signal_flags; -+extern volatile unsigned int recvd_signal_flags; - - extern pool *auth_otp_pool; - extern int auth_otp_logfd; ---- a/tests/api/stubs.c -+++ b/tests/api/stubs.c -@@ -38,6 +38,8 @@ xaset_t *server_list = NULL; - - static cmd_rec *next_cmd = NULL; - -+volatile unsigned int recvd_signal_flags = 0; -+ - int tests_stubs_set_next_cmd(cmd_rec *cmd) { - next_cmd = cmd; - return 0; ---- a/tests/api/tests.h -+++ b/tests/api/tests.h -@@ -80,10 +80,10 @@ Suite *tests_get_misc_suite(void); - Suite *tests_get_json_suite(void); - Suite *tests_get_redis_suite(void); - --/* Temporary hack/placement for this variable, until we get to testing -- * the Signals API. -+/* Temporary hack/placement (in stubs.c) for this variable, -+ * until we get to testing the Signals API. - */ --unsigned int recvd_signal_flags; -+extern volatile unsigned int recvd_signal_flags; - - extern char ServerType; - extern int ServerUseReverseDNS; diff --git a/1056.patch b/1056.patch new file mode 100644 index 0000000..80295e6 --- /dev/null +++ b/1056.patch @@ -0,0 +1,83 @@ +From a3fcb5a27eca23c605aaa221590db1a9360655bb Mon Sep 17 00:00:00 2001 +From: TJ Saunders +Date: Tue, 21 Jul 2020 09:04:39 -0700 +Subject: [PATCH] Issue #1055: Revert back to using `$localstatedir`, as the + `$runstatedir` implementation is incomplete. + +--- + NEWS | 5 +++++ + RELEASE_NOTES | 5 +++++ + configure | 4 ++-- + configure.in | 4 ++-- + 4 files changed, 14 insertions(+), 4 deletions(-) + +diff --git a/NEWS b/NEWS +index 044df08b5..8e80e3244 100644 +--- a/NEWS ++++ b/NEWS +@@ -15,6 +15,11 @@ + where `N' is the issue number. + ----------------------------------------------------------------------------- + ++1.3.7a - Released 21-Jul-2020 ++-------------------------------- ++- Issue 1055 - Fix build-time regression when using the --localstatedir ++ configure option. ++ + 1.3.7 - Released 20-Jul-2020 + -------------------------------- + - Issue 1027 - mod_ldap crashes at ldap_mod_init(). +diff --git a/RELEASE_NOTES b/RELEASE_NOTES +index 8ea1cb244..5b4363920 100644 +--- a/RELEASE_NOTES ++++ b/RELEASE_NOTES +@@ -6,6 +6,11 @@ This file contains a description of the major changes to ProFTPD for the + releases. More information on these changes can be found in the NEWS and + ChangeLog files. + ++1.3.7a ++--------- ++ ++ + Fix build-time regression when using the --localstatedir configure option. ++ + 1.3.7 + --------- + +diff --git a/configure b/configure +index 707888b5c..0a516705b 100755 +--- a/configure ++++ b/configure +@@ -25116,7 +25116,7 @@ _ACEOF + + + cat >>confdefs.h <<_ACEOF +-#define PR_RUN_DIR "`eval echo "${runstatedir}"`" ++#define PR_RUN_DIR "`eval echo "${localstatedir}"`" + _ACEOF + + +@@ -25126,7 +25126,7 @@ _ACEOF + + + cat >>confdefs.h <<_ACEOF +-#define PR_PID_FILE_PATH "`eval echo "${runstatedir}/proftpd.pid"`" ++#define PR_PID_FILE_PATH "`eval echo "${localstatedir}/proftpd.pid"`" + _ACEOF + + +diff --git a/configure.in b/configure.in +index a8ce7389d..50561de9c 100644 +--- a/configure.in ++++ b/configure.in +@@ -4058,9 +4058,9 @@ locale_dir="`eval echo ${localedir}`" + locale_dir="`eval echo ${locale_dir}`" + AC_DEFINE_UNQUOTED(PR_LOCALE_DIR, "`eval echo "${locale_dir}"`", [Define the locale directory]) + +-AC_DEFINE_UNQUOTED(PR_RUN_DIR, "`eval echo "${runstatedir}"`", [Define the run directory]) ++AC_DEFINE_UNQUOTED(PR_RUN_DIR, "`eval echo "${localstatedir}"`", [Define the run directory]) + AC_DEFINE_UNQUOTED(PR_CONFIG_FILE_PATH, "`eval echo "${sysconfdir}/proftpd.conf"`", [Define the configuration file path]) +-AC_DEFINE_UNQUOTED(PR_PID_FILE_PATH, "`eval echo "${runstatedir}/proftpd.pid"`", [Define the PID file path]) ++AC_DEFINE_UNQUOTED(PR_PID_FILE_PATH, "`eval echo "${localstatedir}/proftpd.pid"`", [Define the PID file path]) + + prefix="$pr_saved_prefix" + exec_prefix="$pr_saved_exec_prefix" diff --git a/proftpd-1.3.6-ENOATTR.patch b/proftpd-1.3.6-ENOATTR.patch deleted file mode 100644 index 18e3bf7..0000000 --- a/proftpd-1.3.6-ENOATTR.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- proftpd-1.3.6/tests/api/fsio.c -+++ proftpd-1.3.6/tests/api/fsio.c -@@ -26,6 +26,12 @@ - - #include "tests.h" - -+#ifdef PR_USE_XATTR -+#ifndef ENOATTR -+# define ENOATTR ENODATA -+#endif -+#endif -+ - static pool *p = NULL; - - static char *fsio_cwd = NULL; diff --git a/proftpd-1.3.6c-logging-not-systemd.patch b/proftpd-1.3.6c-logging-not-systemd.patch deleted file mode 100644 index c7bd00b..0000000 --- a/proftpd-1.3.6c-logging-not-systemd.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- proftpd.conf -+++ proftpd.conf -@@ -114,9 +114,6 @@ UseSendfile off - LogFormat default "%h %l %u %t \"%r\" %s %b" - LogFormat auth "%v [%P] %h %t \"%r\" %s" - --# Don't log hostname or timestamps because systemd will do that for us --LogOptions -Timestamp -Hostname +RoleBasedProcessLabels -- - # Enable basic controls via ftpdctl - # (http://www.proftpd.org/docs/modules/mod_ctrls.html) - ControlsEngine on diff --git a/proftpd-1.3.6c-logoptions.patch b/proftpd-1.3.6c-logoptions.patch deleted file mode 100644 index 9c23d84..0000000 --- a/proftpd-1.3.6c-logoptions.patch +++ /dev/null @@ -1,1599 +0,0 @@ ---- doc/modules/mod_core.html -+++ doc/modules/mod_core.html -@@ -2970,9 +2970,11 @@ adding/remove certain fields of data. - The options supported by the TraceOptions directive are: - --These options are all disabled by default. -+The Timestamp option is enabled by default; the others -+are disabled by default. - -

- To enable an option, preface the option name with a '+' (plus) character; ---- doc/modules/mod_log.html -+++ doc/modules/mod_log.html -@@ -21,6 +21,7 @@ ProFTPD 1.3.x, and is compiled by -

  • AllowLogSymlinks -
  • ExtendedLog -
  • LogFormat -+
  • LogOptions -
  • ServerLog -
  • SystemLog - -@@ -475,6 +476,58 @@ See also: E - -

    -


    -+

    LogOptions

    -+Syntax: LogOptions opt1 ... optN
    -+Default: None
    -+Context: server config, <VirtualHost>, <Global>
    -+Module: mod_core
    -+Compatibility: 1.3.7rc4 and later -+ -+

    -+The LogOptions directive can be used to change the format -+of the SystemLog messages, e.g. -+adding/remove certain fields of data. These options also apply to -+all module logging; ProFTPD logging is centralized, and the -+LogOptions are applied to any/all logging. -+ -+

    -+The options supported by the LogOptions directive are: -+

      -+
    • Hostname -+
    • RoleBasedProcessLabels -+
    • Timestamp -+
    • VirtualHost -+
    -+All of these options are enabled by default, except for the -+RoleBasedProcessLabels option. -+ -+

    -+To enable an option, preface the option name with a '+' (plus) character; -+to disable the option, use a '-' (minus) character prefix. For example: -+

    -+  # Log messages without timestamps or hostname
    -+  LogOptions -Hostname -Timestamp
    -+
    -+ -+

    -+The RoleBasedProcessLabels option changes the label -+just for the PID, from e.g.: -+

    -+  proftpd[1234]
    -+
    -+to one of the following, depending on whether the process is the master -+daemon process, or a forked session process: -+
    -+  daemon[2345]
    -+  session[34567]
    -+
    -+This is useful, for example, when relying on systemd logging: -+
    -+  LogOptions -Timestamp -Hostname +RoleBasedProcessLabels
    -+
    -+ -+

    -+


    -

    ServerLog

    - Syntax: ServerLog path|"none"
    - Default: None
    ---- include/log.h -+++ include/log.h -@@ -2,7 +2,7 @@ - * ProFTPD - FTP server daemon - * Copyright (c) 1997, 1998 Public Flood Software - * Copyright (c) 1999, 2000 MacGyver aka Habeeb J. Dihu -- * Copyright (c) 2001-2016 The ProFTPD Project team -+ * Copyright (c) 2001-2020 The ProFTPD Project team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -99,7 +99,6 @@ - # endif - #endif - -- - int log_lastlog(uid_t uid, const char *user_name, const char *tty, - const pr_netaddr_t *remote_addr); - #endif /* PR_USE_LASTLOG */ -@@ -224,4 +223,12 @@ int pr_log_event_listening(unsigned int - */ - void pr_log_stacktrace(int fd, const char *name); - -+/* Set options that affect the format of the logged messages. */ -+int pr_log_set_options(unsigned long log_opts); -+#define PR_LOG_OPT_USE_TIMESTAMP 0x0001 -+#define PR_LOG_OPT_USE_HOSTNAME 0x0002 -+#define PR_LOG_OPT_USE_VHOST 0x0004 -+#define PR_LOG_OPT_USE_ROLE_BASED_PROCESS_LABELS 0x0008 -+#define PR_LOG_OPT_DEFAULT (PR_LOG_OPT_USE_TIMESTAMP|PR_LOG_OPT_USE_HOSTNAME|PR_LOG_OPT_USE_VHOST) -+ - #endif /* PR_LOG_H */ ---- include/trace.h -+++ include/trace.h -@@ -1,6 +1,6 @@ - /* - * ProFTPD - FTP server daemon -- * Copyright (c) 2006-2016 The ProFTPD Project team -+ * Copyright (c) 2006-2020 The ProFTPD Project team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -50,8 +50,9 @@ int pr_trace_use_stderr(int); - - int pr_trace_set_options(unsigned long trace_opts); - #define PR_TRACE_OPT_LOG_CONN_IPS 0x0001 --#define PR_TRACE_OPT_USE_TIMESTAMP_MILLIS 0x0002 --#define PR_TRACE_OPT_DEFAULT PR_TRACE_OPT_USE_TIMESTAMP_MILLIS -+#define PR_TRACE_OPT_USE_TIMESTAMP 0x0002 -+#define PR_TRACE_OPT_USE_TIMESTAMP_MILLIS 0x0004 -+#define PR_TRACE_OPT_DEFAULT (PR_TRACE_OPT_USE_TIMESTAMP|PR_TRACE_OPT_USE_TIMESTAMP_MILLIS) - - int pr_trace_msg(const char *, int, const char *, ...) - #ifdef __GNUC__ ---- modules/mod_core.c -+++ modules/mod_core.c -@@ -1675,7 +1675,7 @@ MODRET set_traceoptions(cmd_rec *cmd) { - - opt++; - -- if (strncasecmp(opt, "ConnIPs", 8) == 0) { -+ if (strcasecmp(opt, "ConnIPs") == 0) { - switch (action) { - case '-': - trace_opts &= ~PR_TRACE_OPT_LOG_CONN_IPS; -@@ -1686,7 +1686,18 @@ MODRET set_traceoptions(cmd_rec *cmd) { - break; - } - -- } else if (strncasecmp(opt, "TimestampMillis", 16) == 0) { -+ } else if (strcasecmp(opt, "Timestamp") == 0) { -+ switch (action) { -+ case '-': -+ trace_opts &= ~PR_TRACE_OPT_USE_TIMESTAMP; -+ break; -+ -+ case '+': -+ trace_opts |= PR_TRACE_OPT_USE_TIMESTAMP; -+ break; -+ } -+ -+ } else if (strcasecmp(opt, "TimestampMillis") == 0) { - switch (action) { - case '-': - trace_opts &= ~PR_TRACE_OPT_USE_TIMESTAMP_MILLIS; ---- modules/mod_log.c -+++ modules/mod_log.c -@@ -507,6 +507,104 @@ MODRET set_logformat(cmd_rec *cmd) { - return PR_HANDLED(cmd); - } - -+/* usage: LogOptions opt1 ... */ -+MODRET set_logoptions(cmd_rec *cmd) { -+ register unsigned int i; -+ int ctx; -+ unsigned long log_opts = PR_LOG_OPT_DEFAULT; -+ config_rec *c; -+ -+ if (cmd->argc < 2) { -+ CONF_ERROR(cmd, "wrong number of parameters"); -+ } -+ -+ CHECK_CONF(cmd, CONF_ROOT|CONF_GLOBAL|CONF_VIRTUAL); -+ -+ for (i = 1; i < cmd->argc; i++) { -+ char action, *opt; -+ -+ opt = cmd->argv[i]; -+ action = *opt; -+ -+ if (action != '+' && -+ action != '-') { -+ CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "bad LogOption: '", opt, "'", -+ NULL)); -+ } -+ -+ opt++; -+ -+ if (strcasecmp(opt, "Timestamp") == 0) { -+ switch (action) { -+ case '-': -+ log_opts &= ~PR_LOG_OPT_USE_TIMESTAMP; -+ break; -+ -+ case '+': -+ log_opts |= PR_LOG_OPT_USE_TIMESTAMP; -+ break; -+ } -+ -+ } else if (strcasecmp(opt, "Hostname") == 0) { -+ switch (action) { -+ case '-': -+ log_opts &= ~PR_LOG_OPT_USE_HOSTNAME; -+ break; -+ -+ case '+': -+ log_opts |= PR_LOG_OPT_USE_HOSTNAME; -+ break; -+ } -+ -+ } else if (strcasecmp(opt, "VirtualHost") == 0) { -+ switch (action) { -+ case '-': -+ log_opts &= ~PR_LOG_OPT_USE_VHOST; -+ break; -+ -+ case '+': -+ log_opts |= PR_LOG_OPT_USE_VHOST; -+ break; -+ } -+ -+ } else if (strcasecmp(opt, "RoleBasedProcessLabels") == 0) { -+ switch (action) { -+ case '-': -+ log_opts &= ~PR_LOG_OPT_USE_ROLE_BASED_PROCESS_LABELS; -+ break; -+ -+ case '+': -+ log_opts |= PR_LOG_OPT_USE_ROLE_BASED_PROCESS_LABELS; -+ break; -+ } -+ -+ } else { -+ CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "unknown LogOption: '", -+ opt, "'", NULL)); -+ } -+ } -+ -+ c = add_config_param(cmd->argv[0], 1, NULL); -+ c->argv[0] = palloc(c->pool, sizeof(unsigned long)); -+ *((unsigned long *) c->argv[0]) = log_opts; -+ -+ ctx = (cmd->config && cmd->config->config_type != CONF_PARAM ? -+ cmd->config->config_type : cmd->server->config_type ? -+ cmd->server->config_type : CONF_ROOT); -+ -+ if (ctx == CONF_ROOT) { -+ /* If we're the "server config" context, set the LogOptions here, -+ * too. This will apply these LogOptions to the daemon process. -+ */ -+ if (pr_log_set_options(log_opts) < 0) { -+ pr_log_debug(DEBUG6, "%s: error setting LogOptions (%lu): %s", -+ (char *) cmd->argv[0], log_opts, strerror(errno)); -+ } -+ } -+ -+ return PR_HANDLED(cmd); -+} -+ - static int parse_classes(char *s, int *incl_classes, int *excl_classes) { - int incl = CL_NONE, excl = CL_NONE; - char *nextp = NULL; -@@ -2224,6 +2322,9 @@ static void log_sess_reinit_ev(const voi - } - } - -+ /* Restore original LogOptions settings. */ -+ (void) pr_log_set_options(PR_LOG_OPT_DEFAULT); -+ - res = log_sess_init(); - if (res < 0) { - pr_session_disconnect(&log_module, -@@ -2463,12 +2564,24 @@ MODRET log_post_pass(cmd_rec *cmd) { - - /* Open all the log files */ - static int log_sess_init(void) { -+ config_rec *c; - char *serverlog_name = NULL; - logfile_t *lf = NULL; - - pr_event_register(&log_module, "core.session-reinit", log_sess_reinit_ev, - NULL); - -+ c = find_config(main_server->conf, CONF_PARAM, "LogOptions", FALSE); -+ if (c != NULL) { -+ unsigned long log_opts; -+ -+ log_opts = *((unsigned long *) c->argv[0]); -+ if (pr_log_set_options(log_opts) < 0) { -+ pr_log_debug(DEBUG6, "%s: error setting LogOptions (%lu): %s", -+ c->name, log_opts, strerror(errno)); -+ } -+ } -+ - /* Open the ServerLog, if present. */ - serverlog_name = get_param_ptr(main_server->conf, "ServerLog", FALSE); - if (serverlog_name != NULL) { -@@ -2612,6 +2725,7 @@ static conftable log_conftab[] = { - { "AllowLogSymlinks", set_allowlogsymlinks, NULL }, - { "ExtendedLog", set_extendedlog, NULL }, - { "LogFormat", set_logformat, NULL }, -+ { "LogOptions", set_logoptions, NULL }, - { "ServerLog", set_serverlog, NULL }, - { "SystemLog", set_systemlog, NULL }, - { NULL, NULL, NULL } ---- src/ftpdctl.c -+++ src/ftpdctl.c -@@ -35,6 +35,7 @@ static const char *program = "ftpdctl"; - - /* NOTE: these empty stubs are needed for proper linking. What a mess. */ - -+unsigned char is_master; - session_t session; - server_rec *main_server = NULL; - ---- src/log.c -+++ src/log.c -@@ -34,8 +34,12 @@ - - #define LOGBUFFER_SIZE (PR_TUNABLE_PATH_MAX * 4) - -+/* From src/main.c */ -+extern unsigned char is_master; -+ - static int syslog_open = FALSE; - static int syslog_discard = FALSE; -+static unsigned long log_opts = PR_LOG_OPT_DEFAULT; - static int logstderr = TRUE; - static int debug_level = DEBUG0; - static int default_level = PR_LOG_NOTICE; -@@ -483,23 +487,24 @@ static void log_write(int priority, int - main_server->ServerFQDN) { - const pr_netaddr_t *remote_addr; - const char *remote_name; -+ size_t buflen = 0; - - remote_addr = pr_netaddr_get_sess_remote_addr(); - remote_name = pr_netaddr_get_sess_remote_name(); - -- snprintf(serverinfo, sizeof(serverinfo)-1, "%s", main_server->ServerFQDN); -+ if (log_opts & PR_LOG_OPT_USE_VHOST) { -+ snprintf(serverinfo, sizeof(serverinfo)-1, "%s", -+ main_server->ServerFQDN); -+ buflen += strlen(serverinfo); -+ } -+ - serverinfo[sizeof(serverinfo)-1] = '\0'; - - if (remote_addr != NULL && - remote_name != NULL) { -- size_t serverinfo_len; -- -- serverinfo_len = strlen(serverinfo); -- -- snprintf(serverinfo + serverinfo_len, -- sizeof(serverinfo) - serverinfo_len, " (%s[%s])", -+ snprintf(serverinfo + buflen, sizeof(serverinfo) - buflen, -+ "%s(%s[%s])", (log_opts & PR_LOG_OPT_USE_VHOST) ? " " : "", - remote_name, pr_netaddr_get_ipstr(remote_addr)); -- - serverinfo[sizeof(serverinfo)-1] = '\0'; - } - } -@@ -507,37 +512,63 @@ static void log_write(int priority, int - if (!discard && - (logstderr || !main_server)) { - char buf[LOGBUFFER_SIZE] = {'\0'}; -- size_t buflen, len; -- struct timeval now; -- struct tm *tm = NULL; -- unsigned long millis; -- -- gettimeofday(&now, NULL); -- tm = pr_localtime(NULL, (const time_t *) &(now.tv_sec)); -- if (tm == NULL) { -- return; -+ size_t buflen = 0, len = 0; -+ pid_t log_pid; -+ const char *process_label = "proftpd"; -+ -+ if (log_opts & PR_LOG_OPT_USE_TIMESTAMP) { -+ pool *tmp_pool; -+ struct timeval now; -+ struct tm *tm = NULL; -+ unsigned long millis; -+ -+ tmp_pool = make_sub_pool(permanent_pool); -+ pr_pool_tag(tmp_pool, "Log message pool"); -+ -+ gettimeofday(&now, NULL); -+ tm = pr_localtime(tmp_pool, (const time_t *) &(now.tv_sec)); -+ if (tm == NULL) { -+ destroy_pool(tmp_pool); -+ return; -+ } -+ -+ len = strftime(buf, sizeof(buf)-1, "%Y-%m-%d %H:%M:%S", tm); -+ buflen = len; -+ buf[sizeof(buf)-1] = '\0'; -+ destroy_pool(tmp_pool); -+ -+ /* Convert microsecs to millisecs. */ -+ millis = now.tv_usec / 1000; -+ -+ len = snprintf(buf + buflen, sizeof(buf) - len, ",%03lu ", millis); -+ buflen += len; - } - -- len = strftime(buf, sizeof(buf)-1, "%Y-%m-%d %H:%M:%S", tm); -- buflen = len; -- buf[sizeof(buf)-1] = '\0'; -+ if (log_opts & PR_LOG_OPT_USE_HOSTNAME) { -+ len = snprintf(buf + buflen, sizeof(buf) - buflen, "%s ", -+ systemlog_host); -+ buflen += len; -+ } - -- /* Convert microsecs to millisecs. */ -- millis = now.tv_usec / 1000; -+ log_pid = session.pid ? session.pid : getpid(); - -- len = snprintf(buf + buflen, sizeof(buf) - len, ",%03lu ", millis); -- buflen += len; -- buf[sizeof(buf)-1] = '\0'; -+ if (log_opts & PR_LOG_OPT_USE_ROLE_BASED_PROCESS_LABELS) { -+ if (is_master) { -+ process_label = "daemon"; -+ -+ } else { -+ process_label = "session"; -+ } -+ } - - if (*serverinfo) { - len = snprintf(buf + buflen, sizeof(buf) - buflen, -- "%s proftpd[%u] %s: %s\n", systemlog_host, -- (unsigned int) (session.pid ? session.pid : getpid()), serverinfo, s); -+ "%s[%u] %s: %s\n", process_label, (unsigned int) log_pid, serverinfo, -+ s); - - } else { - len = snprintf(buf + buflen, sizeof(buf) - buflen, -- "%s proftpd[%u]: %s\n", systemlog_host, -- (unsigned int) (session.pid ? session.pid : getpid()), s); -+ "%s[%u]: %s\n", process_label, (unsigned int) log_pid, s); - } - - buflen += len; -@@ -588,37 +619,65 @@ static void log_write(int priority, int - - if (systemlog_fd != -1) { - char buf[LOGBUFFER_SIZE] = {'\0'}; -- size_t buflen, len; -- struct timeval now; -- struct tm *tm; -- unsigned long millis; -- -- gettimeofday(&now, NULL); -- tm = pr_localtime(NULL, (const time_t *) &(now.tv_sec)); -- if (tm == NULL) { -- return; -+ size_t buflen = 0, len = 0; -+ pid_t log_pid; -+ const char *process_label = "proftpd"; -+ -+ if (log_opts & PR_LOG_OPT_USE_TIMESTAMP) { -+ pool *tmp_pool; -+ struct timeval now; -+ struct tm *tm; -+ unsigned long millis; -+ -+ tmp_pool = make_sub_pool(permanent_pool); -+ pr_pool_tag(tmp_pool, "Log message pool"); -+ -+ gettimeofday(&now, NULL); -+ tm = pr_localtime(tmp_pool, (const time_t *) &(now.tv_sec)); -+ if (tm == NULL) { -+ destroy_pool(tmp_pool); -+ return; -+ } -+ -+ len = strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm); -+ buflen = len; -+ buf[sizeof(buf) - 1] = '\0'; -+ destroy_pool(tmp_pool); -+ -+ /* Convert microsecs to millisecs. */ -+ millis = now.tv_usec / 1000; -+ -+ len = snprintf(buf + buflen, sizeof(buf) - len, ",%03lu ", millis); -+ buflen += len; - } - -- len = strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm); -- buflen = len; - buf[sizeof(buf) - 1] = '\0'; - -- /* Convert microsecs to millisecs. */ -- millis = now.tv_usec / 1000; -+ if (log_opts & PR_LOG_OPT_USE_HOSTNAME) { -+ len = snprintf(buf + buflen, sizeof(buf) - buflen, "%s ", -+ systemlog_host); -+ buflen += len; -+ } - -- len = snprintf(buf + buflen, sizeof(buf) - len, ",%03lu ", millis); -- buflen += len; -- buf[sizeof(buf) - 1] = '\0'; -+ log_pid = session.pid ? session.pid : getpid(); -+ -+ if (log_opts & PR_LOG_OPT_USE_ROLE_BASED_PROCESS_LABELS) { -+ if (is_master) { -+ process_label = "daemon"; -+ -+ } else { -+ process_label = "session"; -+ } -+ } - - if (*serverinfo) { - len = snprintf(buf + buflen, sizeof(buf) - buflen, -- "%s proftpd[%u] %s: %s\n", systemlog_host, -- (unsigned int) (session.pid ? session.pid : getpid()), serverinfo, s); -+ "%s[%u] %s: %s\n", process_label, (unsigned int) log_pid, serverinfo, -+ s); - - } else { - len = snprintf(buf + buflen, sizeof(buf) - buflen, -- "%s proftpd[%u]: %s\n", systemlog_host, -- (unsigned int) (session.pid ? session.pid : getpid()), s); -+ "%s[%u]: %s\n", process_label, (unsigned int) log_pid, s); - } - - buflen += len; -@@ -744,6 +803,11 @@ int pr_log_setdefaultlevel(int level) { - return old_level; - } - -+int pr_log_set_options(unsigned long opts) { -+ log_opts = opts; -+ return 0; -+} -+ - /* Convert a string into the matching syslog level value. Return -1 - * if no matching level is found. - */ ---- src/trace.c -+++ src/trace.c -@@ -93,7 +93,7 @@ static void trace_restart_ev(const void - static int trace_write(const char *channel, int level, const char *msg, - int discard) { - char buf[PR_TUNABLE_BUFFER_SIZE * 2]; -- size_t buflen, len; -+ size_t buflen = 0, len = 0; - struct tm *tm; - int use_conn_ips = FALSE; - -@@ -103,31 +103,32 @@ static int trace_write(const char *chann - - memset(buf, '\0', sizeof(buf)); - -- if (!(trace_opts & PR_TRACE_OPT_USE_TIMESTAMP_MILLIS)) { -- time_t now; -+ if (trace_opts & PR_TRACE_OPT_USE_TIMESTAMP) { -+ if (trace_opts & PR_TRACE_OPT_USE_TIMESTAMP_MILLIS) { -+ struct timeval now; -+ unsigned long millis; - -- now = time(NULL); -- tm = pr_localtime(NULL, &now); -+ gettimeofday(&now, NULL); -+ tm = pr_localtime(NULL, (const time_t *) &(now.tv_sec)); - -- len = strftime(buf, sizeof(buf)-1, "%Y-%m-%d %H:%M:%S", tm); -- buflen = len; -+ len = strftime(buf, sizeof(buf)-1, "%Y-%m-%d %H:%M:%S", tm); -+ buflen = len; - -- } else { -- struct timeval now; -- unsigned long millis; -- -- gettimeofday(&now, NULL); -+ /* Convert microsecs to millisecs. */ -+ millis = now.tv_usec / 1000; - -- tm = pr_localtime(NULL, (const time_t *) &(now.tv_sec)); -+ len = snprintf(buf + buflen, sizeof(buf) - buflen, ",%03lu ", millis); -+ buflen += len; - -- len = strftime(buf, sizeof(buf)-1, "%Y-%m-%d %H:%M:%S", tm); -- buflen = len; -+ } else { -+ time_t now; - -- /* Convert microsecs to millisecs. */ -- millis = now.tv_usec / 1000; -+ now = time(NULL); -+ tm = pr_localtime(NULL, &now); - -- len = snprintf(buf + buflen, sizeof(buf) - buflen, ",%03lu", millis); -- buflen += len; -+ len = strftime(buf, sizeof(buf)-1, "%Y-%m-%d %H:%M:%S ", tm); -+ buflen = len; -+ } - } - - if ((trace_opts & PR_TRACE_OPT_LOG_CONN_IPS) && -@@ -140,7 +141,7 @@ static int trace_write(const char *chann - } - - if (use_conn_ips == FALSE) { -- len = snprintf(buf + buflen, sizeof(buf) - buflen, " [%u] <%s:%d>: %s", -+ len = snprintf(buf + buflen, sizeof(buf) - buflen, "[%u] <%s:%d>: %s", - (unsigned int) (session.pid ? session.pid : getpid()), channel, level, - msg); - buflen += len; -@@ -154,7 +155,7 @@ static int trace_write(const char *chann - server_port = pr_netaddr_get_port(session.c->local_addr); - - len = snprintf(buf + buflen, sizeof(buf) - buflen, -- " [%u] (client %s, server %s:%d) <%s:%d>: %s", -+ "[%u] (client %s, server %s:%d) <%s:%d>: %s", - (unsigned int) (session.pid ? session.pid : getpid()), - client_ip != NULL ? client_ip : "none", - server_ip != NULL ? server_ip : "none", server_port, channel, level, msg); ---- tests/t/config/logoptions.t -+++ tests/t/config/logoptions.t -@@ -0,0 +1,11 @@ -+#!/usr/bin/env perl -+ -+use lib qw(t/lib); -+use strict; -+ -+use Test::Unit::HarnessUnit; -+ -+$| = 1; -+ -+my $r = Test::Unit::HarnessUnit->new(); -+$r->start("ProFTPD::Tests::Config::LogOptions"); ---- tests/tests.pl -+++ tests/tests.pl -@@ -140,6 +140,7 @@ if (scalar(@ARGV) > 0) { - t/config/ifdefine.t - t/config/include.t - t/config/listoptions.t -+ t/config/logoptions.t - t/config/loginpasswordprompt.t - t/config/masqueradeaddress.t - t/config/maxclients.t ---- tests/t/lib/ProFTPD/Tests/Config/LogOptions.pm -+++ tests/t/lib/ProFTPD/Tests/Config/LogOptions.pm -@@ -0,0 +1,452 @@ -+package ProFTPD::Tests::Config::LogOptions; -+ -+use lib qw(t/lib); -+use base qw(ProFTPD::TestSuite::Child); -+use strict; -+ -+use File::Spec; -+use IO::Handle; -+ -+use ProFTPD::TestSuite::FTP; -+use ProFTPD::TestSuite::Utils qw(:auth :config :running :test :testsuite); -+ -+$| = 1; -+ -+my $order = 0; -+ -+my $TESTS = { -+ logoptions_no_timestamp => { -+ order => ++$order, -+ test_class => [qw(forking)], -+ }, -+ -+ logoptions_no_hostname => { -+ order => ++$order, -+ test_class => [qw(forking)], -+ }, -+ -+ logoptions_no_virtualhost => { -+ order => ++$order, -+ test_class => [qw(forking)], -+ }, -+ -+ logoptions_use_rolebasedprocesslabels => { -+ order => ++$order, -+ test_class => [qw(forking)], -+ }, -+}; -+ -+sub new { -+ return shift()->SUPER::new(@_); -+} -+ -+sub list_tests { -+ return testsuite_get_runnable_tests($TESTS); -+} -+ -+sub logoptions_no_timestamp { -+ my $self = shift; -+ my $tmpdir = $self->{tmpdir}; -+ my $setup = test_setup($tmpdir, 'log'); -+ -+ my $config = { -+ PidFile => $setup->{pid_file}, -+ ScoreboardFile => $setup->{scoreboard_file}, -+ SystemLog => $setup->{log_file}, -+ -+ AuthUserFile => $setup->{auth_user_file}, -+ AuthGroupFile => $setup->{auth_group_file}, -+ -+ LogOptions => '-Timestamp', -+ -+ IfModules => { -+ 'mod_delay.c' => { -+ DelayEngine => 'off', -+ }, -+ }, -+ }; -+ -+ my ($port, $config_user, $config_group) = config_write($setup->{config_file}, -+ $config); -+ -+ # Open pipes, for use between the parent and child processes. Specifically, -+ # the child will indicate when it's done with its test by writing a message -+ # to the parent. -+ my ($rfh, $wfh); -+ unless (pipe($rfh, $wfh)) { -+ die("Can't open pipe: $!"); -+ } -+ -+ my $ex; -+ -+ # Fork child -+ $self->handle_sigchld(); -+ defined(my $pid = fork()) or die("Can't fork: $!"); -+ if ($pid) { -+ eval { -+ my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); -+ $client->login($setup->{user}, $setup->{passwd}); -+ $client->quit(); -+ }; -+ if ($@) { -+ $ex = $@; -+ } -+ -+ $wfh->print("done\n"); -+ $wfh->flush(); -+ -+ } else { -+ eval { server_wait($setup->{config_file}, $rfh) }; -+ if ($@) { -+ warn($@); -+ exit 1; -+ } -+ -+ exit 0; -+ } -+ -+ # Stop server -+ server_stop($setup->{pid_file}); -+ $self->assert_child_ok($pid); -+ -+ eval { -+ if (open(my $fh, "< $setup->{log_file}")) { -+ my $ok = 0; -+ -+ while (my $line = <$fh>) { -+ chomp($line); -+ -+ if ($ENV{TEST_VERBOSE}) { -+ print STDERR "# $line\n"; -+ } -+ -+ my $expected = '^\S+ proftpd\[\d+\] .*?$'; -+ -+ if ($line =~ /$expected/) { -+ $ok = 1; -+ last; -+ } -+ } -+ -+ close($fh); -+ -+ $self->assert($ok, test_msg("Missing expected LogOptions messages")); -+ -+ } else { -+ die("Can't read $setup->{log_file}: $!"); -+ } -+ }; -+ if ($@) { -+ $ex = $@; -+ } -+ -+ test_cleanup($setup->{log_file}, $ex); -+} -+ -+sub logoptions_no_hostname { -+ my $self = shift; -+ my $tmpdir = $self->{tmpdir}; -+ my $setup = test_setup($tmpdir, 'log'); -+ -+ my $config = { -+ PidFile => $setup->{pid_file}, -+ ScoreboardFile => $setup->{scoreboard_file}, -+ SystemLog => $setup->{log_file}, -+ -+ AuthUserFile => $setup->{auth_user_file}, -+ AuthGroupFile => $setup->{auth_group_file}, -+ -+ LogOptions => '-Hostname', -+ -+ IfModules => { -+ 'mod_delay.c' => { -+ DelayEngine => 'off', -+ }, -+ }, -+ }; -+ -+ my ($port, $config_user, $config_group) = config_write($setup->{config_file}, -+ $config); -+ -+ # Open pipes, for use between the parent and child processes. Specifically, -+ # the child will indicate when it's done with its test by writing a message -+ # to the parent. -+ my ($rfh, $wfh); -+ unless (pipe($rfh, $wfh)) { -+ die("Can't open pipe: $!"); -+ } -+ -+ my $ex; -+ -+ # Fork child -+ $self->handle_sigchld(); -+ defined(my $pid = fork()) or die("Can't fork: $!"); -+ if ($pid) { -+ eval { -+ my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); -+ $client->login($setup->{user}, $setup->{passwd}); -+ $client->quit(); -+ }; -+ if ($@) { -+ $ex = $@; -+ } -+ -+ $wfh->print("done\n"); -+ $wfh->flush(); -+ -+ } else { -+ eval { server_wait($setup->{config_file}, $rfh) }; -+ if ($@) { -+ warn($@); -+ exit 1; -+ } -+ -+ exit 0; -+ } -+ -+ # Stop server -+ server_stop($setup->{pid_file}); -+ $self->assert_child_ok($pid); -+ -+ eval { -+ if (open(my $fh, "< $setup->{log_file}")) { -+ my $ok = 0; -+ -+ while (my $line = <$fh>) { -+ chomp($line); -+ -+ if ($ENV{TEST_VERBOSE}) { -+ print STDERR "# $line\n"; -+ } -+ -+ my $expected = '^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3} proftpd\[\d+\] .*?$'; -+ -+ if ($line =~ /$expected/) { -+ my $pid = $1; -+ $ok = 1; -+ last; -+ } -+ } -+ -+ close($fh); -+ -+ $self->assert($ok, test_msg("Missing expected LogOptions messages")); -+ -+ } else { -+ die("Can't read $setup->{log_file}: $!"); -+ } -+ }; -+ if ($@) { -+ $ex = $@; -+ } -+ -+ test_cleanup($setup->{log_file}, $ex); -+} -+ -+sub logoptions_no_virtualhost { -+ my $self = shift; -+ my $tmpdir = $self->{tmpdir}; -+ my $setup = test_setup($tmpdir, 'log'); -+ -+ my $config = { -+ PidFile => $setup->{pid_file}, -+ ScoreboardFile => $setup->{scoreboard_file}, -+ SystemLog => $setup->{log_file}, -+ -+ AuthUserFile => $setup->{auth_user_file}, -+ AuthGroupFile => $setup->{auth_group_file}, -+ -+ LogOptions => '-VirtualHost', -+ -+ IfModules => { -+ 'mod_delay.c' => { -+ DelayEngine => 'off', -+ }, -+ }, -+ }; -+ -+ my ($port, $config_user, $config_group) = config_write($setup->{config_file}, -+ $config); -+ -+ # Open pipes, for use between the parent and child processes. Specifically, -+ # the child will indicate when it's done with its test by writing a message -+ # to the parent. -+ my ($rfh, $wfh); -+ unless (pipe($rfh, $wfh)) { -+ die("Can't open pipe: $!"); -+ } -+ -+ my $ex; -+ -+ # Fork child -+ $self->handle_sigchld(); -+ defined(my $pid = fork()) or die("Can't fork: $!"); -+ if ($pid) { -+ eval { -+ my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); -+ $client->login($setup->{user}, $setup->{passwd}); -+ $client->quit(); -+ }; -+ if ($@) { -+ $ex = $@; -+ } -+ -+ $wfh->print("done\n"); -+ $wfh->flush(); -+ -+ } else { -+ eval { server_wait($setup->{config_file}, $rfh) }; -+ if ($@) { -+ warn($@); -+ exit 1; -+ } -+ -+ exit 0; -+ } -+ -+ # Stop server -+ server_stop($setup->{pid_file}); -+ $self->assert_child_ok($pid); -+ -+ eval { -+ if (open(my $fh, "< $setup->{log_file}")) { -+ my $ok = 0; -+ -+ while (my $line = <$fh>) { -+ chomp($line); -+ -+ if ($ENV{TEST_VERBOSE}) { -+ print STDERR "# $line\n"; -+ } -+ -+ my $expected = '^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3} \S+ proftpd\[\d+\] \(.*?$'; -+ -+ if ($line =~ /$expected/) { -+ $ok = 1; -+ last; -+ } -+ } -+ -+ close($fh); -+ -+ $self->assert($ok, test_msg("Missing expected LogOptions messages")); -+ -+ } else { -+ die("Can't read $setup->{log_file}: $!"); -+ } -+ }; -+ if ($@) { -+ $ex = $@; -+ } -+ -+ test_cleanup($setup->{log_file}, $ex); -+} -+ -+sub logoptions_use_rolebasedprocesslabels { -+ my $self = shift; -+ my $tmpdir = $self->{tmpdir}; -+ my $setup = test_setup($tmpdir, 'log'); -+ -+ my $config = { -+ PidFile => $setup->{pid_file}, -+ ScoreboardFile => $setup->{scoreboard_file}, -+ SystemLog => $setup->{log_file}, -+ -+ AuthUserFile => $setup->{auth_user_file}, -+ AuthGroupFile => $setup->{auth_group_file}, -+ -+ LogOptions => '+RoleBasedProcessLabels', -+ -+ IfModules => { -+ 'mod_delay.c' => { -+ DelayEngine => 'off', -+ }, -+ }, -+ }; -+ -+ my ($port, $config_user, $config_group) = config_write($setup->{config_file}, -+ $config); -+ -+ # Open pipes, for use between the parent and child processes. Specifically, -+ # the child will indicate when it's done with its test by writing a message -+ # to the parent. -+ my ($rfh, $wfh); -+ unless (pipe($rfh, $wfh)) { -+ die("Can't open pipe: $!"); -+ } -+ my $ex; -+ # Fork child -+ $self->handle_sigchld(); -+ defined(my $pid = fork()) or die("Can't fork: $!"); -+ if ($pid) { -+ eval { -+ my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); -+ $client->login($setup->{user}, $setup->{passwd}); -+ $client->quit(); -+ }; -+ if ($@) { -+ $ex = $@; -+ } -+ -+ $wfh->print("done\n"); -+ $wfh->flush(); -+ -+ } else { -+ eval { server_wait($setup->{config_file}, $rfh) }; -+ if ($@) { -+ warn($@); -+ exit 1; -+ } -+ -+ exit 0; -+ } -+ -+ # Stop server -+ server_stop($setup->{pid_file}); -+ $self->assert_child_ok($pid); -+ -+ eval { -+ if (open(my $fh, "< $setup->{log_file}")) { -+ my $saw_daemon_label = 0; -+ my $saw_session_label = 0; -+ -+ while (my $line = <$fh>) { -+ chomp($line); -+ -+ if ($ENV{TEST_VERBOSE}) { -+ print STDERR "# $line\n"; -+ } -+ -+ my $expected = '^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3} \S+ daemon\[\d+\] '; -+ if ($line =~ /$expected/) { -+ $saw_daemon_label = 1; -+ } -+ -+ $expected = '^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3} \S+ session\[\d+\] '; -+ if ($line =~ /$expected/) { -+ $saw_session_label = 1; -+ } -+ -+ if ($saw_daemon_label == 1 && -+ $saw_session_label) { -+ last; -+ } -+ } -+ -+ close($fh); -+ -+ $self->assert($saw_daemon_label && $saw_session_label, -+ test_msg("Missing expected LogOptions messages")); -+ -+ } else { -+ die("Can't read $setup->{log_file}: $!"); -+ } -+ }; -+ if ($@) { -+ $ex = $@; -+ } -+ -+ test_cleanup($setup->{log_file}, $ex); -+} -+ -+1; ---- tests/t/lib/ProFTPD/Tests/Config/TraceOptions.pm -+++ tests/t/lib/ProFTPD/Tests/Config/TraceOptions.pm -@@ -24,6 +24,11 @@ my $TESTS = { - order => ++$order, - test_class => [qw(feature_trace forking)], - }, -+ -+ traceoptions_no_timestamp => { -+ order => ++$order, -+ test_class => [qw(feature_trace forking)], -+ }, - }; - - sub new { -@@ -37,51 +42,137 @@ sub list_tests { - sub traceoptions_conn_ips { - my $self = shift; - my $tmpdir = $self->{tmpdir}; -+ my $setup = test_setup($tmpdir, 'trace'); -+ -+ my $trace_log = File::Spec->rel2abs("$tmpdir/trace.log"); -+ -+ my $config = { -+ PidFile => $setup->{pid_file}, -+ ScoreboardFile => $setup->{scoreboard_file}, -+ SystemLog => $setup->{log_file}, -+ TraceLog => $trace_log, -+ Trace => 'DEFAULT:10', -+ TraceOptions => '+ConnIPs', -+ -+ AuthUserFile => $setup->{auth_user_file}, -+ AuthGroupFile => $setup->{auth_group_file}, -+ -+ IfModules => { -+ 'mod_delay.c' => { -+ DelayEngine => 'off', -+ }, -+ }, -+ }; -+ -+ my ($port, $config_user, $config_group) = config_write($setup->{config_file}, -+ $config); -+ -+ # Open pipes, for use between the parent and child processes. Specifically, -+ # the child will indicate when it's done with its test by writing a message -+ # to the parent. -+ my ($rfh, $wfh); -+ unless (pipe($rfh, $wfh)) { -+ die("Can't open pipe: $!"); -+ } -+ -+ my $ex; - -- my $config_file = "$tmpdir/trace.conf"; -- my $pid_file = File::Spec->rel2abs("$tmpdir/trace.pid"); -- my $scoreboard_file = File::Spec->rel2abs("$tmpdir/trace.scoreboard"); -- -- my $log_file = File::Spec->rel2abs('tests.log'); -- -- my $auth_user_file = File::Spec->rel2abs("$tmpdir/trace.passwd"); -- my $auth_group_file = File::Spec->rel2abs("$tmpdir/trace.group"); -- -- my $user = 'proftpd'; -- my $passwd = 'test'; -- my $group = 'ftpd'; -- my $home_dir = File::Spec->rel2abs($tmpdir); -- my $uid = 500; -- my $gid = 500; -- -- # Make sure that, if we're running as root, that the home directory has -- # permissions/privs set for the account we create -- if ($< == 0) { -- unless (chmod(0755, $home_dir)) { -- die("Can't set perms on $home_dir to 0755: $!"); -+ # Fork child -+ $self->handle_sigchld(); -+ defined(my $pid = fork()) or die("Can't fork: $!"); -+ if ($pid) { -+ eval { -+ my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); -+ $client->login($setup->{user}, $setup->{passwd}); -+ $client->quit(); -+ }; -+ if ($@) { -+ $ex = $@; -+ } -+ -+ $wfh->print("done\n"); -+ $wfh->flush(); -+ -+ } else { -+ eval { server_wait($setup->{config_file}, $rfh) }; -+ if ($@) { -+ warn($@); -+ exit 1; - } - -- unless (chown($uid, $gid, $home_dir)) { -- die("Can't set owner of $home_dir to $uid/$gid: $!"); -+ exit 0; -+ } -+ -+ # Stop server -+ server_stop($setup->{pid_file}); -+ $self->assert_child_ok($pid); -+ -+ eval { -+ if (open(my $fh, "< $trace_log")) { -+ my $ok = 0; -+ -+ while (my $line = <$fh>) { -+ chomp($line); -+ -+ my $expected = '\[\d+\]\s+\(client\s+(\S+), server\s+\S+\)\s+<(\S+):(\d+)>: (.*?)$'; -+ -+ if ($line =~ /$expected/) { -+ my $client_ip = $1; -+ my $trace_channel = $2; -+ my $trace_level = $3; -+ my $trace_msg = $4; -+ -+ next unless $trace_channel eq 'command'; -+ -+ my $expected = 'command'; -+ $self->assert($expected eq $trace_channel, -+ test_msg("Expected '$expected', got '$trace_channel'")); -+ -+ $expected = 7; -+ $self->assert($expected >= $trace_level, -+ test_msg("Expected >= $expected, got $trace_level")); -+ -+ $expected = '127.0.0.1'; -+ $self->assert($expected eq $client_ip, -+ test_msg("Expected '$expected', got '$client_ip'")); -+ -+ $ok = 1; -+ last; -+ } -+ } -+ -+ close($fh); -+ -+ $self->assert($ok, test_msg("Missing expected TraceLog messages")); -+ -+ } else { -+ die("Can't read $trace_log: $!"); - } -+ }; -+ if ($@) { -+ $ex = $@; - } - -- auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, -- '/bin/bash'); -- auth_group_write($auth_group_file, $group, $gid, $user); -+ test_cleanup($setup->{log_file}, $ex); -+} -+ -+sub traceoptions_timestamp_millis { -+ my $self = shift; -+ my $tmpdir = $self->{tmpdir}; -+ my $setup = test_setup($tmpdir, 'trace'); - - my $trace_log = File::Spec->rel2abs("$tmpdir/trace.log"); - - my $config = { -- PidFile => $pid_file, -- ScoreboardFile => $scoreboard_file, -- SystemLog => $log_file, -+ PidFile => $setup->{pid_file}, -+ ScoreboardFile => $setup->{scoreboard_file}, -+ SystemLog => $setup->{log_file}, - TraceLog => $trace_log, - Trace => 'DEFAULT:10', -- TraceOptions => '+ConnIPs', -+ TraceOptions => '+TimestampMillis', - -- AuthUserFile => $auth_user_file, -- AuthGroupFile => $auth_group_file, -+ AuthUserFile => $setup->{auth_user_file}, -+ AuthGroupFile => $setup->{auth_group_file}, - - IfModules => { - 'mod_delay.c' => { -@@ -90,7 +181,8 @@ sub traceoptions_conn_ips { - }, - }; - -- my ($port, $config_user, $config_group) = config_write($config_file, $config); -+ my ($port, $config_user, $config_group) = config_write($setup->{config_file}, -+ $config); - - # Open pipes, for use between the parent and child processes. Specifically, - # the child will indicate when it's done with its test by writing a message -@@ -108,10 +200,9 @@ sub traceoptions_conn_ips { - if ($pid) { - eval { - my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); -- $client->login($user, $passwd); -+ $client->login($setup->{user}, $setup->{passwd}); - $client->quit(); - }; -- - if ($@) { - $ex = $@; - } -@@ -120,7 +211,7 @@ sub traceoptions_conn_ips { - $wfh->flush(); - - } else { -- eval { server_wait($config_file, $rfh) }; -+ eval { server_wait($setup->{config_file}, $rfh) }; - if ($@) { - warn($@); - exit 1; -@@ -130,106 +221,74 @@ sub traceoptions_conn_ips { - } - - # Stop server -- server_stop($pid_file); -- -+ server_stop($setup->{pid_file}); - $self->assert_child_ok($pid); - -- if (open(my $fh, "< $trace_log")) { -- my $ok = 0; -+ eval { -+ if (open(my $fh, "< $trace_log")) { -+ my $ok = 0; - -- while (my $line = <$fh>) { -- chomp($line); -+ while (my $line = <$fh>) { -+ chomp($line); - -- my $expected = '\[\d+\]\s+\(client\s+(\S+), server\s+\S+\)\s+<(\S+):(\d+)>: (.*?)$'; -+ if ($ENV{TEST_VERBOSE}) { -+ print STDERR "# $line\n"; -+ } - -- if ($line =~ /$expected/) { -- my $client_ip = $1; -- my $trace_channel = $2; -- my $trace_level = $3; -- my $trace_msg = $4; -+ my $expected = '\d+:\d+:\d+,\d+\s+\[\d+\]\s+<(\S+):(\d+)>: (.*?)$'; - -- next unless $trace_channel eq 'command'; -+ if ($line =~ /$expected/) { -+ my $trace_channel = $1; -+ my $trace_level = $2; -+ my $trace_msg = $3; - -- my $expected = 'command'; -- $self->assert($expected eq $trace_channel, -- test_msg("Expected '$expected', got '$trace_channel'")); -+ next unless $trace_channel eq 'command'; - -- $expected = 7; -- $self->assert($expected >= $trace_level, -- test_msg("Expected >= $expected, got $trace_level")); -+ my $expected = 'command'; -+ $self->assert($expected eq $trace_channel, -+ test_msg("Expected '$expected', got '$trace_channel'")); - -- $expected = '127.0.0.1'; -- $self->assert($expected eq $client_ip, -- test_msg("Expected '$expected', got '$client_ip'")); -+ $expected = 7; -+ $self->assert($expected >= $trace_level, -+ test_msg("Expected >= $expected, got $trace_level")); - -- $ok = 1; -- last; -+ $ok = 1; -+ last; -+ } - } -- } -- -- close($fh); - -- $self->assert($ok, test_msg("Missing expected TraceLog messages")); -+ close($fh); - -- } else { -- die("Can't read $trace_log: $!"); -- } -+ $self->assert($ok, test_msg("Missing expected TraceLog messages")); - -- if ($ex) { -- die($ex); -+ } else { -+ die("Can't read $trace_log: $!"); -+ } -+ }; -+ if ($@) { -+ $ex = $@; - } - -- unlink($log_file); -+ test_cleanup($setup->{log_file}, $ex); - } - --sub traceoptions_timestamp_millis { -+sub traceoptions_no_timestamp { - my $self = shift; - my $tmpdir = $self->{tmpdir}; -- -- my $config_file = "$tmpdir/trace.conf"; -- my $pid_file = File::Spec->rel2abs("$tmpdir/trace.pid"); -- my $scoreboard_file = File::Spec->rel2abs("$tmpdir/trace.scoreboard"); -- -- my $log_file = File::Spec->rel2abs('tests.log'); -- -- my $auth_user_file = File::Spec->rel2abs("$tmpdir/trace.passwd"); -- my $auth_group_file = File::Spec->rel2abs("$tmpdir/trace.group"); -- -- my $user = 'proftpd'; -- my $passwd = 'test'; -- my $group = 'ftpd'; -- my $home_dir = File::Spec->rel2abs($tmpdir); -- my $uid = 500; -- my $gid = 500; -- -- # Make sure that, if we're running as root, that the home directory has -- # permissions/privs set for the account we create -- if ($< == 0) { -- unless (chmod(0755, $home_dir)) { -- die("Can't set perms on $home_dir to 0755: $!"); -- } -- -- unless (chown($uid, $gid, $home_dir)) { -- die("Can't set owner of $home_dir to $uid/$gid: $!"); -- } -- } -- -- auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, -- '/bin/bash'); -- auth_group_write($auth_group_file, $group, $gid, $user); -+ my $setup = test_setup($tmpdir, 'trace'); - - my $trace_log = File::Spec->rel2abs("$tmpdir/trace.log"); - - my $config = { -- PidFile => $pid_file, -- ScoreboardFile => $scoreboard_file, -- SystemLog => $log_file, -+ PidFile => $setup->{pid_file}, -+ ScoreboardFile => $setup->{scoreboard_file}, -+ SystemLog => $setup->{log_file}, - TraceLog => $trace_log, - Trace => 'DEFAULT:10', -- TraceOptions => '+TimestampMillis', -+ TraceOptions => '-Timestamp', - -- AuthUserFile => $auth_user_file, -- AuthGroupFile => $auth_group_file, -+ AuthUserFile => $setup->{auth_user_file}, -+ AuthGroupFile => $setup->{auth_group_file}, - - IfModules => { - 'mod_delay.c' => { -@@ -238,7 +297,8 @@ sub traceoptions_timestamp_millis { - }, - }; - -- my ($port, $config_user, $config_group) = config_write($config_file, $config); -+ my ($port, $config_user, $config_group) = config_write($setup->{config_file}, -+ $config); - - # Open pipes, for use between the parent and child processes. Specifically, - # the child will indicate when it's done with its test by writing a message -@@ -256,10 +316,9 @@ sub traceoptions_timestamp_millis { - if ($pid) { - eval { - my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); -- $client->login($user, $passwd); -+ $client->login($setup->{user}, $setup->{passwd}); - $client->quit(); - }; -- - if ($@) { - $ex = $@; - } -@@ -268,7 +327,7 @@ sub traceoptions_timestamp_millis { - $wfh->flush(); - - } else { -- eval { server_wait($config_file, $rfh) }; -+ eval { server_wait($setup->{config_file}, $rfh) }; - if ($@) { - warn($@); - exit 1; -@@ -278,51 +337,55 @@ sub traceoptions_timestamp_millis { - } - - # Stop server -- server_stop($pid_file); -- -+ server_stop($setup->{pid_file}); - $self->assert_child_ok($pid); - -- if (open(my $fh, "< $trace_log")) { -- my $ok = 0; -+ eval { -+ if (open(my $fh, "< $trace_log")) { -+ my $ok = 0; - -- while (my $line = <$fh>) { -- chomp($line); -+ while (my $line = <$fh>) { -+ chomp($line); - -- my $expected = '\d+:\d+:\d+,\d+\s+\[\d+\]\s+<(\S+):(\d+)>: (.*?)$'; -+ if ($ENV{TEST_VERBOSE}) { -+ print STDERR "# $line\n"; -+ } - -- if ($line =~ /$expected/) { -- my $trace_channel = $1; -- my $trace_level = $2; -- my $trace_msg = $3; -+ my $expected = '\[\d+\]\s+<(\S+):(\d+)>: (.*?)$'; - -- next unless $trace_channel eq 'command'; -+ if ($line =~ /$expected/) { -+ my $trace_channel = $1; -+ my $trace_level = $2; -+ my $trace_msg = $3; - -- my $expected = 'command'; -- $self->assert($expected eq $trace_channel, -- test_msg("Expected '$expected', got '$trace_channel'")); -+ next unless $trace_channel eq 'command'; - -- $expected = 7; -- $self->assert($expected >= $trace_level, -- test_msg("Expected >= $expected, got $trace_level")); -+ my $expected = 'command'; -+ $self->assert($expected eq $trace_channel, -+ test_msg("Expected '$expected', got '$trace_channel'")); - -- $ok = 1; -- last; -- } -- } -+ $expected = 7; -+ $self->assert($expected >= $trace_level, -+ test_msg("Expected >= $expected, got $trace_level")); - -- close($fh); -+ $ok = 1; -+ last; -+ } -+ } - -- $self->assert($ok, test_msg("Missing expected TraceLog messages")); -+ close($fh); - -- } else { -- die("Can't read $trace_log: $!"); -- } -+ $self->assert($ok, test_msg("Missing expected TraceLog messages")); - -- if ($ex) { -- die($ex); -+ } else { -+ die("Can't read $trace_log: $!"); -+ } -+ }; -+ if ($@) { -+ $ex = $@; - } - -- unlink($log_file); -+ test_cleanup($setup->{log_file}, $ex); - } - - 1; diff --git a/proftpd-1.3.6c-shellbang.patch b/proftpd-1.3.6c-shellbang.patch deleted file mode 100644 index 5af88d5..0000000 --- a/proftpd-1.3.6c-shellbang.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- contrib/ftpasswd -+++ contrib/ftpasswd -@@ -1,4 +1,4 @@ --#!/usr/bin/env perl -+#!/usr/bin/perl - # --------------------------------------------------------------------------- - # Copyright (C) 2000-2020 TJ Saunders - # ---- contrib/ftpmail -+++ contrib/ftpmail -@@ -1,4 +1,4 @@ --#!/usr/bin/env perl -+#!/usr/bin/perl - # --------------------------------------------------------------------------- - # Copyright (C) 2008-2013 TJ Saunders - # ---- contrib/ftpquota -+++ contrib/ftpquota -@@ -1,4 +1,4 @@ --#!/usr/bin/env perl -+#!/usr/bin/perl - # ------------------------------------------------------------------------- - # Copyright (C) 2000-2017 TJ Saunders - # ---- contrib/xferstats.holger-preiss -+++ contrib/xferstats.holger-preiss -@@ -1,4 +1,4 @@ --#!/usr/bin/env perl -+#!/usr/bin/perl - # --------------------------------------------------------------------------- - # - # USAGE: xferstats ---- src/prxs.in -+++ src/prxs.in -@@ -1,4 +1,4 @@ --#!/usr/bin/env perl -+#!/usr/bin/perl - - # --------------------------------------------------------------------------- - # Copyright (C) 2008-2012 TJ Saunders diff --git a/proftpd-1.3.7-shellbang.patch b/proftpd-1.3.7-shellbang.patch new file mode 100644 index 0000000..d328c78 --- /dev/null +++ b/proftpd-1.3.7-shellbang.patch @@ -0,0 +1,40 @@ +--- contrib/ftpasswd ++++ contrib/ftpasswd +@@ -1,4 +1,4 @@ +-#!/usr/bin/env perl ++#!/usr/bin/perl + # --------------------------------------------------------------------------- + # Copyright (C) 2000-2020 TJ Saunders + # +--- contrib/ftpmail ++++ contrib/ftpmail +@@ -1,4 +1,4 @@ +-#!/usr/bin/env perl ++#!/usr/bin/perl + # --------------------------------------------------------------------------- + # Copyright (C) 2008-2017 TJ Saunders + # +--- contrib/ftpquota ++++ contrib/ftpquota +@@ -1,4 +1,4 @@ +-#!/usr/bin/env perl ++#!/usr/bin/perl + # ------------------------------------------------------------------------- + # Copyright (C) 2000-2017 TJ Saunders + # +--- contrib/xferstats.holger-preiss ++++ contrib/xferstats.holger-preiss +@@ -1,4 +1,4 @@ +-#!/usr/bin/env perl ++#!/usr/bin/perl + # --------------------------------------------------------------------------- + # + # USAGE: xferstats +--- src/prxs.in ++++ src/prxs.in +@@ -1,4 +1,4 @@ +-#!/usr/bin/env perl ++#!/usr/bin/perl + + # --------------------------------------------------------------------------- + # Copyright (C) 2008-2012 TJ Saunders diff --git a/proftpd-1.3.7rc3-logging-not-systemd.patch b/proftpd-1.3.7rc3-logging-not-systemd.patch new file mode 100644 index 0000000..c7bd00b --- /dev/null +++ b/proftpd-1.3.7rc3-logging-not-systemd.patch @@ -0,0 +1,12 @@ +--- proftpd.conf ++++ proftpd.conf +@@ -114,9 +114,6 @@ UseSendfile off + LogFormat default "%h %l %u %t \"%r\" %s %b" + LogFormat auth "%v [%P] %h %t \"%r\" %s" + +-# Don't log hostname or timestamps because systemd will do that for us +-LogOptions -Timestamp -Hostname +RoleBasedProcessLabels +- + # Enable basic controls via ftpdctl + # (http://www.proftpd.org/docs/modules/mod_ctrls.html) + ControlsEngine on diff --git a/proftpd.spec b/proftpd.spec index e5df547..9d919de 100644 --- a/proftpd.spec +++ b/proftpd.spec @@ -65,13 +65,13 @@ # Dynamic modules contain references to symbols in main dæmon, so we need to disable linker checks for undefined symbols %undefine _strict_symbol_defs_build -#global prever rc3 +#global prever rc4 %global baserelease 1 %global mod_vroot_version 0.9.5 Summary: Flexible, stable and highly-configurable FTP server Name: proftpd -Version: 1.3.6e +Version: 1.3.7 Release: %{?prever:0.}%{baserelease}%{?prever:.%{prever}}%{?dist} License: GPLv2+ URL: http://www.proftpd.org/ @@ -87,16 +87,13 @@ Source8: proftpd-welcome.msg Source9: proftpd.sysconfig Source10: http://github.com/Castaglia/proftpd-mod_vroot/archive/v%{mod_vroot_version}.tar.gz -Patch1: proftpd-1.3.6c-shellbang.patch +Patch1: proftpd-1.3.7-shellbang.patch Patch2: proftpd.conf-no-memcached.patch Patch3: proftpd-1.3.4rc1-mod_vroot-test.patch Patch4: proftpd-1.3.6-no-mod-wrap.patch Patch5: proftpd-1.3.6-no-mod-geoip.patch -Patch7: proftpd-1.3.6c-logoptions.patch -Patch8: proftpd-1.3.6c-logging-not-systemd.patch - -Patch100: 0001-Move-definition-of-recvd_signal_flags-for-API-tests.patch -Patch116: proftpd-1.3.6-ENOATTR.patch +Patch8: proftpd-1.3.7rc3-logging-not-systemd.patch +Patch9: https://patch-diff.githubusercontent.com/raw/proftpd/proftpd/pull/1056.patch BuildRequires: coreutils BuildRequires: gcc @@ -305,21 +302,6 @@ mv contrib/README contrib/README.contrib %patch5 -b .nogeoip %endif -# Add options to vary logging format -# https://bugzilla.redhat.com/show_bug.cgi?id=1808989 -# http://bugs.proftpd.org/show_bug.cgi?id=4185 -# https://github.com/proftpd/proftpd/issues/1002 -# https://github.com/proftpd/proftpd/pull/1009 -%patch7 - -# Fix API tests compile failure with GCC 10 -# https://github.com/proftpd/proftpd/pull/886 -%patch100 -p1 - -# Don't assume ENOATTR is defined in test suite -# https://github.com/proftpd/proftpd/pull/730 -%patch116 -p1 - # OpenSSL Cipher Profiles introduced in Fedora 21 # Elsewhere, we use the default of DEFAULT:!ADH:!EXPORT:!DES %if (0%{?rhel} && 0%{?rhel} <= 7) || (0%{?fedora} && 0%{?fedora} <= 20) @@ -335,6 +317,11 @@ sed -i -e '/killall/s/test.*/systemctl reload proftpd.service/' \ %patch8 %endif +# Fix regression in configure script +# https://github.com/proftpd/proftpd/issues/1055 +# https://github.com/proftpd/proftpd/pull/1056 +%patch9 -p1 + # Avoid docfile dependencies chmod -c -x contrib/xferstats.holger-preiss @@ -377,7 +364,6 @@ make %{?_smp_mflags} %install make install DESTDIR=%{buildroot} \ - rundir="%{rundir}/proftpd" \ INSTALL_USER=`id -un` \ INSTALL_GROUP=`id -gn` mkdir -p %{buildroot}%{_sysconfdir}/proftpd/conf.d @@ -492,9 +478,7 @@ fi %doc COPYING %endif %doc CREDITS ChangeLog NEWS README.md -%doc README.DSO README.modules README.IPv6 README.PAM -%doc README.capabilities README.classes README.controls README.facl -%doc contrib/README.contrib contrib/README.ratio +%doc README.modules contrib/README.contrib contrib/README.ratio %doc doc/* sample-configurations/ %dir %{_localstatedir}/ftp/ %dir %{_localstatedir}/ftp/pub/ @@ -610,6 +594,12 @@ fi %{_mandir}/man1/ftpwho.1* %changelog +* Tue Jul 21 2020 Paul Howarth - 1.3.7-1 +- Update to 1.3.7 (see RELEASE_NOTES for details) +- Fix regression in configure script + https://github.com/proftpd/proftpd/issues/1055 + https://github.com/proftpd/proftpd/pull/1056 + * Tue Jul 21 2020 Paul Howarth - 1.3.6e-1 - Update to 1.3.6e - Fixed null pointer dereference in mod_sftp when using SCP incorrectly diff --git a/sources b/sources index ca3a2b6..1050606 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (proftpd-1.3.6e.tar.gz) = 6652cca8d2e0efe069fe2f6b342c2afb8f9f85ef2365fc9958240f35b396c103dea766ce8a6676c087c1e95376aaf38705725bd645682d6d52900046788af38f +SHA512 (proftpd-1.3.7.tar.gz) = db17d0f03d22de5379109a25d2ca5d35ec2129c70f8352cef698a65c3ad9e9fde1600821162e94fc07c7b70bc21803d3ed2f86e33c15c795d7e3084d71c56498 SHA512 (v0.9.5.tar.gz) = 10e4de29d84c2f2f5e88502fcd62768e2b0797b05a95fc22b59605e3c7377bfe3609c99e2f6fc2a17f9c3a267ff815c651ae39be8b6cb133565a4590f767353d