#include "includes.h"
#include "system/filesys.h"
#include "lib/util/server_id.h"
-#include "popt_common.h"
+#include "lib/util/close_low_fd.h"
+#include "lib/cmdline/cmdline.h"
+#include "locking/share_mode_lock.h"
#include "smbd/smbd.h"
#include "smbd/globals.h"
+#include "smbd/smbXsrv_open.h"
#include "registry/reg_init_full.h"
#include "libcli/auth/schannel.h"
#include "secrets.h"
#include "../lib/util/memcache.h"
#include "ctdbd_conn.h"
+#include "lib/util/util_process.h"
#include "util_cluster.h"
#include "printing/queue_process.h"
-#include "rpc_server/rpc_service_setup.h"
#include "rpc_server/rpc_config.h"
#include "passdb.h"
#include "auth.h"
#include "lib/util/sys_rw.h"
#include "cleanupdb.h"
#include "g_lock.h"
-#include "rpc_server/epmd.h"
-#include "rpc_server/lsasd.h"
-#include "rpc_server/fssd.h"
-#include "rpc_server/mdssd.h"
+#include "lib/global_contexts.h"
+#include "source3/lib/substitute.h"
#ifdef CLUSTER_SUPPORT
#include "ctdb_protocol.h"
What to do when smb.conf is updated.
********************************************************************/
+static NTSTATUS messaging_send_to_children(struct messaging_context *msg_ctx,
+ uint32_t msg_type, DATA_BLOB* data);
+
static void smbd_parent_conf_updated(struct messaging_context *msg,
void *private_data,
uint32_t msg_type,
struct server_id server_id,
DATA_BLOB *data)
{
- struct tevent_context *ev_ctx =
- talloc_get_type_abort(private_data, struct tevent_context);
bool ok;
DEBUG(10,("smbd_parent_conf_updated: Got message saying smb.conf was "
"updated. Reloading.\n"));
change_to_root_user();
reload_services(NULL, NULL, false);
- printing_subsystem_update(ev_ctx, msg, false);
ok = reinit_guest_session_info(NULL);
if (!ok) {
DBG_ERR("Failed to reinit guest info\n");
}
-}
-
-/*******************************************************************
- Delete a statcache entry.
- ********************************************************************/
-
-static void smb_stat_cache_delete(struct messaging_context *msg,
- void *private_data,
- uint32_t msg_tnype,
- struct server_id server_id,
- DATA_BLOB *data)
-{
- const char *name = (const char *)data->data;
- DEBUG(10,("smb_stat_cache_delete: delete name %s\n", name));
- stat_cache_delete(name);
+ messaging_send_to_children(msg, MSG_SMB_CONF_UPDATED, NULL);
}
/****************************************************************************
{
DBG_NOTICE("notifyd: Reloading services after SIGHUP\n");
reload_services(NULL, NULL, false);
+ reopen_logs();
}
static bool smbd_notifyd_init(struct messaging_context *msg, bool interactive,
{
struct tevent_context *ev = messaging_tevent_context(msg);
struct tevent_req *req;
+ struct tevent_signal *se = NULL;
pid_t pid;
NTSTATUS status;
bool ok;
- struct tevent_signal *se;
if (interactive) {
req = notifyd_req(msg, ev);
}
if (pid != 0) {
- if (am_parent != 0) {
+ if (am_parent != NULL) {
add_child_pid(am_parent, pid);
}
*ppid = pid_to_procid(pid);
return true;
}
- status = smbd_reinit_after_fork(msg, ev, true, "smbd-notifyd");
+ status = smbd_reinit_after_fork(msg, ev, true);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("%s: reinit_after_fork failed: %s\n",
__func__, nt_errstr(status)));
exit(1);
}
+ process_set_title("smbd-notifyd", "notifyd");
+
+ reopen_logs();
+
/* Set up sighup handler for notifyd */
se = tevent_add_signal(ev,
ev,
}
}
+static void cleanupd_sig_hup_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *pvt)
+{
+ DBG_NOTICE("cleanupd: Reloading services after SIGHUP\n");
+ reopen_logs();
+}
+
static void cleanupd_stopped(struct tevent_req *req);
static bool cleanupd_init(struct messaging_context *msg, bool interactive,
{
struct tevent_context *ev = messaging_tevent_context(msg);
struct server_id parent_id = messaging_server_id(msg);
+ struct tevent_signal *se = NULL;
struct tevent_req *req;
pid_t pid;
NTSTATUS status;
close(up_pipe[0]);
- status = smbd_reinit_after_fork(msg, ev, true, "cleanupd");
+ status = smbd_reinit_after_fork(msg, ev, true);
if (!NT_STATUS_IS_OK(status)) {
DBG_WARNING("reinit_after_fork failed: %s\n",
nt_errstr(status));
exit(1);
}
+ process_set_title("smbd-cleanupd", "cleanupd");
+
+ se = tevent_add_signal(ev,
+ ev,
+ SIGHUP,
+ 0,
+ cleanupd_sig_hup_handler,
+ NULL);
+ if (se == NULL) {
+ DBG_ERR("Could not add SIGHUP handler\n");
+ exit(1);
+ }
+
req = smbd_cleanupd_send(msg, ev, msg, parent_id.pid);
if (req == NULL) {
DBG_WARNING("smbd_cleanupd_send failed\n");
smb_set_close_on_exec(fd);
if (s->parent->interactive) {
- reinit_after_fork(msg_ctx, ev, true, NULL);
+ reinit_after_fork(msg_ctx, ev, true);
smbd_process(ev, msg_ctx, fd, true);
exit_server_cleanly("end of interactive mode");
return;
pid = fork();
if (pid == 0) {
+ char addrstr[INET6_ADDRSTRLEN];
NTSTATUS status = NT_STATUS_OK;
/*
* them, counting worker smbds. */
CatchChild();
- status = smbd_reinit_after_fork(msg_ctx, ev, true, NULL);
+ status = smbd_reinit_after_fork(msg_ctx, ev, true);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,
NT_STATUS_TOO_MANY_OPENED_FILES)) {
smb_panic("reinit_after_fork() failed");
}
+ print_sockaddr(addrstr, sizeof(addrstr), &addr);
+ process_set_title("smbd[%s]", "client [%s]", addrstr);
+
smbd_process(ev, msg_ctx, fd, false);
exit:
exit_server_cleanly("end of child");
* writes only two messages for each child
* started/finished. But each child writes,
* say, 50 messages also in logserver.smb,
- * begining with the debug_count of the
+ * beginning with the debug_count of the
* parent, before the child opens its own log
* file logserver.client. In a worst case
* scenario the size of logserver.smb would be
}
s->parent = parent;
- s->fd = open_socket_in(SOCK_STREAM,
- port,
- parent->sockets == NULL ? 0 : 2,
- ifss,
- true);
- if (s->fd == -1) {
- DEBUG(0,("smbd_open_one_socket: open_socket_in: "
- "%s\n", strerror(errno)));
+
+ s->fd = open_socket_in(SOCK_STREAM, ifss, port, true);
+ if (s->fd < 0) {
+ int err = -(s->fd);
+ DBG_ERR("open_socket_in failed: %s\n", strerror(err));
TALLOC_FREE(s);
/*
* We ignore an error here, as we've done before
messaging_register(msg_ctx, NULL, MSG_SHUTDOWN, msg_exit_server);
messaging_register(msg_ctx, ev_ctx, MSG_SMB_CONF_UPDATED,
smbd_parent_conf_updated);
- messaging_register(msg_ctx, NULL, MSG_SMB_STAT_CACHE_DELETE,
- smb_stat_cache_delete);
messaging_register(msg_ctx, NULL, MSG_DEBUG, smbd_msg_debug);
messaging_register(msg_ctx, NULL, MSG_SMB_FORCE_TDIS,
smb_parent_send_to_children);
+ messaging_register(msg_ctx, NULL, MSG_SMB_FORCE_TDIS_DENIED,
+ smb_parent_send_to_children);
messaging_register(msg_ctx, NULL, MSG_SMB_KILL_CLIENT_IP,
smb_parent_send_to_children);
messaging_register(msg_ctx, NULL, MSG_SMB_TELL_NUM_CHILDREN,
* set from the config file.
*/
- if (!init_names())
- return False;
-
if (!secrets_init())
return False;
void *siginfo,
void *private_data)
{
- struct smbd_parent_context *parent =
- talloc_get_type_abort(private_data,
- struct smbd_parent_context);
-
change_to_root_user();
DEBUG(1,("parent: Reloading services after SIGHUP\n"));
reload_services(NULL, NULL, false);
-
- printing_subsystem_update(parent->ev_ctx, parent->msg_ctx, true);
}
struct smbd_claim_version_state {
static void smbd_claim_version_parser(struct server_id exclusive,
size_t num_shared,
- struct server_id *shared,
+ const struct server_id *shared,
const uint8_t *data,
size_t datalen,
void *private_data)
const char *version)
{
const char *name = "samba_version_string";
+ const TDB_DATA key = string_term_tdb_data(name);
struct smbd_claim_version_state state;
struct g_lock_ctx *ctx;
NTSTATUS status;
return NT_STATUS_UNSUCCESSFUL;
}
- status = g_lock_lock(ctx, string_term_tdb_data(name), G_LOCK_READ,
- (struct timeval) { .tv_sec = 60 });
+ status = g_lock_lock(ctx,
+ key,
+ G_LOCK_READ,
+ (struct timeval) { .tv_sec = 60 },
+ NULL,
+ NULL);
if (!NT_STATUS_IS_OK(status)) {
DBG_WARNING("g_lock_lock(G_LOCK_READ) failed: %s\n",
nt_errstr(status));
state = (struct smbd_claim_version_state) { .mem_ctx = ctx };
- status = g_lock_dump(ctx, string_term_tdb_data(name),
- smbd_claim_version_parser, &state);
+ status = g_lock_dump(ctx, key, smbd_claim_version_parser, &state);
if (!NT_STATUS_IS_OK(status) &&
!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
DBG_ERR("Could not read samba_version_string\n");
- g_lock_unlock(ctx, string_term_tdb_data(name));
+ g_lock_unlock(ctx, key);
TALLOC_FREE(ctx);
return status;
}
return NT_STATUS_OK;
}
- status = g_lock_lock(ctx, string_term_tdb_data(name), G_LOCK_WRITE,
- (struct timeval) { .tv_sec = 60 });
+ status = g_lock_lock(ctx,
+ key,
+ G_LOCK_UPGRADE,
+ (struct timeval) { .tv_sec = 60 },
+ NULL,
+ NULL);
if (!NT_STATUS_IS_OK(status)) {
DBG_WARNING("g_lock_lock(G_LOCK_WRITE) failed: %s\n",
nt_errstr(status));
return NT_STATUS_SXS_VERSION_CONFLICT;
}
- status = g_lock_write_data(ctx, string_term_tdb_data(name),
- (const uint8_t *)version,
- strlen(version)+1);
+ status = g_lock_write_data(
+ ctx, key, (const uint8_t *)version, strlen(version)+1);
if (!NT_STATUS_IS_OK(status)) {
DBG_WARNING("g_lock_write_data failed: %s\n",
nt_errstr(status));
return status;
}
- status = g_lock_lock(ctx, string_term_tdb_data(name), G_LOCK_READ,
- (struct timeval) { .tv_sec = 60 });
+ status = g_lock_lock(ctx,
+ key,
+ G_LOCK_DOWNGRADE,
+ (struct timeval) { .tv_sec = 60 },
+ NULL,
+ NULL);
if (!NT_STATUS_IS_OK(status)) {
DBG_WARNING("g_lock_lock(G_LOCK_READ) failed: %s\n",
nt_errstr(status));
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;
int opt;
poptContext pc;
- bool print_build_options = False;
struct server_id main_server_id = {0};
- enum {
- OPT_DAEMON = 1000,
- OPT_INTERACTIVE,
- OPT_FORK,
- OPT_NO_PROCESS_GROUP,
- OPT_LOG_STDOUT
- };
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 = "log-stdout",
- .shortName = 'S',
- .argInfo = POPT_ARG_NONE,
- .arg = NULL,
- .val = OPT_LOG_STDOUT,
- .descrip = "Log to stdout" ,
- },
{
.longName = "build-options",
.shortName = 'b',
.descrip = "Set profiling level","PROFILE_LEVEL",
},
POPT_COMMON_SAMBA
+ POPT_COMMON_DAEMON
+ POPT_COMMON_VERSION
POPT_TABLEEND
};
struct smbd_parent_context *parent = NULL;
struct tevent_signal *se;
int profiling_level;
char *np_dir = NULL;
+ const struct loadparm_substitution *lp_sub =
+ loadparm_s3_global_substitution();
static const struct smbd_shim smbd_shim_fns =
{
- .send_stat_cache_delete_message = smbd_send_stat_cache_delete_message,
.change_to_root_user = smbd_change_to_root_user,
.become_authenticated_pipe_user = smbd_become_authenticated_pipe_user,
.unbecome_authenticated_pipe_user = smbd_unbecome_authenticated_pipe_user,
.exit_server = smbd_exit_server,
.exit_server_cleanly = smbd_exit_server_cleanly,
};
+ bool ok;
+
+ setproctitle_init(argc, discard_const(argv), environ);
/*
* Do this before any other talloc operation
talloc_enable_null_tracking();
frame = talloc_stackframe();
- setup_logging(argv[0], DEBUG_DEFAULT_STDOUT);
-
smb_init_locale();
set_smbd_shim(&smbd_shim_fns);
set_auth_parameters(argc,argv);
#endif
- pc = poptGetContext("smbd", argc, argv, long_options, 0);
+ ok = samba_cmdline_init(frame,
+ SAMBA_CMDLINE_CONFIG_SERVER,
+ true /* require_smbconf */);
+ if (!ok) {
+ DBG_ERR("Failed to setup cmdline parser!\n");
+ exit(ENOMEM);
+ }
+
+ 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 get popt context!\n");
+ exit(ENOMEM);
+ }
+
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 OPT_LOG_STDOUT:
- log_stdout = true;
- break;
case 'b':
- print_build_options = True;
+ build_options(true); /* Display output to screen as well as debug */
+ exit(0);
break;
default:
d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
}
poptFreeContext(pc);
- if (interactive) {
- Fork = False;
- log_stdout = True;
- }
+ log_stdout = (debug_get_log_type() == DEBUG_STDOUT);
- if (log_stdout) {
- setup_logging(argv[0], DEBUG_STDOUT);
- } else {
- setup_logging(argv[0], DEBUG_FILE);
- }
-
- if (print_build_options) {
- build_options(True); /* Display output to screen as well as debug */
- exit(0);
+ if (cmdline_daemon_cfg->interactive) {
+ log_stdout = True;
}
#ifdef HAVE_SETLUID
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);
}
gain_root_privilege();
gain_root_group_privilege();
- fault_setup();
- dump_core_setup("smbd", lp_logfile(talloc_tos()));
+ dump_core_setup("smbd", lp_logfile(talloc_tos(), lp_sub));
/* we are never interested in SIGPIPE */
BlockSignals(True,SIGPIPE);
BlockSignals(True,SIGUSR2);
#endif
- /* POSIX demands that signals are inherited. If the invoking process has
- * these signals masked, we will have problems, as we won't recieve them. */
+ /*
+ * POSIX demands that signals are inherited. If the invoking
+ * process has these signals masked, we will have problems, as
+ * we won't receive them.
+ */
BlockSignals(False, SIGHUP);
BlockSignals(False, SIGUSR1);
BlockSignals(False, SIGTERM);
DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
(int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid()));
- /* Output the build options to the debug log */
+ /* Output the build options to the debug log */
build_options(False);
if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4) {
exit(1);
}
- if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
- DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
- exit(1);
- }
-
/*
* This calls unshare(CLONE_FS); on linux
* in order to check if the running kernel/container
exit(1);
}
- if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
- && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
- DEBUG(0, ("server role = 'active directory domain controller' not compatible with running smbd standalone. \n"));
- DEBUGADD(0, ("You should start 'samba' instead, and it will control starting smbd if required\n"));
- exit(1);
+ if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
+ if (!lp_parm_bool(-1, "server role check", "inhibit", false)) {
+ DBG_ERR("server role = 'active directory domain controller' not compatible with running smbd standalone. \n");
+ DEBUGADD(0, ("You should start 'samba' instead, and it will control starting smbd if required\n"));
+ exit(1);
+ }
+ /* Main 'samba' daemon will notify */
+ daemon_sd_notifications(false);
}
/* ...NOTE... Log files are working from this point! */
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 ...");
}
#ifdef HAVE_SETPGID
* 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()))
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);
+ status = reinit_after_fork(msg_ctx, ev_ctx, false);
if (!NT_STATUS_IS_OK(status)) {
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
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;
am_parent = parent;
exit_daemon("smbd can not open secrets.tdb", EACCES);
}
- if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) {
+ if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC || lp_server_role() == ROLE_IPA_DC) {
struct loadparm_context *lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
if (!open_schannel_session_store(NULL, lp_ctx)) {
exit_daemon("ERROR: Samba cannot open schannel store for secured NETLOGON operations.", EACCES);
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);
}
after the fork on every single connection. This is a small
performance improvment and reduces the total number of system
fds used. */
- if (!share_info_db_init()) {
+ status = share_info_db_init();
+ if (!NT_STATUS_IS_OK(status)) {
exit_daemon("ERROR: failed to load share info db.", EACCES);
}
return -1;
}
- if (is_daemon && !interactive) {
- if (rpc_epmapper_daemon() == RPC_DAEMON_FORK) {
- start_epmd(ev_ctx, msg_ctx);
- }
- }
-
- status = dcesrv_ep_setup(ev_ctx, msg_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- DBG_ERR("Failed to setup RPC server: %s\n", nt_errstr(status));
- exit_daemon("Samba cannot setup ep pipe", EACCES);
- }
-
- if (is_daemon && !interactive) {
+ if (!cmdline_daemon_cfg->interactive) {
daemon_ready("smbd");
}
- /* 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 (rpc_lsasd_daemon() == RPC_DAEMON_FORK) {
- start_lsasd(ev_ctx, msg_ctx);
- }
-
- if (rpc_fss_daemon() == RPC_DAEMON_FORK) {
- start_fssd(ev_ctx, msg_ctx);
- }
-
- if (!lp__disable_spoolss() &&
- (rpc_spoolss_daemon() != RPC_DAEMON_DISABLED)) {
- bool bgq = lp_parm_bool(-1, "smbd", "backgroundqueue", true);
-
- if (!printing_subsystem_init(ev_ctx, msg_ctx, true, bgq)) {
- exit_daemon("Samba failed to init printing subsystem", EACCES);
- }
- }
-
-#ifdef WITH_SPOTLIGHT
- if ((rpc_mdssvc_mode() == RPC_SERVICE_MODE_EXTERNAL) &&
- (rpc_mdssd_daemon() == RPC_DAEMON_FORK)) {
- start_mdssd(ev_ctx, msg_ctx);
- }
-#endif
- } else if (!lp__disable_spoolss() &&
- (rpc_spoolss_daemon() != RPC_DAEMON_DISABLED)) {
- if (!printing_subsystem_init(ev_ctx, msg_ctx, false, false)) {
- exit(1);
- }
- }
-
- if (!is_daemon) {
- int sock;
+ if (!cmdline_daemon_cfg->daemon) {
+ int ret, sock;
/* inetd mode */
TALLOC_FREE(frame);
sock = dup(0);
/* close stdin, stdout (if not logging to it), but not stderr */
- close_low_fds(true, !debug_get_output_is_stdout(), false);
+ ret = close_low_fd(0);
+ if (ret != 0) {
+ DBG_ERR("close_low_fd(0) failed: %s\n", strerror(ret));
+ return 1;
+ }
+ if (!debug_get_output_is_stdout()) {
+ ret = close_low_fd(1);
+ if (ret != 0) {
+ DBG_ERR("close_low_fd(1) failed: %s\n",
+ strerror(ret));
+ return 1;
+ }
+ }
#ifdef HAVE_ATEXIT
atexit(killkids);
if (!open_sockets_smbd(parent, ev_ctx, msg_ctx, ports))
exit_server("open_sockets_smbd() failed");
- /* do a printer update now that all messaging has been set up,
- * before we allow clients to start connecting */
- if (!lp__disable_spoolss() &&
- (rpc_spoolss_daemon() != RPC_DAEMON_DISABLED)) {
- printing_subsystem_update(ev_ctx, msg_ctx, false);
- }
-
TALLOC_FREE(frame);
/* 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
*/
struct stat st;
if (fstat(0, &st) != 0) {
- return false;
+ return 1;
}
if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
tevent_add_fd(ev_ctx,