-/*
+/*
Unix SMB/CIFS implementation.
Winbind daemon for ntdom nss module
*/
#include "includes.h"
+#include "popt_common.h"
#include "winbindd.h"
-#include "../../nsswitch/libwbclient/wbc_async.h"
+#include "nsswitch/winbind_client.h"
+#include "nsswitch/wb_reqtrans.h"
+#include "ntdomain.h"
+#include "../librpc/gen_ndr/srv_lsa.h"
+#include "../librpc/gen_ndr/srv_samr.h"
+#include "secrets.h"
+#include "idmap.h"
+#include "lib/addrchange.h"
+#include "serverid.h"
+#include "auth.h"
+#include "messages.h"
+#include "../lib/util/pidfile.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
+static bool client_is_idle(struct winbindd_cli_state *state);
static void remove_client(struct winbindd_cli_state *state);
static bool opt_nocache = False;
extern bool override_logfile;
-struct event_context *winbind_event_context(void)
+struct tevent_context *winbind_event_context(void)
{
- static struct event_context *ctx;
+ static struct tevent_context *ev = NULL;
+
+ if (ev != NULL) {
+ return ev;
+ }
- if (!ctx && !(ctx = event_context_init(NULL))) {
- smb_panic("Could not init winbind event context");
+ /*
+ * Note we MUST use the NULL context here, not the autofree context,
+ * to avoid side effects in forked children exiting.
+ */
+ ev = samba_tevent_context_init(NULL);
+ if (ev == NULL) {
+ smb_panic("Could not init winbindd's messaging context.\n");
}
- return ctx;
+ return ev;
}
struct messaging_context *winbind_messaging_context(void)
{
- static struct messaging_context *ctx;
+ static struct messaging_context *msg = NULL;
- if (ctx == NULL) {
- ctx = messaging_init(NULL, procid_self(),
- winbind_event_context());
+ if (msg != NULL) {
+ return msg;
}
- if (ctx == NULL) {
- DEBUG(0, ("Could not init winbind messaging context.\n"));
+
+ /*
+ * Note we MUST use the NULL context here, not the autofree context,
+ * to avoid side effects in forked children exiting.
+ */
+ msg = messaging_init(NULL, winbind_event_context());
+ if (msg == NULL) {
+ smb_panic("Could not init winbindd's messaging context.\n");
}
- return ctx;
+ return msg;
}
/* Reload configuration */
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();
}
-/**************************************************************************** **
- Handle a fault..
- **************************************************************************** */
-
-static void fault_quit(void)
-{
- dump_core();
-}
-
static void winbindd_status(void)
{
struct winbindd_cli_state *tmp;
if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
DEBUG(2, ("\tclient list:\n"));
for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
- DEBUGADD(2, ("\t\tpid %lu, sock %d\n",
- (unsigned long)tmp->pid, tmp->sock));
+ DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
+ (unsigned long)tmp->pid, tmp->sock,
+ client_is_idle(tmp) ? "idle" : "active"));
}
}
}
-/* Print winbindd status to log file */
-
-static void print_winbindd_status(void)
-{
- winbindd_status();
-}
-
/* Flush client cache */
static void flush_caches(void)
#endif
if (is_parent) {
- serverid_deregister_self();
- pidfile_unlink();
+ struct messaging_context *msg = winbind_messaging_context();
+ struct server_id self = messaging_server_id(msg);
+ serverid_deregister(self);
+ 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,
void *siginfo,
void *private_data)
{
- print_winbindd_status();
+ winbindd_status();
}
static bool winbindd_setup_sig_usr2_handler(void)
{
uint8 ret;
pid_t child_pid;
+ NTSTATUS status;
DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
"message.\n"));
* 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",
/* child */
- if (!winbindd_reinit_after_fork(NULL)) {
+ status = winbindd_reinit_after_fork(NULL, NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
+ nt_errstr(status)));
_exit(0);
}
const char *winbindd_cmd_name;
} dispatch_table[] = {
- /* PAM auth functions */
-
- { WINBINDD_PAM_AUTH_CRAP, winbindd_pam_auth_crap, "AUTH_CRAP" },
- { WINBINDD_PAM_CHAUTHTOK, winbindd_pam_chauthtok, "CHAUTHTOK" },
- { WINBINDD_PAM_LOGOFF, winbindd_pam_logoff, "PAM_LOGOFF" },
- { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, winbindd_pam_chng_pswd_auth_crap, "CHNG_PSWD_AUTH_CRAP" },
-
/* Enumeration functions */
{ WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
"INTERFACE_VERSION" },
{ WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
{ WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
+ { WINBINDD_DC_INFO, winbindd_dc_info, "DC_INFO" },
{ WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
{ WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir,
"WINBINDD_PRIV_PIPE_DIR" },
{ 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" },
- { WINBINDD_WINS_BYIP, winbindd_wins_byip, "WINS_BYIP" },
-
/* End of list */
{ WINBINDD_NUM_CMDS, NULL, "NONE" }
wb_ping_send, wb_ping_recv },
{ WINBINDD_LOOKUPSID, "LOOKUPSID",
winbindd_lookupsid_send, winbindd_lookupsid_recv },
+ { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
+ winbindd_lookupsids_send, winbindd_lookupsids_recv },
{ WINBINDD_LOOKUPNAME, "LOOKUPNAME",
winbindd_lookupname_send, winbindd_lookupname_recv },
{ WINBINDD_SID_TO_UID, "SID_TO_UID",
winbindd_uid_to_sid_send, winbindd_uid_to_sid_recv },
{ WINBINDD_GID_TO_SID, "GID_TO_SID",
winbindd_gid_to_sid_send, winbindd_gid_to_sid_recv },
+ { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
+ winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
{ WINBINDD_GETPWSID, "GETPWSID",
winbindd_getpwsid_send, winbindd_getpwsid_recv },
{ WINBINDD_GETPWNAM, "GETPWNAM",
winbindd_ping_dc_send, winbindd_ping_dc_recv },
{ WINBINDD_PAM_AUTH, "PAM_AUTH",
winbindd_pam_auth_send, winbindd_pam_auth_recv },
+ { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
+ winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
+ { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
+ winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
+ { 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, "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 }
};
winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
{ WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
- { WINBINDD_SET_MAPPING, "SET_MAPPING",
- winbindd_set_mapping_send, winbindd_set_mapping_recv },
- { WINBINDD_REMOVE_MAPPING, "SET_MAPPING",
- winbindd_remove_mapping_send, winbindd_remove_mapping_recv },
- { WINBINDD_SET_HWM, "SET_HWM",
- winbindd_set_hwm_send, winbindd_set_hwm_recv },
{ WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
+ { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
+ winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
{ 0, NULL, NULL, NULL }
};
struct winbindd_dispatch_table *table = dispatch_table;
struct winbindd_async_dispatch_table *atable;
- state->mem_ctx = talloc_init("winbind request");
+ state->mem_ctx = talloc_named(state, 0, "winbind request");
if (state->mem_ctx == NULL)
return;
state->cmd_name = "unknown request";
state->recv_fn = NULL;
+ state->last_access = time(NULL);
/* Process command */
len = sizeof(sunaddr);
- do {
- sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr,
- &len);
- } while (sock == -1 && errno == EINTR);
+ sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
- if (sock == -1)
+ if (sock == -1) {
+ if (errno != EINTR) {
+ DEBUG(0, ("Failed to accept socket - %s\n",
+ strerror(errno)));
+ }
return;
+ }
DEBUG(6,("accepted socket %d\n", sock));
/* Create new connection structure */
- if ((state = TALLOC_ZERO_P(NULL, struct winbindd_cli_state)) == NULL) {
+ if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
close(sock);
return;
}
TALLOC_FREE(state);
}
+/* Is a client idle? */
+
+static bool client_is_idle(struct winbindd_cli_state *state) {
+ return (state->request == NULL &&
+ state->response == NULL &&
+ !state->pwent_state && !state->grent_state);
+}
+
/* Shutdown client connection which has been idle for the longest time */
static bool remove_idle_client(void)
int nidle = 0;
for (state = winbindd_client_list(); state; state = state->next) {
- if (state->response == NULL &&
- !state->pwent_state && !state->grent_state) {
+ if (client_is_idle(state)) {
nidle++;
if (!last_access || state->last_access < last_access) {
last_access = state->last_access;
struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
struct winbindd_listen_state);
- while (winbindd_num_clients() >
- WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) {
+ while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
DEBUG(5,("winbindd: Exceeding %d client "
"connections, removing idle "
- "connection.\n",
- WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
+ "connection.\n", lp_winbind_max_clients()));
if (!remove_idle_client()) {
DEBUG(0,("winbindd: Exceeding %d "
"client connections, no idle "
"connection found\n",
- WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
+ lp_winbind_max_clients()));
break;
}
}
new_connection(s->fd, s->privileged);
}
+/*
+ * Winbindd socket accessor functions
+ */
+
+const char *get_winbind_pipe_dir(void)
+{
+ return lp_parm_const_string(-1, "winbindd", "socket dir", get_dyn_WINBINDD_SOCKET_DIR());
+}
+
+char *get_winbind_priv_pipe_dir(void)
+{
+ 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);
}
pub_state->privileged = false;
- pub_state->fd = open_winbindd_socket();
+ pub_state->fd = create_pipe_sock(
+ get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME, 0755);
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,
}
priv_state->privileged = true;
- priv_state->fd = open_winbindd_priv_socket();
+ priv_state->fd = create_pipe_sock(
+ get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750);
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;
}
+static void winbindd_register_handlers(struct messaging_context *msg_ctx,
+ 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())
+ exit(1);
+ if (!winbindd_setup_sig_usr2_handler())
+ exit(1);
+
+ CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
+
+ /*
+ * Ensure all cache and idmap caches are consistent
+ * and initialized before we startup.
+ */
+ if (!winbindd_cache_validate_and_initialize()) {
+ exit(1);
+ }
+
+ /* get broadcast messages */
+
+ if (!serverid_register(messaging_server_id(msg_ctx),
+ FLAG_MSG_GENERAL |
+ FLAG_MSG_WINBIND |
+ FLAG_MSG_DBWRAP)) {
+ DEBUG(1, ("Could not register myself in serverid.tdb\n"));
+ exit(1);
+ }
+
+ /* React on 'smbcontrol winbindd reload-config' in the same way
+ as to SIGHUP signal */
+ messaging_register(msg_ctx, NULL,
+ MSG_SMB_CONF_UPDATED, msg_reload_services);
+ messaging_register(msg_ctx, NULL,
+ MSG_SHUTDOWN, msg_shutdown);
+
+ /* Handle online/offline messages. */
+ messaging_register(msg_ctx, NULL,
+ MSG_WINBIND_OFFLINE, winbind_msg_offline);
+ messaging_register(msg_ctx, NULL,
+ MSG_WINBIND_ONLINE, winbind_msg_online);
+ messaging_register(msg_ctx, NULL,
+ MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
+
+ messaging_register(msg_ctx, NULL,
+ MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
+
+ messaging_register(msg_ctx, NULL,
+ MSG_WINBIND_VALIDATE_CACHE,
+ winbind_msg_validate_cache);
+
+ messaging_register(msg_ctx, NULL,
+ MSG_WINBIND_DUMP_DOMAIN_LIST,
+ winbind_msg_dump_domain_list);
+
+ messaging_register(msg_ctx, NULL,
+ MSG_WINBIND_IP_DROPPED,
+ winbind_msg_ip_dropped_parent);
+
+ /* Register handler for MSG_DEBUG. */
+ messaging_register(msg_ctx, NULL,
+ MSG_DEBUG,
+ winbind_msg_debug);
+
+ netsamlogon_cache_init(); /* Non-critical */
+
+ /* clear the cached list of trusted domains */
+
+ wcache_tdc_clear();
+
+ if (!init_domain_list()) {
+ DEBUG(0,("unable to initialize domain list\n"));
+ exit(1);
+ }
+
+ init_idmap_child();
+ init_locator_child();
+
+ smb_nscd_flush_user_cache();
+ smb_nscd_flush_group_cache();
+
+ if (lp_allow_trusted_domains()) {
+ if (tevent_add_timer(winbind_event_context(), NULL, timeval_zero(),
+ rescan_trusted_domains, NULL) == NULL) {
+ DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
+ exit(1);
+ }
+ }
+
+}
+
+struct winbindd_addrchanged_state {
+ struct addrchange_context *ctx;
+ struct tevent_context *ev;
+ struct messaging_context *msg_ctx;
+};
+
+static void winbindd_addr_changed(struct tevent_req *req);
+
+static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct messaging_context *msg_ctx)
+{
+ struct winbindd_addrchanged_state *state;
+ struct tevent_req *req;
+ NTSTATUS status;
+
+ state = talloc(mem_ctx, struct winbindd_addrchanged_state);
+ if (state == NULL) {
+ DEBUG(10, ("talloc failed\n"));
+ return;
+ }
+ state->ev = ev;
+ state->msg_ctx = msg_ctx;
+
+ status = addrchange_context_create(state, &state->ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("addrchange_context_create failed: %s\n",
+ nt_errstr(status)));
+ TALLOC_FREE(state);
+ return;
+ }
+ req = addrchange_send(state, ev, state->ctx);
+ if (req == NULL) {
+ DEBUG(0, ("addrchange_send failed\n"));
+ TALLOC_FREE(state);
+ return;
+ }
+ tevent_req_set_callback(req, winbindd_addr_changed, state);
+}
+
+static void winbindd_addr_changed(struct tevent_req *req)
+{
+ struct winbindd_addrchanged_state *state = tevent_req_callback_data(
+ req, struct winbindd_addrchanged_state);
+ enum addrchange_type type;
+ struct sockaddr_storage addr;
+ NTSTATUS status;
+
+ status = addrchange_recv(req, &type, &addr);
+ TALLOC_FREE(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
+ nt_errstr(status)));
+ TALLOC_FREE(state);
+ return;
+ }
+ if (type == ADDRCHANGE_DEL) {
+ char addrstr[INET6_ADDRSTRLEN];
+ DATA_BLOB blob;
+
+ print_sockaddr(addrstr, sizeof(addrstr), &addr);
+
+ DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
+ addrstr));
+
+ blob = data_blob_const(addrstr, strlen(addrstr)+1);
+
+ status = messaging_send(state->msg_ctx,
+ messaging_server_id(state->msg_ctx),
+ MSG_WINBIND_IP_DROPPED, &blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("messaging_send failed: %s - ignoring\n",
+ nt_errstr(status)));
+ }
+ }
+ req = addrchange_send(state, state->ev, state->ctx);
+ if (req == NULL) {
+ DEBUG(0, ("addrchange_send failed\n"));
+ TALLOC_FREE(state);
+ return;
+ }
+ tevent_req_set_callback(req, winbindd_addr_changed, state);
+}
+
/* Main function */
int main(int argc, char **argv, char **envp)
};
poptContext pc;
int opt;
- TALLOC_CTX *frame = talloc_stackframe();
- struct tevent_timer *te;
+ TALLOC_CTX *frame;
+ NTSTATUS status;
+ bool ok;
+
+ /*
+ * Do this before any other talloc operation
+ */
+ 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(SIGUSR1, SIG_IGN);
CatchSignal(SIGUSR2, SIG_IGN);
- fault_setup((void (*)(void *))fault_quit );
- dump_core_setup("winbindd");
+ fault_setup();
+ 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);
}
}
- setup_logging("winbindd", log_stdout);
+
+ 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()));
DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
- DEBUG(0, ("error opening config file\n"));
+ 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()));
+
+ if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
+ DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
+ DEBUGADD(0, ("You should start 'samba' instead, and it will control starting the internal AD DC winbindd implementation, which is not the same as this one\n"));
exit(1);
}
exit(1);
}
- if (!directory_exist(lp_lockdir())) {
- mkdir(lp_lockdir(), 0755);
+ ok = directory_create_or_exist(lp_lockdir(), geteuid(), 0755);
+ if (!ok) {
+ DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
+ lp_lockdir(), strerror(errno)));
+ exit(1);
+ }
+
+ ok = directory_create_or_exist(lp_piddir(), geteuid(), 0755);
+ if (!ok) {
+ DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
+ lp_piddir(), strerror(errno)));
+ exit(1);
}
/* Setup names. */
return False;
}
- /* Enable netbios namecache */
-
- namecache_enable();
-
/* Unblock all signals we are interested in as they may have been
blocked by the parent process. */
if (!interactive)
become_daemon(Fork, no_process_group, log_stdout);
- pidfile_create("winbindd");
+ pidfile_create(lp_piddir(), "winbindd");
#if HAVE_SETPGID
/*
* winbindd-specific resources we must free yet. JRA.
*/
- if (!NT_STATUS_IS_OK(reinit_after_fork(winbind_messaging_context(),
- winbind_event_context(),
- false))) {
+ status = reinit_after_fork(winbind_messaging_context(),
+ winbind_event_context(),
+ false);
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("reinit_after_fork() failed\n"));
exit(1);
}
- /* Setup signal handlers */
-
- if (!winbindd_setup_sig_term_handler(true))
- exit(1);
- if (!winbindd_setup_sig_hup_handler(NULL))
- exit(1);
- if (!winbindd_setup_sig_chld_handler())
- exit(1);
- if (!winbindd_setup_sig_usr2_handler())
- exit(1);
-
- CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
-
/*
- * Ensure all cache and idmap caches are consistent
- * and initialized before we startup.
+ * Do not initialize the parent-child-pipe before becoming
+ * a daemon: this is used to detect a died parent in the child
+ * process.
*/
- if (!winbindd_cache_validate_and_initialize()) {
- exit(1);
- }
-
- /* get broadcast messages */
-
- if (!serverid_register_self(FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP)) {
- DEBUG(1, ("Could not register myself in serverid.tdb\n"));
+ status = init_before_fork();
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("init_before_fork failed: %s\n", nt_errstr(status)));
exit(1);
}
- /* React on 'smbcontrol winbindd reload-config' in the same way
- as to SIGHUP signal */
- messaging_register(winbind_messaging_context(), NULL,
- MSG_SMB_CONF_UPDATED, msg_reload_services);
- messaging_register(winbind_messaging_context(), NULL,
- MSG_SHUTDOWN, msg_shutdown);
-
- /* Handle online/offline messages. */
- messaging_register(winbind_messaging_context(), NULL,
- MSG_WINBIND_OFFLINE, winbind_msg_offline);
- messaging_register(winbind_messaging_context(), NULL,
- MSG_WINBIND_ONLINE, winbind_msg_online);
- messaging_register(winbind_messaging_context(), NULL,
- MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
-
- messaging_register(winbind_messaging_context(), NULL,
- MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
-
- messaging_register(winbind_messaging_context(), NULL,
- MSG_WINBIND_VALIDATE_CACHE,
- winbind_msg_validate_cache);
-
- messaging_register(winbind_messaging_context(), NULL,
- MSG_WINBIND_DUMP_DOMAIN_LIST,
- winbind_msg_dump_domain_list);
-
- /* Register handler for MSG_DEBUG. */
- messaging_register(winbind_messaging_context(), NULL,
- MSG_DEBUG,
- winbind_msg_debug);
-
- netsamlogon_cache_init(); /* Non-critical */
-
- /* clear the cached list of trusted domains */
-
- wcache_tdc_clear();
+ winbindd_register_handlers(winbind_messaging_context(), !Fork);
- if (!init_domain_list()) {
- DEBUG(0,("unable to initialize domain list\n"));
+ 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)));
exit(1);
}
- init_idmap_child();
- init_locator_child();
+ rpc_lsarpc_init(NULL);
+ rpc_samr_init(NULL);
- smb_nscd_flush_user_cache();
- smb_nscd_flush_group_cache();
+ winbindd_init_addrchange(NULL, winbind_event_context(),
+ winbind_messaging_context());
/* setup listen sockets */
exit(1);
}
- te = tevent_add_timer(winbind_event_context(), NULL, timeval_zero(),
- rescan_trusted_domains, NULL);
- if (te == NULL) {
- DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
- exit(1);
- }
-
TALLOC_FREE(frame);
/* Loop waiting for requests */
while (1) {