winbind: Fix a typo
[samba.git] / source3 / winbindd / winbindd.c
index 75f9dbb142e32033d14af546292c549c22ccbfb8..f0f0eef7bfc2f5bb8ed111072d8076d6e09bea06 100644 (file)
@@ -34,7 +34,6 @@
 #include "rpc_client/cli_netlogon.h"
 #include "idmap.h"
 #include "lib/addrchange.h"
-#include "serverid.h"
 #include "auth.h"
 #include "messages.h"
 #include "../lib/util/pidfile.h"
@@ -45,6 +44,7 @@
 #include "lib/async_req/async_sock.h"
 #include "libsmb/samlogon_cache.h"
 #include "libcli/auth/netlogon_creds_cli.h"
+#include "passdb.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 void winbindd_setup_max_fds(void);
+static void request_ok(struct winbindd_cli_state *state);
+static void request_error(struct winbindd_cli_state *state);
 
 static bool opt_nocache = False;
 static bool interactive = False;
 
 extern bool override_logfile;
 
-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, server_event_context());
-       if (msg == NULL) {
-               smb_panic("Could not init winbindd's messaging context.\n");
-       }
-       return msg;
-}
-
 struct imessaging_context *winbind_imessaging_context(void)
 {
        static struct imessaging_context *msg = NULL;
@@ -240,9 +223,6 @@ static void terminate(bool is_parent)
 #endif
 
        if (is_parent) {
-               struct messaging_context *msg = winbind_messaging_context();
-               struct server_id self = messaging_server_id(msg);
-               serverid_deregister(self);
                pidfile_unlink(lp_pid_directory(), "winbindd");
        }
 
@@ -256,11 +236,14 @@ static void winbindd_sig_term_handler(struct tevent_context *ev,
                                      void *siginfo,
                                      void *private_data)
 {
-       bool *is_parent = talloc_get_type_abort(private_data, bool);
+       bool *p = talloc_get_type_abort(private_data, bool);
+       bool is_parent = *p;
+
+       TALLOC_FREE(p);
 
        DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
-                signum, (int)*is_parent));
-       terminate(*is_parent);
+                signum, is_parent));
+       terminate(is_parent);
 }
 
 /*
@@ -531,6 +514,8 @@ static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
        /* install default SIGCHLD handler: validation code uses fork/waitpid */
        CatchSignal(SIGCHLD, SIG_DFL);
 
+       setproctitle("validate cache child");
+
        ret = (uint8_t)winbindd_validate_cache_nobackup();
        DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
        messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
@@ -538,36 +523,41 @@ static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
        _exit(0);
 }
 
