X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source3%2Fwinbindd%2Fwinbindd.c;h=361d02c03bd0ff0373c7c74229790f2b8e9a684b;hb=5eae612c724339b225de8be9057dab4043a625a5;hp=0c9cdcf52e104b490f5d42d668fa5e52a9015e0d;hpb=bad98e37e7e4077a74c7b32d74499c78810192c5;p=mat%2Fsamba.git diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index 0c9cdcf52e..361d02c03b 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. Winbind daemon for ntdom nss module @@ -26,12 +26,18 @@ #include "popt_common.h" #include "winbindd.h" #include "nsswitch/winbind_client.h" -#include "../../nsswitch/libwbclient/wbc_async.h" -#include "librpc/gen_ndr/messaging.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" +#include "util_cluster.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND @@ -44,6 +50,44 @@ static bool interactive = False; extern bool override_logfile; +struct tevent_context *winbind_event_context(void) +{ + static struct tevent_context *ev = NULL; + + if (ev != NULL) { + return ev; + } + + /* + * 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 ev; +} + +struct messaging_context *winbind_messaging_context(void) +{ + static struct messaging_context *msg = NULL; + + if (msg != NULL) { + return msg; + } + + /* + * 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 msg; +} + /* Reload configuration */ static bool reload_services_file(const char *lfile) @@ -51,11 +95,12 @@ static bool reload_services_file(const char *lfile) 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 @@ -65,7 +110,7 @@ static bool reload_services_file(const char *lfile) } reopen_logs(); - ret = lp_load(get_dyn_CONFIGFILE(),False,False,True,True); + ret = lp_load_global(get_dyn_CONFIGFILE()); reopen_logs(); load_interfaces(); @@ -74,15 +119,6 @@ static bool reload_services_file(const char *lfile) } -/**************************************************************************** ** - Handle a fault.. - **************************************************************************** */ - -static void fault_quit(void) -{ - dump_core(); -} - static void winbindd_status(void) { struct winbindd_cli_state *tmp; @@ -154,7 +190,7 @@ static void terminate(bool is_parent) char *path = NULL; if (asprintf(&path, "%s/%s", - get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME) > 0) { + lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME) > 0) { unlink(path); SAFE_FREE(path); } @@ -177,8 +213,10 @@ static void terminate(bool is_parent) #endif if (is_parent) { - serverid_deregister(procid_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); @@ -198,6 +236,26 @@ static void winbindd_sig_term_handler(struct tevent_context *ev, 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; @@ -246,6 +304,41 @@ bool winbindd_setup_sig_term_handler(bool parent) return true; } +bool winbindd_setup_stdin_handler(bool parent, bool foreground) +{ + bool *is_parent; + + if (foreground) { + struct stat st; + + 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 + Only do this on a pipe or socket, no other device. + */ + if (fstat(0, &st) != 0) { + return false; + } + if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) { + 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, @@ -374,6 +467,7 @@ static void winbind_msg_validate_cache(struct messaging_context *msg_ctx, { uint8 ret; pid_t child_pid; + NTSTATUS status; DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache " "message.\n")); @@ -383,7 +477,7 @@ static void winbind_msg_validate_cache(struct messaging_context *msg_ctx, * 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", @@ -400,7 +494,10 @@ static void winbind_msg_validate_cache(struct messaging_context *msg_ctx, /* 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); } @@ -432,6 +529,7 @@ static struct winbindd_dispatch_table { "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" }, @@ -440,11 +538,6 @@ static struct winbindd_dispatch_table { { 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" } @@ -466,6 +559,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = { 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", @@ -476,6 +571,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = { 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", @@ -531,6 +628,10 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = { { 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 } }; @@ -564,6 +665,7 @@ static void process_request(struct winbindd_cli_state *state) state->cmd_name = "unknown request"; state->recv_fn = NULL; + state->last_access = time(NULL); /* Process command */ @@ -756,19 +858,21 @@ static void new_connection(int listen_sock, bool privileged) 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; } @@ -863,7 +967,8 @@ static void remove_client(struct winbindd_cli_state *state) /* Is a client idle? */ static bool client_is_idle(struct winbindd_cli_state *state) { - return (state->response == NULL && + return (state->request == NULL && + state->response == NULL && !state->pwent_state && !state->grent_state); } @@ -927,14 +1032,9 @@ static void winbindd_listen_fde_handler(struct tevent_context *ev, * Winbindd socket accessor functions */ -const char *get_winbind_pipe_dir(void) -{ - return lp_parm_const_string(-1, "winbindd", "socket dir", WINBINDD_SOCKET_DIR); -} - 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) @@ -942,6 +1042,7 @@ 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); @@ -951,10 +1052,14 @@ static bool winbindd_setup_listeners(void) pub_state->privileged = false; pub_state->fd = create_pipe_sock( - get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME, 0755); + lp_winbindd_socket_directory(), 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, @@ -977,6 +1082,10 @@ static bool winbindd_setup_listeners(void) 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, @@ -1004,13 +1113,15 @@ bool winbindd_use_cache(void) return !opt_nocache; } -void winbindd_register_handlers(void) +static void winbindd_register_handlers(struct messaging_context *msg_ctx, + bool foreground) { - struct tevent_timer *te; /* 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()) @@ -1030,44 +1141,52 @@ void winbindd_register_handlers(void) /* get broadcast messages */ - if (!serverid_register(procid_self(), - FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP)) { + 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(winbind_messaging_context(), NULL, + messaging_register(msg_ctx, NULL, MSG_SMB_CONF_UPDATED, msg_reload_services); - messaging_register(winbind_messaging_context(), NULL, + messaging_register(msg_ctx, NULL, MSG_SHUTDOWN, msg_shutdown); /* Handle online/offline messages. */ - messaging_register(winbind_messaging_context(), NULL, + messaging_register(msg_ctx, NULL, MSG_WINBIND_OFFLINE, winbind_msg_offline); - messaging_register(winbind_messaging_context(), NULL, + messaging_register(msg_ctx, NULL, MSG_WINBIND_ONLINE, winbind_msg_online); - messaging_register(winbind_messaging_context(), NULL, + messaging_register(msg_ctx, NULL, MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus); + /* Handle domain online/offline messages for domains */ + messaging_register(winbind_messaging_context(), NULL, + MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline); messaging_register(winbind_messaging_context(), NULL, + MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online); + + messaging_register(msg_ctx, NULL, MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list); - messaging_register(winbind_messaging_context(), NULL, + messaging_register(msg_ctx, NULL, MSG_WINBIND_VALIDATE_CACHE, winbind_msg_validate_cache); - messaging_register(winbind_messaging_context(), NULL, + messaging_register(msg_ctx, NULL, MSG_WINBIND_DUMP_DOMAIN_LIST, winbind_msg_dump_domain_list); - messaging_register(winbind_messaging_context(), NULL, + messaging_register(msg_ctx, NULL, MSG_WINBIND_IP_DROPPED, winbind_msg_ip_dropped_parent); /* Register handler for MSG_DEBUG. */ - messaging_register(winbind_messaging_context(), NULL, + messaging_register(msg_ctx, NULL, MSG_DEBUG, winbind_msg_debug); @@ -1088,15 +1207,100 @@ void winbindd_register_handlers(void) smb_nscd_flush_user_cache(); smb_nscd_flush_group_cache(); - 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); + 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) @@ -1124,8 +1328,23 @@ int main(int argc, char **argv, char **envp) }; poptContext pc; int opt; - TALLOC_CTX *frame = talloc_stackframe(); + TALLOC_CTX *frame; NTSTATUS status; + bool ok; + + /* + * Do this before any other talloc operation + */ + talloc_enable_null_tracking(); + frame = talloc_stackframe(); + + /* + * We want total control over the permissions on created files, + * so set our umask to 0. + */ + umask(0); + + 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 */ @@ -1133,8 +1352,8 @@ int main(int argc, char **argv, char **envp) 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(); @@ -1187,6 +1406,14 @@ int main(int argc, char **argv, char **envp) } } + /* 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"); @@ -1211,14 +1438,34 @@ int main(int argc, char **argv, char **envp) 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); + } + + if (!cluster_probe_ok()) { exit(1); } @@ -1233,8 +1480,18 @@ int main(int argc, char **argv, char **envp) 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. */ @@ -1264,7 +1521,7 @@ int main(int argc, char **argv, char **envp) if (!interactive) become_daemon(Fork, no_process_group, log_stdout); - pidfile_create("winbindd"); + pidfile_create(lp_piddir(), "winbindd"); #if HAVE_SETPGID /* @@ -1284,21 +1541,37 @@ int main(int argc, char **argv, char **envp) 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(winbind_messaging_context(), !Fork); + + 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); + } rpc_lsarpc_init(NULL); rpc_samr_init(NULL); - if (!init_system_info()) { - DEBUG(0,("ERROR: failed to setup system user info.\n")); - exit(1); - } + winbindd_init_addrchange(NULL, winbind_event_context(), + winbind_messaging_context()); /* setup listen sockets */