#include "serverid.h"
#include "auth.h"
#include "messages.h"
+#include "../lib/util/pidfile.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
bool ret;
if (lp_loaded()) {
- const char *fname = lp_configfile();
+ char *fname = lp_configfile(talloc_tos());
if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
set_dyn_CONFIGFILE(fname);
}
+ TALLOC_FREE(fname);
}
/* if this is a child, restore the logfile to the special
}
reopen_logs();
- ret = lp_load(get_dyn_CONFIGFILE(),False,False,True,True);
+ ret = lp_load_global(get_dyn_CONFIGFILE());
reopen_logs();
load_interfaces();
if (is_parent) {
serverid_deregister(procid_self());
- pidfile_unlink();
+ pidfile_unlink(lp_piddir(), "winbindd");
}
exit(0);
terminate(*is_parent);
}
+/*
+ handle stdin becoming readable when we are in --foreground mode
+ */
+static void winbindd_stdin_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data)
+{
+ char c;
+ if (read(0, &c, 1) != 1) {
+ bool *is_parent = talloc_get_type_abort(private_data, bool);
+
+ /* we have reached EOF on stdin, which means the
+ parent has exited. Shutdown the server */
+ DEBUG(0,("EOF on stdin (is_parent=%d)\n",
+ (int)*is_parent));
+ terminate(*is_parent);
+ }
+}
+
bool winbindd_setup_sig_term_handler(bool parent)
{
struct tevent_signal *se;
return true;
}
+bool winbindd_setup_stdin_handler(bool parent, bool foreground)
+{
+ bool *is_parent;
+
+ if (foreground) {
+ is_parent = talloc(winbind_event_context(), bool);
+ if (!is_parent) {
+ return false;
+ }
+
+ *is_parent = parent;
+
+ /* 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
+ */
+ tevent_add_fd(winbind_event_context(), is_parent, 0, TEVENT_FD_READ, winbindd_stdin_handler, is_parent);
+ }
+
+ return true;
+}
+
static void winbindd_sig_hup_handler(struct tevent_context *ev,
struct tevent_signal *se,
int signum,
* so we don't block the main winbindd and the validation
* code can safely use fork/waitpid...
*/
- child_pid = sys_fork();
+ child_pid = fork();
if (child_pid == -1) {
DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
{ WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
{ WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
- /* WINS functions */
-
- { WINBINDD_WINS_BYNAME, winbindd_wins_byname, "WINS_BYNAME" },
-
/* End of list */
{ WINBINDD_NUM_CMDS, NULL, "NONE" }
{ WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
winbindd_pam_chng_pswd_auth_crap_send,
winbindd_pam_chng_pswd_auth_crap_recv },
- { WINBINDD_WINS_BYIP, "PING",
+ { WINBINDD_WINS_BYIP, "WINS_BYIP",
winbindd_wins_byip_send, winbindd_wins_byip_recv },
+ { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
+ winbindd_wins_byname_send, winbindd_wins_byname_recv },
{ 0, NULL, NULL, NULL }
};
char *get_winbind_priv_pipe_dir(void)
{
- return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR);
+ return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
}
static bool winbindd_setup_listeners(void)
struct winbindd_listen_state *pub_state = NULL;
struct winbindd_listen_state *priv_state = NULL;
struct tevent_fd *fde;
+ int rc;
pub_state = talloc(winbind_event_context(),
struct winbindd_listen_state);
if (pub_state->fd == -1) {
goto failed;
}
+ rc = listen(pub_state->fd, 5);
+ if (rc < 0) {
+ goto failed;
+ }
fde = tevent_add_fd(winbind_event_context(), pub_state, pub_state->fd,
TEVENT_FD_READ, winbindd_listen_fde_handler,
if (priv_state->fd == -1) {
goto failed;
}
+ rc = listen(priv_state->fd, 5);
+ if (rc < 0) {
+ goto failed;
+ }
fde = tevent_add_fd(winbind_event_context(), priv_state,
priv_state->fd, TEVENT_FD_READ,
return !opt_nocache;
}
-void winbindd_register_handlers(void)
+void winbindd_register_handlers(bool foreground)
{
/* Setup signal handlers */
if (!winbindd_setup_sig_term_handler(true))
exit(1);
+ if (!winbindd_setup_stdin_handler(true, foreground))
+ exit(1);
if (!winbindd_setup_sig_hup_handler(NULL))
exit(1);
if (!winbindd_setup_sig_chld_handler())
/* get broadcast messages */
if (!serverid_register(procid_self(),
- FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP)) {
+ FLAG_MSG_GENERAL |
+ FLAG_MSG_WINBIND |
+ FLAG_MSG_DBWRAP)) {
DEBUG(1, ("Could not register myself in serverid.tdb\n"));
exit(1);
}
talloc_enable_null_tracking();
frame = talloc_stackframe();
+ setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
+
/* glibc (?) likes to print "User defined signal 1" and exit if a
SIGUSR[12] is received before a handler is installed */
CatchSignal(SIGUSR2, SIG_IGN);
fault_setup();
- dump_core_setup("winbindd", lp_logfile());
+ dump_core_setup("winbindd", lp_logfile(talloc_tos()));
load_case_tables();
}
}
+ /* We call dump_core_setup one more time because the command line can
+ * set the log file or the log-basename and this will influence where
+ * cores are stored. Without this call get_dyn_LOGFILEBASE will be
+ * the default value derived from build's prefix. For EOM this value
+ * is often not related to the path where winbindd is actually run
+ * in production.
+ */
+ dump_core_setup("winbindd", lp_logfile(talloc_tos()));
if (is_daemon && interactive) {
d_fprintf(stderr,"\nERROR: "
"Option -i|--interactive is not allowed together with -D|--daemon\n\n");
SAFE_FREE(lfile);
}
}
+
if (log_stdout) {
setup_logging("winbindd", DEBUG_STDOUT);
} else {
DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
exit(1);
}
+ /* After parsing the configuration file we setup the core path one more time
+ * as the log file might have been set in the configuration and cores's
+ * path is by default basename(lp_logfile()).
+ */
+ dump_core_setup("winbindd", lp_logfile(talloc_tos()));
/* Initialise messaging system */
mkdir(lp_lockdir(), 0755);
}
+ if (!directory_exist(lp_piddir())) {
+ mkdir(lp_piddir(), 0755);
+ }
+
/* Setup names. */
if (!init_names())
if (!interactive)
become_daemon(Fork, no_process_group, log_stdout);
- pidfile_create("winbindd");
+ pidfile_create(lp_piddir(), "winbindd");
#if HAVE_SETPGID
/*
status = reinit_after_fork(winbind_messaging_context(),
winbind_event_context(),
- procid_self(), false);
+ false);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("reinit_after_fork() failed\n"));
exit(1);
}
- winbindd_register_handlers();
+ /*
+ * Do not initialize the parent-child-pipe before becoming
+ * a daemon: this is used to detect a died parent in the child
+ * process.
+ */
+ status = init_before_fork();
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("init_before_fork failed: %s\n", nt_errstr(status)));
+ exit(1);
+ }
+
+ winbindd_register_handlers(!Fork);
- status = init_system_info();
+ status = init_system_session_info();
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("ERROR: failed to setup system user info: %s.\n",
nt_errstr(status)));