-static struct winbindd_dispatch_table {
+static struct winbindd_bool_dispatch_table {
        enum winbindd_cmd cmd;
-       void (*fn)(struct winbindd_cli_state *state);
-       const char *winbindd_cmd_name;
-} dispatch_table[] = {
-
-       /* Enumeration functions */
-
-       { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
-         "LIST_TRUSTDOM" },
-
-       /* Miscellaneous */
-
-       { WINBINDD_INFO, winbindd_info, "INFO" },
-       { WINBINDD_INTERFACE_VERSION, winbindd_interface_version,
+       bool (*fn)(struct winbindd_cli_state *state);
+       const char *cmd_name;
+} bool_dispatch_table[] = {
+       { WINBINDD_INTERFACE_VERSION,
+         winbindd_interface_version,
          "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_INFO,
+         winbindd_info,
+         "INFO" },
+       { WINBINDD_PING,
+         winbindd_ping,
+         "PING" },
+       { WINBINDD_DOMAIN_NAME,
+         winbindd_domain_name,
+         "DOMAIN_NAME" },
+       { WINBINDD_NETBIOS_NAME,
+         winbindd_netbios_name,
+         "NETBIOS_NAME" },
+       { WINBINDD_DC_INFO,
+         winbindd_dc_info,
+         "DC_INFO" },
+       { WINBINDD_CCACHE_NTLMAUTH,
+         winbindd_ccache_ntlm_auth,
+         "NTLMAUTH" },
+       { WINBINDD_CCACHE_SAVE,
+         winbindd_ccache_save,
+         "CCACHE_SAVE" },
+       { WINBINDD_PRIV_PIPE_DIR,
+         winbindd_priv_pipe_dir,
          "WINBINDD_PRIV_PIPE_DIR" },
-
-       /* Credential cache access */
-       { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
-       { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
-
-       /* End of list */
-
-       { WINBINDD_NUM_CMDS, NULL, "NONE" }
+       { WINBINDD_LIST_TRUSTDOM,
+         winbindd_list_trusted_domains,
+         "LIST_TRUSTDOM" },
 };
 
 struct winbindd_async_dispatch_table {
@@ -582,8 +572,6 @@ struct winbindd_async_dispatch_table {
 };
 
 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
-       { WINBINDD_PING, "PING",
-         wb_ping_send, wb_ping_recv },
        { WINBINDD_LOOKUPSID, "LOOKUPSID",
          winbindd_lookupsid_send, winbindd_lookupsid_recv },
        { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
@@ -653,6 +641,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
          winbindd_wins_byip_send, winbindd_wins_byip_recv },
        { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
          winbindd_wins_byname_send, winbindd_wins_byname_recv },
+       { WINBINDD_DOMAIN_INFO, "DOMAIN_INFO",
+         winbindd_domain_info_send, winbindd_domain_info_recv },
 
        { 0, NULL, NULL, NULL }
 };
@@ -674,8 +664,9 @@ static void wb_request_done(struct tevent_req *req);
 
 static void process_request(struct winbindd_cli_state *state)
 {
-       struct winbindd_dispatch_table *table = dispatch_table;
        struct winbindd_async_dispatch_table *atable;
+       size_t i;
+       bool ok;
 
        state->mem_ctx = talloc_named(state, 0, "winbind request");
        if (state->mem_ctx == NULL)
@@ -737,20 +728,28 @@ static void process_request(struct winbindd_cli_state *state)
        state->response->result = WINBINDD_PENDING;
        state->response->length = sizeof(struct winbindd_response);
 
-       for (table = dispatch_table; table->fn; table++) {
-               if (state->request->cmd == table->cmd) {
-                       DEBUG(10,("process_request: request fn %s\n",
-                                 table->winbindd_cmd_name ));
-                       state->cmd_name = table->winbindd_cmd_name;
-                       table->fn(state);
+       for (i=0; i<ARRAY_SIZE(bool_dispatch_table); i++) {
+               if (bool_dispatch_table[i].cmd == state->request->cmd) {
                        break;
                }
        }
 
-       if (!table->fn) {
+       if (i == ARRAY_SIZE(bool_dispatch_table)) {
                DEBUG(10,("process_request: unknown request fn number %d\n",
                          (int)state->request->cmd ));
                request_error(state);
+               return;
+       }
+
+       DBG_DEBUG("process_request: request fn %s\n",
+                 bool_dispatch_table[i].cmd_name);
+
+       ok = bool_dispatch_table[i].fn(state);
+
+       if (ok) {
+               request_ok(state);
+       } else {
+               request_error(state);
        }
 }
 
@@ -860,14 +859,14 @@ static void winbind_client_response_written(struct tevent_req *req)
        state->io_req = req;
 }
 
-void request_error(struct winbindd_cli_state *state)
+static void request_error(struct winbindd_cli_state *state)
 {
        SMB_ASSERT(state->response->result == WINBINDD_PENDING);
        state->response->result = WINBINDD_ERROR;
        request_finished(state);
 }
 
-void request_ok(struct winbindd_cli_state *state)
+static void request_ok(struct winbindd_cli_state *state)
 {
        SMB_ASSERT(state->response->result == WINBINDD_PENDING);
        state->response->result = WINBINDD_OK;
@@ -897,6 +896,7 @@ static void new_connection(int listen_sock, bool privileged)
                }
                return;
        }
+       smb_set_close_on_exec(sock);
 
        DEBUG(6,("accepted socket %d\n", sock));
 
@@ -1027,7 +1027,7 @@ static void remove_client(struct winbindd_cli_state *state)
         * before closing the fd.
         *
         * Otherwise we might hit a race with close_conns_after_fork() (via
-        * winbindd_reinit_after_fork()) where a file description
+        * winbindd_reinit_after_fork()) where a file descriptor
         * is still open in a child, which means it's still active in
         * the parents epoll queue, but the related tevent_fd is already
         * already gone in the parent.
@@ -1300,6 +1300,7 @@ bool winbindd_use_cache(void)
 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
                                       bool foreground)
 {
+       bool scan_trusts = true;
        NTSTATUS status;
        /* Setup signal handlers */
 
@@ -1324,16 +1325,6 @@ static void winbindd_register_handlers(struct messaging_context *msg_ctx,
                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,
@@ -1350,14 +1341,11 @@ static void winbindd_register_handlers(struct messaging_context *msg_ctx,
                           MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
 
        /* Handle domain online/offline messages for domains */
-       messaging_register(winbind_messaging_context(), NULL,
+       messaging_register(server_messaging_context(), NULL,
                           MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
-       messaging_register(winbind_messaging_context(), NULL,
+       messaging_register(server_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(msg_ctx, NULL,
                           MSG_WINBIND_VALIDATE_CACHE,
                           winbind_msg_validate_cache);
@@ -1375,6 +1363,10 @@ static void winbindd_register_handlers(struct messaging_context *msg_ctx,
                           MSG_DEBUG,
                           winbind_msg_debug);
 
+       messaging_register(msg_ctx, NULL,
+                          MSG_WINBIND_DISCONNECT_DC,
+                          winbind_disconnect_dc_parent);
+
        netsamlogon_cache_init(); /* Non-critical */
 
        /* clear the cached list of trusted domains */
@@ -1392,7 +1384,19 @@ static void winbindd_register_handlers(struct messaging_context *msg_ctx,
        smb_nscd_flush_user_cache();
        smb_nscd_flush_group_cache();
 
-       if (lp_allow_trusted_domains()) {
+       if (!lp_winbind_scan_trusted_domains()) {
+               scan_trusts = false;
+       }
+
+       if (!lp_allow_trusted_domains()) {
+               scan_trusts = false;
+       }
+
+       if (IS_DC) {
+               scan_trusts = false;
+       }
+
+       if (scan_trusts) {
                if (tevent_add_timer(server_event_context(), NULL, timeval_zero(),
                              rescan_trusted_domains, NULL) == NULL) {
                        DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
@@ -1523,6 +1527,8 @@ int main(int argc, const char **argv)
        NTSTATUS status;
        bool ok;
 
+       setproctitle_init(argc, discard_const(argv), environ);
+
        /*
         * Do this before any other talloc operation
         */
@@ -1663,7 +1669,7 @@ int main(int argc, const char **argv)
 
        /* Initialise messaging system */
 
-       if (winbind_messaging_context() == NULL) {
+       if (server_messaging_context() == NULL) {
                exit(1);
        }
 
@@ -1757,12 +1763,13 @@ int main(int argc, const char **argv)
         * winbindd-specific resources we must free yet. JRA.
         */
 
-       status = reinit_after_fork(winbind_messaging_context(),
+       status = reinit_after_fork(server_messaging_context(),
                                   server_event_context(),
                                   false, NULL);
        if (!NT_STATUS_IS_OK(status)) {
                exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
        }
+       initialize_password_db(true, server_event_context());
 
        /*
         * Do not initialize the parent-child-pipe before becoming
@@ -1774,13 +1781,13 @@ int main(int argc, const char **argv)
                exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
        }
 
-       winbindd_register_handlers(winbind_messaging_context(), !Fork);
+       winbindd_register_handlers(server_messaging_context(), !Fork);
 
-       if (!messaging_parent_dgm_cleanup_init(winbind_messaging_context())) {
+       if (!messaging_parent_dgm_cleanup_init(server_messaging_context())) {
                exit(1);
        }
 
-       status = init_system_session_info();
+       status = init_system_session_info(NULL);
        if (!NT_STATUS_IS_OK(status)) {
                exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
        }
@@ -1789,7 +1796,7 @@ int main(int argc, const char **argv)
        rpc_samr_init(NULL);
 
        winbindd_init_addrchange(NULL, server_event_context(),
-                                winbind_messaging_context());
+                                server_messaging_context());
 
        /* setup listen sockets */
 
@@ -1805,6 +1812,8 @@ int main(int argc, const char **argv)
                daemon_ready("winbindd");
        }
 
+       gpupdate_init();
+
        /* Loop waiting for requests */
        while (1) {
                frame = talloc_stackframe();