From 191e4496fbce0dce3daf6eaf47b4c1270f379a2f Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 3 Sep 2021 07:22:18 +0200 Subject: [PATCH 1/6] lib/cmdline: add POPT_COMMON_DAEMON daemon popt options Note: interactive=true implies fork=false. This matches the semantics that currently 3/4 daemons implement manually. Not used so far, no change in behaviour. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14803 Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke (cherry picked from commit aaa3c6a4132d2e739958e168e7dc3e78dfa4a72e) --- lib/cmdline/cmdline.c | 80 +++++++++++++++++++++++++++++++++++ lib/cmdline/cmdline.h | 29 +++++++++++++ lib/cmdline/cmdline_private.h | 4 ++ 3 files changed, 113 insertions(+) diff --git a/lib/cmdline/cmdline.c b/lib/cmdline/cmdline.c index a0a55f4dcfb..a299a229f69 100644 --- a/lib/cmdline/cmdline.c +++ b/lib/cmdline/cmdline.c @@ -28,6 +28,7 @@ static TALLOC_CTX *cmdline_mem_ctx; static struct loadparm_context *cmdline_lp_ctx; static struct cli_credentials *cmdline_creds; static samba_cmdline_load_config cmdline_load_config_fn; +static struct samba_cmdline_daemon_cfg cmdline_daemon_cfg; /* PRIVATE */ bool samba_cmdline_set_talloc_ctx(TALLOC_CTX *mem_ctx) @@ -59,6 +60,10 @@ bool samba_cmdline_init_common(TALLOC_CTX *mem_ctx) return false; } + cmdline_daemon_cfg = (struct samba_cmdline_daemon_cfg) { + .fork = true, + }; + fault_setup(); /* @@ -112,6 +117,11 @@ struct cli_credentials *samba_cmdline_get_creds(void) return cmdline_creds; } +struct samba_cmdline_daemon_cfg *samba_cmdline_get_daemon_cfg(void) +{ + return &cmdline_daemon_cfg; +} + void samba_cmdline_burn(int argc, char *argv[]) { bool found = false; @@ -1134,6 +1144,73 @@ static struct poptOption popt_common_version[] = { POPT_TABLEEND }; +/********************************************************** + * DAEMON POPT + **********************************************************/ + +static void popt_daemon_callback(poptContext ctx, + enum poptCallbackReason reason, + const struct poptOption *opt, + const char *arg, + const void *data) +{ + switch(opt->val) { + case OPT_DAEMON: + cmdline_daemon_cfg.daemon = true; + break; + case OPT_INTERACTIVE: + cmdline_daemon_cfg.interactive = true; + cmdline_daemon_cfg.fork = false; + break; + case OPT_FORK: + cmdline_daemon_cfg.fork = false; + break; + case OPT_NO_PROCESS_GROUP: + cmdline_daemon_cfg.no_process_group = true; + break; + } +} + +static struct poptOption popt_common_daemon[] = { + { + .argInfo = POPT_ARG_CALLBACK, + .arg = (void *)popt_daemon_callback + }, + { + .longName = "daemon", + .shortName = 'D', + .argInfo = POPT_ARG_NONE, + .arg = NULL, + .val = OPT_DAEMON, + .descrip = "Become a daemon (default)" , + }, + { + .longName = "interactive", + .shortName = 'i', + .argInfo = POPT_ARG_NONE, + .arg = NULL, + .val = OPT_INTERACTIVE, + .descrip = "Run interactive (not a daemon) and log to stdout", + }, + { + .longName = "foreground", + .shortName = 'F', + .argInfo = POPT_ARG_NONE, + .arg = NULL, + .val = OPT_FORK, + .descrip = "Run daemon in foreground (for daemontools, etc.)", + }, + { + .longName = "no-process-group", + .shortName = '\0', + .argInfo = POPT_ARG_NONE, + .arg = NULL, + .val = OPT_NO_PROCESS_GROUP, + .descrip = "Don't create a new process group" , + }, + POPT_TABLEEND +}; + /********************************************************** * LEGACY S3 POPT **********************************************************/ @@ -1270,6 +1347,9 @@ struct poptOption *samba_cmdline_get_popt(enum smb_cmdline_popt_options opt) case SAMBA_CMDLINE_POPT_OPT_VERSION: return popt_common_version; break; + case SAMBA_CMDLINE_POPT_OPT_DAEMON: + return popt_common_daemon; + break; case SAMBA_CMDLINE_POPT_OPT_SAMBA_LDB: return popt_common_samba_ldb; break; diff --git a/lib/cmdline/cmdline.h b/lib/cmdline/cmdline.h index 3c0c9e8c18d..1f85da0099e 100644 --- a/lib/cmdline/cmdline.h +++ b/lib/cmdline/cmdline.h @@ -46,11 +46,19 @@ enum smb_cmdline_popt_options { SAMBA_CMDLINE_POPT_OPT_CONNECTION, SAMBA_CMDLINE_POPT_OPT_CREDENTIALS, SAMBA_CMDLINE_POPT_OPT_VERSION, + SAMBA_CMDLINE_POPT_OPT_DAEMON, SAMBA_CMDLINE_POPT_OPT_SAMBA_LDB, SAMBA_CMDLINE_POPT_OPT_LEGACY_S3, SAMBA_CMDLINE_POPT_OPT_LEGACY_S4, }; +struct samba_cmdline_daemon_cfg { + bool daemon; + bool interactive; + bool fork; + bool no_process_group; +}; + /** * @brief Initialize the commandline interface for parsing options. * @@ -114,6 +122,15 @@ struct cli_credentials *samba_cmdline_get_creds(void); */ struct poptOption *samba_cmdline_get_popt(enum smb_cmdline_popt_options opt); +/** + * @brief Get a pointer to the poptOptions for daemons + * + * @return A pointer to the daemon options + * + * @see POPT_COMMON_DAEMON + */ +struct samba_cmdline_daemon_cfg *samba_cmdline_get_daemon_cfg(void); + /** * @brief Burn secrets on the command line. * @@ -249,6 +266,18 @@ poptContext samba_popt_get_context(const char * name, .descrip = "Version options:", \ .argDescrip = NULL }, +/** + * @brief A popt structure for daemon options. + */ +#define POPT_COMMON_DAEMON { \ + .longName = NULL, \ + .shortName = '\0', \ + .argInfo = POPT_ARG_INCLUDE_TABLE, \ + .arg = samba_cmdline_get_popt(SAMBA_CMDLINE_POPT_OPT_DAEMON), \ + .val = 0, \ + .descrip = "Daemon options:", \ + .argDescrip = NULL }, + /** * @brief A popt structure for common samba options. */ diff --git a/lib/cmdline/cmdline_private.h b/lib/cmdline/cmdline_private.h index 2261e753447..b1584e020dc 100644 --- a/lib/cmdline/cmdline_private.h +++ b/lib/cmdline/cmdline_private.h @@ -34,6 +34,10 @@ enum { OPT_USE_KERBEROS_CCACHE, OPT_USE_WINBIND_CCACHE, OPT_CLIENT_PROTECTION, + OPT_DAEMON, + OPT_INTERACTIVE, + OPT_FORK, + OPT_NO_PROCESS_GROUP, }; typedef bool (*samba_cmdline_load_config)(void); -- 2.31.1 From 57c3aa0df596bb27ed333fa38a3497b1bac758f9 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 3 Sep 2021 07:28:45 +0200 Subject: [PATCH 2/6] lib/cmdline: restore pre-4.15 logging behaviour for daemons For servers ensure logging is configured to go to a logfile unless in interactive mode by calling setup_logging() before lp_load_global() is called. In 4.14 servers had the chance to call setup_logging(getprogname(), DEBUG_FILE) before they called lp_load_*() explicitly in the server. Now in 4.15 lp_load_*() is called internally when parsing the command line arguments triggered by the server running the poptGetNextOpt() loop, so it's too late when the server calls setup_logging(getprogname(), DEBUG_FILE) as lots of debugging from lp_load_()* was already written to DEBUG_DEFAULT_STDERR. Note that there's a chicken and egg problem *within* this patchset: this change here breaks stdout logging for servers until the servers are converted to use the new POPT_COMMON_DAEMON. The only way to address that would be squashing all changes into one patchset, but for the sake of reviewability (is that an actual english word? :)) I chose to split the changes. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14803 Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke (cherry picked from commit 877183ac0b57f5b2902446e41bb6ab3191f84fa6) --- lib/cmdline/cmdline_s3.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/cmdline/cmdline_s3.c b/lib/cmdline/cmdline_s3.c index 70fd768a648..1f8d9ed5eb5 100644 --- a/lib/cmdline/cmdline_s3.c +++ b/lib/cmdline/cmdline_s3.c @@ -55,10 +55,19 @@ static bool _samba_cmdline_load_config_s3(void) case SAMBA_CMDLINE_CONFIG_CLIENT: ok = lp_load_client(config_file); break; - case SAMBA_CMDLINE_CONFIG_SERVER: + case SAMBA_CMDLINE_CONFIG_SERVER: + { + const struct samba_cmdline_daemon_cfg *cmdline_daemon_cfg = + samba_cmdline_get_daemon_cfg(); + + if (!cmdline_daemon_cfg->interactive) { + setup_logging(getprogname(), DEBUG_FILE); + } + ok = lp_load_global(config_file); break; } + } if (!ok) { fprintf(stderr, -- 2.31.1 From dcb9520cf9b69f23c4acc3ba43ef789b84fa82b9 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 3 Sep 2021 07:33:39 +0200 Subject: [PATCH 3/6] smbd: use POPT_COMMON_DAEMON BUG: https://bugzilla.samba.org/show_bug.cgi?id=14803 Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke (cherry picked from commit ae22442db437061aada6427adde205cd13f1d202) --- source3/smbd/server.c | 112 +++++++++++++----------------------------- 1 file changed, 34 insertions(+), 78 deletions(-) diff --git a/source3/smbd/server.c b/source3/smbd/server.c index e40cc27d2b8..b9fb7e855b8 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -1538,10 +1538,7 @@ extern void build_options(bool screen); int main(int argc,const char *argv[]) { /* shall I run as a daemon */ - bool is_daemon = false; - bool interactive = false; - bool Fork = true; - bool no_process_group = false; + struct samba_cmdline_daemon_cfg *cmdline_daemon_cfg = NULL; bool log_stdout = false; char *ports = NULL; char *profile_level = NULL; @@ -1550,46 +1547,8 @@ extern void build_options(bool screen); bool print_build_options = False; bool serving_printers = false; struct server_id main_server_id = {0}; - enum { - OPT_DAEMON = 1000, - OPT_INTERACTIVE, - OPT_FORK, - OPT_NO_PROCESS_GROUP, - }; struct poptOption long_options[] = { POPT_AUTOHELP - { - .longName = "daemon", - .shortName = 'D', - .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = OPT_DAEMON, - .descrip = "Become a daemon (default)" , - }, - { - .longName = "interactive", - .shortName = 'i', - .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = OPT_INTERACTIVE, - .descrip = "Run interactive (not a daemon) and log to stdout", - }, - { - .longName = "foreground", - .shortName = 'F', - .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = OPT_FORK, - .descrip = "Run daemon in foreground (for daemontools, etc.)", - }, - { - .longName = "no-process-group", - .shortName = '\0', - .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = OPT_NO_PROCESS_GROUP, - .descrip = "Don't create a new process group" , - }, { .longName = "build-options", .shortName = 'b', @@ -1615,6 +1574,7 @@ extern void build_options(bool screen); .descrip = "Set profiling level","PROFILE_LEVEL", }, POPT_COMMON_SAMBA + POPT_COMMON_DAEMON POPT_COMMON_VERSION POPT_TABLEEND }; @@ -1674,6 +1634,8 @@ extern void build_options(bool screen); exit(ENOMEM); } + cmdline_daemon_cfg = samba_cmdline_get_daemon_cfg(); + pc = samba_popt_get_context(getprogname(), argc, argv, @@ -1686,18 +1648,6 @@ extern void build_options(bool screen); while((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { - case OPT_DAEMON: - is_daemon = true; - break; - case OPT_INTERACTIVE: - interactive = true; - break; - case OPT_FORK: - Fork = false; - break; - case OPT_NO_PROCESS_GROUP: - no_process_group = true; - break; case 'b': print_build_options = True; break; @@ -1712,15 +1662,10 @@ extern void build_options(bool screen); log_stdout = (debug_get_log_type() == DEBUG_STDOUT); - if (interactive) { - Fork = False; + if (cmdline_daemon_cfg->interactive) { log_stdout = True; } - if (!log_stdout) { - setup_logging(argv[0], DEBUG_FILE); - } - if (print_build_options) { build_options(True); /* Display output to screen as well as debug */ exit(0); @@ -1733,11 +1678,11 @@ extern void build_options(bool screen); set_remote_machine_name("smbd", False); - if (interactive && (DEBUGLEVEL >= 9)) { + if (cmdline_daemon_cfg->interactive && (DEBUGLEVEL >= 9)) { talloc_enable_leak_report(); } - if (log_stdout && Fork) { + if (log_stdout && cmdline_daemon_cfg->fork) { DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n")); exit(1); } @@ -1879,23 +1824,25 @@ extern void build_options(bool screen); main_server_id = messaging_server_id(msg_ctx); set_profile_level(profiling_level, &main_server_id); - if (!is_daemon && !is_a_socket(0)) { - if (!interactive) { + if (!cmdline_daemon_cfg->daemon && !is_a_socket(0)) { + if (!cmdline_daemon_cfg->interactive) { DEBUG(3, ("Standard input is not a socket, " "assuming -D option\n")); } /* - * Setting is_daemon here prevents us from eventually calling + * Setting "daemon" here prevents us from eventually calling * the open_sockets_inetd() */ - is_daemon = True; + cmdline_daemon_cfg->daemon = true; } - if (is_daemon && !interactive) { + if (cmdline_daemon_cfg->daemon && !cmdline_daemon_cfg->interactive) { DEBUG(3, ("Becoming a daemon.\n")); - become_daemon(Fork, no_process_group, log_stdout); + become_daemon(cmdline_daemon_cfg->fork, + cmdline_daemon_cfg->no_process_group, + log_stdout); } else { daemon_status("smbd", "Starting process ..."); } @@ -1905,8 +1852,11 @@ extern void build_options(bool screen); * If we're interactive we want to set our own process group for * signal management. */ - if (interactive && !no_process_group) + if (cmdline_daemon_cfg->interactive && + !cmdline_daemon_cfg->no_process_group) + { setpgid( (pid_t)0, (pid_t)0); + } #endif if (!directory_exist(lp_lock_directory())) @@ -1915,7 +1865,7 @@ extern void build_options(bool screen); if (!directory_exist(lp_pid_directory())) mkdir(lp_pid_directory(), 0755); - if (is_daemon) + if (cmdline_daemon_cfg->daemon) pidfile_create(lp_pid_directory(), "smbd"); status = reinit_after_fork(msg_ctx, ev_ctx, false, NULL); @@ -1923,7 +1873,7 @@ extern void build_options(bool screen); exit_daemon("reinit_after_fork() failed", map_errno_from_nt_status(status)); } - if (!interactive) { + if (!cmdline_daemon_cfg->interactive) { /* * Do not initialize the parent-child-pipe before becoming a * daemon: this is used to detect a died parent in the child @@ -1939,7 +1889,7 @@ extern void build_options(bool screen); if (!parent) { exit_server("talloc(struct smbd_parent_context) failed"); } - parent->interactive = interactive; + parent->interactive = cmdline_daemon_cfg->interactive; parent->ev_ctx = ev_ctx; parent->msg_ctx = msg_ctx; parent->dce_ctx = dce_ctx; @@ -2020,11 +1970,17 @@ extern void build_options(bool screen); exit_daemon("Samba cannot init leases", EACCES); } - if (!smbd_notifyd_init(msg_ctx, interactive, &parent->notifyd)) { + if (!smbd_notifyd_init( + msg_ctx, + cmdline_daemon_cfg->interactive, + &parent->notifyd)) { exit_daemon("Samba cannot init notification", EACCES); } - if (!cleanupd_init(msg_ctx, interactive, &parent->cleanupd)) { + if (!cleanupd_init( + msg_ctx, + cmdline_daemon_cfg->interactive, + &parent->cleanupd)) { exit_daemon("Samba cannot init the cleanupd", EACCES); } @@ -2105,7 +2061,7 @@ extern void build_options(bool screen); exit_daemon("Samba cannot setup ep pipe", EACCES); } - if (!interactive) { + if (!cmdline_daemon_cfg->interactive) { daemon_ready("smbd"); } @@ -2115,7 +2071,7 @@ extern void build_options(bool screen); /* only start other daemons if we are running as a daemon * -- bad things will happen if smbd is launched via inetd * and we fork a copy of ourselves here */ - if (is_daemon && !interactive) { + if (cmdline_daemon_cfg->daemon && !cmdline_daemon_cfg->interactive) { if (rpc_epmapper_daemon() == RPC_DAEMON_FORK) { start_epmd(ev_ctx, msg_ctx, dce_ctx); @@ -2158,7 +2114,7 @@ extern void build_options(bool screen); } } - if (!is_daemon) { + if (!cmdline_daemon_cfg->daemon) { int ret, sock; /* inetd mode */ @@ -2211,7 +2167,7 @@ extern void build_options(bool screen); /* make sure we always have a valid stackframe */ frame = talloc_stackframe(); - if (!Fork) { + if (!cmdline_daemon_cfg->fork) { /* if we are running in the foreground then look for EOF on stdin, and exit if it happens. This allows us to die if the parent process dies -- 2.31.1 From 3e21c561b5168312baf064835a11132d1845892b Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 3 Sep 2021 12:14:19 +0200 Subject: [PATCH 4/6] nmbd: use POPT_COMMON_DAEMON BUG: https://bugzilla.samba.org/show_bug.cgi?id=14803 Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke (cherry picked from commit a20f63b384750d389aeafd4bd5e229aed72cb271) --- source3/nmbd/nmbd.c | 103 ++++++++++---------------------------------- 1 file changed, 23 insertions(+), 80 deletions(-) diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index c33d3a441ae..d43c52bb406 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -771,56 +771,14 @@ static bool open_sockets(bool isdaemon, int port) int main(int argc, const char *argv[]) { - bool is_daemon = false; - bool opt_interactive = false; - bool Fork = true; - bool no_process_group = false; + struct samba_cmdline_daemon_cfg *cmdline_daemon_cfg = NULL; bool log_stdout = false; poptContext pc; char *p_lmhosts = NULL; int opt; struct messaging_context *msg; - enum { - OPT_DAEMON = 1000, - OPT_INTERACTIVE, - OPT_FORK, - OPT_NO_PROCESS_GROUP - }; struct poptOption long_options[] = { POPT_AUTOHELP - { - .longName = "daemon", - .shortName = 'D', - .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = OPT_DAEMON, - .descrip = "Become a daemon (default)", - }, - { - .longName = "interactive", - .shortName = 'i', - .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = OPT_INTERACTIVE, - .descrip = "Run interactive (not a daemon)", - }, - { - .longName = "foreground", - .shortName = 'F', - .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = OPT_FORK, - .descrip = "Run daemon in foreground " - "(for daemontools, etc.)", - }, - { - .longName = "no-process-group", - .shortName = 0, - .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = OPT_NO_PROCESS_GROUP, - .descrip = "Don't create a new process group", - }, { .longName = "hosts", .shortName = 'H', @@ -838,6 +796,7 @@ static bool open_sockets(bool isdaemon, int port) .descrip = "Listen on the specified port", }, POPT_COMMON_SAMBA + POPT_COMMON_DAEMON POPT_COMMON_VERSION POPT_TABLEEND }; @@ -870,6 +829,8 @@ static bool open_sockets(bool isdaemon, int port) exit(ENOMEM); } + cmdline_daemon_cfg = samba_cmdline_get_daemon_cfg(); + global_nmb_port = NMB_PORT; pc = samba_popt_get_context(getprogname(), @@ -884,25 +845,9 @@ static bool open_sockets(bool isdaemon, int port) } while ((opt = poptGetNextOpt(pc)) != -1) { - switch (opt) { - case OPT_DAEMON: - is_daemon = true; - break; - case OPT_INTERACTIVE: - opt_interactive = true; - break; - case OPT_FORK: - Fork = false; - break; - case OPT_NO_PROCESS_GROUP: - no_process_group = true; - break; - default: - d_fprintf(stderr, "\nInvalid option %s: %s\n\n", - poptBadOption(pc, 0), poptStrerror(opt)); - poptPrintUsage(pc, stderr, 0); - exit(1); - } + d_fprintf(stderr, "\nInvalid options\n\n"); + poptPrintUsage(pc, stderr, 0); + exit(1); }; poptFreeContext(pc); @@ -943,27 +888,20 @@ static bool open_sockets(bool isdaemon, int port) CatchChild(); log_stdout = (debug_get_log_type() == DEBUG_STDOUT); - if ( opt_interactive ) { - Fork = False; + if ( cmdline_daemon_cfg->interactive ) { log_stdout = True; } - if ( log_stdout && Fork ) { + if ( log_stdout && cmdline_daemon_cfg->fork ) { DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n")); exit(1); } - if (!log_stdout) { - setup_logging( argv[0], DEBUG_FILE); - } - reopen_logs(); DEBUG(0,("nmbd version %s started.\n", samba_version_string())); DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE)); - reopen_logs(); - if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC && !lp_parm_bool(-1, "server role check", "inhibit", false)) { /* TODO: when we have a merged set of defaults for @@ -1000,15 +938,17 @@ static bool open_sockets(bool isdaemon, int port) set_samba_nb_type(); - if (!is_daemon && !is_a_socket(0)) { + if (!cmdline_daemon_cfg->daemon && !is_a_socket(0)) { DEBUG(3, ("standard input is not a socket, assuming -D option\n")); - is_daemon = True; + cmdline_daemon_cfg->daemon = true; } - if (is_daemon && !opt_interactive) { + if (cmdline_daemon_cfg->daemon && !cmdline_daemon_cfg->interactive) { DEBUG(3, ("Becoming a daemon.\n")); - become_daemon(Fork, no_process_group, log_stdout); - } else if (!opt_interactive) { + become_daemon(cmdline_daemon_cfg->fork, + cmdline_daemon_cfg->no_process_group, + log_stdout); + } else if (!cmdline_daemon_cfg->interactive) { daemon_status("nmbd", "Starting process..."); } @@ -1017,8 +957,11 @@ static bool open_sockets(bool isdaemon, int port) * If we're interactive we want to set our own process group for * signal management. */ - if (opt_interactive && !no_process_group) + if (cmdline_daemon_cfg->interactive && + !cmdline_daemon_cfg->no_process_group) + { setpgid( (pid_t)0, (pid_t)0 ); + } #endif #ifndef SYNC_DNS @@ -1059,7 +1002,7 @@ static bool open_sockets(bool isdaemon, int port) if (!nmbd_setup_sig_term_handler(msg)) exit_daemon("NMBD failed to setup signal handler", EINVAL); - if (!nmbd_setup_stdin_handler(msg, !Fork)) + if (!nmbd_setup_stdin_handler(msg, !cmdline_daemon_cfg->fork)) exit_daemon("NMBD failed to setup stdin handler", EINVAL); if (!nmbd_setup_sig_hup_handler(msg)) exit_daemon("NMBD failed to setup SIGHUP handler", EINVAL); @@ -1086,7 +1029,7 @@ static bool open_sockets(bool isdaemon, int port) DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) ); - if ( !open_sockets( is_daemon, global_nmb_port ) ) { + if ( !open_sockets( cmdline_daemon_cfg->daemon, global_nmb_port ) ) { kill_async_dns_child(); return 1; } @@ -1136,7 +1079,7 @@ static bool open_sockets(bool isdaemon, int port) exit_daemon( "NMBD failed to setup packet server.", EACCES); } - if (!opt_interactive) { + if (!cmdline_daemon_cfg->interactive) { daemon_ready("nmbd"); } -- 2.31.1 From 7f28aae8cc8007ea4f6299870ba8a4a31fac2aea Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 3 Sep 2021 12:25:00 +0200 Subject: [PATCH 5/6] winbindd: use POPT_COMMON_DAEMON Note: this also changes logging to go to stderr instead of stdout which is the same behaviour as smbd and nmbd (starting with 4.15). BUG: https://bugzilla.samba.org/show_bug.cgi?id=14803 Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke (cherry picked from commit 9d82454cdfc2b4b8007c7b54b3afd5686f49be19) --- source3/winbindd/winbindd.c | 88 ++++++++++--------------------------- 1 file changed, 23 insertions(+), 65 deletions(-) diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index 9b148b18a58..7f80d49897e 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -1594,49 +1594,10 @@ static void winbindd_addr_changed(struct tevent_req *req) int main(int argc, const char **argv) { - static bool is_daemon = False; - static bool Fork = True; static bool log_stdout = False; - static bool no_process_group = False; - enum { - OPT_DAEMON = 1000, - OPT_FORK, - OPT_NO_PROCESS_GROUP - }; + struct samba_cmdline_daemon_cfg *cmdline_daemon_cfg = NULL; struct poptOption long_options[] = { POPT_AUTOHELP - { - .longName = "foreground", - .shortName = 'F', - .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = OPT_FORK, - .descrip = "Daemon in foreground mode", - }, - { - .longName = "no-process-group", - .shortName = 0, - .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = OPT_NO_PROCESS_GROUP, - .descrip = "Don't create a new process group", - }, - { - .longName = "daemon", - .shortName = 'D', - .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = OPT_DAEMON, - .descrip = "Become a daemon (default)", - }, - { - .longName = "interactive", - .shortName = 'i', - .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = 'i', - .descrip = "Interactive mode", - }, { .longName = "no-caching", .shortName = 'n', @@ -1646,6 +1607,7 @@ int main(int argc, const char **argv) .descrip = "Disable caching", }, POPT_COMMON_SAMBA + POPT_COMMON_DAEMON POPT_COMMON_VERSION POPT_TABLEEND }; @@ -1691,6 +1653,8 @@ int main(int argc, const char **argv) exit(1); } + cmdline_daemon_cfg = samba_cmdline_get_daemon_cfg(); + pc = samba_popt_get_context(getprogname(), argc, argv, long_options, 0); if (pc == NULL) { DBG_ERR("Failed to setup popt parser!\n"); @@ -1700,19 +1664,6 @@ int main(int argc, const char **argv) while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { - /* Don't become a daemon */ - case OPT_DAEMON: - is_daemon = True; - break; - case 'i': - interactive = True; - break; - case OPT_FORK: - Fork = false; - break; - case OPT_NO_PROCESS_GROUP: - no_process_group = true; - break; case 'n': opt_nocache = true; break; @@ -1737,7 +1688,7 @@ int main(int argc, const char **argv) set_remote_machine_name("winbindd", False); dump_core_setup("winbindd", lp_logfile(talloc_tos(), lp_sub)); - if (is_daemon && interactive) { + if (cmdline_daemon_cfg->daemon && cmdline_daemon_cfg->interactive) { d_fprintf(stderr,"\nERROR: " "Option -i|--interactive is not allowed together with -D|--daemon\n\n"); poptPrintUsage(pc, stderr, 0); @@ -1745,12 +1696,18 @@ int main(int argc, const char **argv) } log_stdout = (debug_get_log_type() == DEBUG_STDOUT); - if (interactive) { - Fork = true; + if (cmdline_daemon_cfg->interactive) { + /* + * libcmdline POPT_DAEMON callback sets "fork" to false if "-i" + * for interactive is passed on the commandline. Set it back to + * true. TODO: check if this is correct, smbd and nmbd don't do + * this. + */ + cmdline_daemon_cfg->fork = true; log_stdout = true; } - if (log_stdout && Fork) { + if (log_stdout && cmdline_daemon_cfg->fork) { d_fprintf(stderr, "\nERROR: " "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n"); poptPrintUsage(pc, stderr, 0); @@ -1768,11 +1725,6 @@ int main(int argc, const char **argv) } } - if (log_stdout) { - setup_logging("winbindd", DEBUG_STDOUT); - } else { - setup_logging("winbindd", DEBUG_FILE); - } reopen_logs(); DEBUG(0,("winbindd version %s started.\n", samba_version_string())); @@ -1910,7 +1862,9 @@ int main(int argc, const char **argv) BlockSignals(False, SIGCHLD); if (!interactive) { - become_daemon(Fork, no_process_group, log_stdout); + become_daemon(cmdline_daemon_cfg->fork, + cmdline_daemon_cfg->no_process_group, + log_stdout); } else { daemon_status("winbindd", "Starting process ..."); } @@ -1922,8 +1876,11 @@ int main(int argc, const char **argv) * If we're interactive we want to set our own process group for * signal management. */ - if (interactive && !no_process_group) + if (cmdline_daemon_cfg->interactive && + !cmdline_daemon_cfg->no_process_group) + { setpgid( (pid_t)0, (pid_t)0); + } #endif TimeInit(); @@ -1957,7 +1914,8 @@ int main(int argc, const char **argv) exit_daemon(nt_errstr(status), map_errno_from_nt_status(status)); } - winbindd_register_handlers(global_messaging_context(), !Fork); + winbindd_register_handlers(global_messaging_context(), + !cmdline_daemon_cfg->fork); if (!messaging_parent_dgm_cleanup_init(global_messaging_context())) { exit(1); -- 2.31.1 From c52ecb9ee3418aebc07554f35b823b09583c540c Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 3 Sep 2021 14:04:22 +0200 Subject: [PATCH 6/6] s4/samba: POPT_COMMON_DAEMON MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note: this also changes logging to go to stderr instead of stdout which is the same behaviour as smbd, nmbd and winbindd (starting with 4.15). BUG: https://bugzilla.samba.org/show_bug.cgi?id=14803 RN: smbd/winbindd started in daemon mode generate output on stderr/stdout Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke Autobuild-User(master): Ralph Böhme Autobuild-Date(master): Mon Sep 6 14:23:15 UTC 2021 on sn-devel-184 (cherry picked from commit 28686f8713958726085bd38a0889aa7725c95371) --- source4/samba/server.c | 88 ++++++++++-------------------------------- 1 file changed, 20 insertions(+), 68 deletions(-) diff --git a/source4/samba/server.c b/source4/samba/server.c index d22183df705..d8948337847 100644 --- a/source4/samba/server.c +++ b/source4/samba/server.c @@ -505,10 +505,7 @@ static int binary_smbd_main(TALLOC_CTX *mem_ctx, int argc, const char *argv[]) { - bool opt_daemon = false; - bool opt_fork = true; - bool opt_interactive = false; - bool opt_no_process_group = false; + struct samba_cmdline_daemon_cfg *cmdline_daemon_cfg = NULL; bool db_is_backup = false; int opt; int ret; @@ -523,36 +520,11 @@ static int binary_smbd_main(TALLOC_CTX *mem_ctx, int max_runtime = 0; struct stat st; enum { - OPT_DAEMON = 1000, - OPT_FOREGROUND, - OPT_INTERACTIVE, - OPT_PROCESS_MODEL, + OPT_PROCESS_MODEL = 1000, OPT_SHOW_BUILD, - OPT_NO_PROCESS_GROUP, }; struct poptOption long_options[] = { POPT_AUTOHELP - { - .longName = "daemon", - .shortName = 'D', - .argInfo = POPT_ARG_NONE, - .val = OPT_DAEMON, - .descrip = "Become a daemon (default)", - }, - { - .longName = "foreground", - .shortName = 'F', - .argInfo = POPT_ARG_NONE, - .val = OPT_FOREGROUND, - .descrip = "Run the daemon in foreground", - }, - { - .longName = "interactive", - .shortName = 'i', - .argInfo = POPT_ARG_NONE, - .val = OPT_INTERACTIVE, - .descrip = "Run interactive (not a daemon)", - }, { .longName = "model", .shortName = 'M', @@ -576,13 +548,8 @@ static int binary_smbd_main(TALLOC_CTX *mem_ctx, .val = OPT_SHOW_BUILD, .descrip = "show build info", }, - { - .longName = "no-process-group", - .argInfo = POPT_ARG_NONE, - .val = OPT_NO_PROCESS_GROUP, - .descrip = "Don't create a new process group", - }, POPT_COMMON_SAMBA + POPT_COMMON_DAEMON POPT_COMMON_VERSION POPT_TABLEEND }; @@ -590,7 +557,6 @@ static int binary_smbd_main(TALLOC_CTX *mem_ctx, struct tevent_signal *se = NULL; struct samba_tevent_trace_state *samba_tevent_trace_state = NULL; struct loadparm_context *lp_ctx = NULL; - bool log_stdout = false; bool ok; setproctitle("root process"); @@ -604,6 +570,8 @@ static int binary_smbd_main(TALLOC_CTX *mem_ctx, exit(1); } + cmdline_daemon_cfg = samba_cmdline_get_daemon_cfg(); + pc = samba_popt_get_context(binary_name, argc, argv, @@ -617,24 +585,12 @@ static int binary_smbd_main(TALLOC_CTX *mem_ctx, while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { - case OPT_DAEMON: - opt_daemon = true; - break; - case OPT_FOREGROUND: - opt_fork = false; - break; - case OPT_INTERACTIVE: - opt_interactive = true; - break; case OPT_PROCESS_MODEL: model = poptGetOptArg(pc); break; case OPT_SHOW_BUILD: show_build(); break; - case OPT_NO_PROCESS_GROUP: - opt_no_process_group = true; - break; default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); @@ -643,15 +599,16 @@ static int binary_smbd_main(TALLOC_CTX *mem_ctx, } } - if (opt_daemon && opt_interactive) { + if (cmdline_daemon_cfg->daemon && cmdline_daemon_cfg->interactive) { fprintf(stderr,"\nERROR: " "Option -i|--interactive is " "not allowed together with -D|--daemon\n\n"); poptPrintUsage(pc, stderr, 0); return 1; - } else if (!opt_interactive && opt_fork) { + } else if (!cmdline_daemon_cfg->interactive && + cmdline_daemon_cfg->fork) { /* default is --daemon */ - opt_daemon = true; + cmdline_daemon_cfg->daemon = true; } poptFreeContext(pc); @@ -660,16 +617,6 @@ static int binary_smbd_main(TALLOC_CTX *mem_ctx, talloc_enable_null_tracking(); - log_stdout = (debug_get_log_type() == DEBUG_STDOUT); - if (opt_interactive) { - log_stdout = true; - } - - if (log_stdout) { - setup_logging(binary_name, DEBUG_STDOUT); - } else { - setup_logging(binary_name, DEBUG_FILE); - } setup_signals(); /* we want total control over the permissions on created files, @@ -695,10 +642,12 @@ static int binary_smbd_main(TALLOC_CTX *mem_ctx, return 1; } - if (opt_daemon) { + if (cmdline_daemon_cfg->daemon) { DBG_NOTICE("Becoming a daemon.\n"); - become_daemon(opt_fork, opt_no_process_group, false); - } else if (!opt_interactive) { + become_daemon(cmdline_daemon_cfg->fork, + cmdline_daemon_cfg->no_process_group, + false); + } else if (!cmdline_daemon_cfg->interactive) { daemon_status("samba", "Starting process..."); } @@ -794,7 +743,7 @@ static int binary_smbd_main(TALLOC_CTX *mem_ctx, samba_tevent_trace_callback, samba_tevent_trace_state); - if (opt_interactive) { + if (cmdline_daemon_cfg->interactive) { /* terminate when stdin goes away */ stdin_event_flags = TEVENT_FD_READ; } else { @@ -807,8 +756,11 @@ static int binary_smbd_main(TALLOC_CTX *mem_ctx, * If we're interactive we want to set our own process group for * signal management, unless --no-process-group specified. */ - if (opt_interactive && !opt_no_process_group) + if (cmdline_daemon_cfg->interactive && + !cmdline_daemon_cfg->no_process_group) + { setpgid((pid_t)0, (pid_t)0); + } #endif /* catch EOF on stdin */ @@ -1014,7 +966,7 @@ static int binary_smbd_main(TALLOC_CTX *mem_ctx, } } - if (!opt_interactive) { + if (!cmdline_daemon_cfg->interactive) { daemon_ready("samba"); } -- 2.31.1