s3-winbindd: Remove undocumented winbindd:socket dir parameter
[mat/samba.git] / source3 / winbindd / winbindd.c
index fe6e34b4b99a7a9cf1417d90d410793282025ef9..31280c216b86e4784e73ff6a245f40888d61fa62 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
 
    Winbind daemon for ntdom nss module
@@ -36,6 +36,7 @@
 #include "serverid.h"
 #include "auth.h"
 #include "messages.h"
+#include "../lib/util/pidfile.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
@@ -48,14 +49,42 @@ 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)
 {
-       struct messaging_context *msg_ctx = server_messaging_context();
-       if (likely(msg_ctx != NULL)) {
-               return msg_ctx;
+       static struct messaging_context *msg = NULL;
+
+       if (msg != NULL) {
+               return msg;
        }
-       smb_panic("Could not init winbindd's messaging context.\n");
-       return NULL;
+
+       /*
+        * 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 */
@@ -160,7 +189,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);
                }
@@ -183,8 +212,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);
@@ -215,7 +246,7 @@ static void winbindd_stdin_handler(struct tevent_context *ev,
        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",
@@ -277,20 +308,33 @@ 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.
                */
-               tevent_add_fd(winbind_event_context(), is_parent, 0, TEVENT_FD_READ, winbindd_stdin_handler, is_parent);
+               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;
 }
 
@@ -620,6 +664,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 */
 
@@ -816,7 +861,7 @@ static void new_connection(int listen_sock, bool privileged)
 
        if (sock == -1) {
                if (errno != EINTR) {
-                       DEBUG(0, ("Faild to accept socket - %s\n",
+                       DEBUG(0, ("Failed to accept socket - %s\n",
                                  strerror(errno)));
                }
                return;
@@ -921,7 +966,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);
 }
 
@@ -985,11 +1031,6 @@ 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", get_dyn_WINBINDD_SOCKET_DIR());
-}
-
 char *get_winbind_priv_pipe_dir(void)
 {
        return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
@@ -1010,7 +1051,7 @@ 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;
        }
@@ -1071,7 +1112,8 @@ bool winbindd_use_cache(void)
        return !opt_nocache;
 }
 
-void winbindd_register_handlers(bool foreground)
+static void winbindd_register_handlers(struct messaging_context *msg_ctx,
+                                      bool foreground)
 {
        /* Setup signal handlers */
 
@@ -1098,7 +1140,7 @@ void winbindd_register_handlers(bool foreground)
 
        /* get broadcast messages */
 
-       if (!serverid_register(procid_self(),
+       if (!serverid_register(messaging_server_id(msg_ctx),
                               FLAG_MSG_GENERAL |
                               FLAG_MSG_WINBIND |
                               FLAG_MSG_DBWRAP)) {
@@ -1108,36 +1150,42 @@ void winbindd_register_handlers(bool foreground)
 
        /* 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);
 
@@ -1281,6 +1329,7 @@ int main(int argc, char **argv, char **envp)
        int opt;
        TALLOC_CTX *frame;
        NTSTATUS status;
+       bool ok;
 
        /*
         * Do this before any other talloc operation
@@ -1288,6 +1337,12 @@ int main(int argc, char **argv, char **envp)
        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
@@ -1403,6 +1458,12 @@ int main(int argc, char **argv, char **envp)
         */
        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);
+       }
+
        /* Initialise messaging system */
 
        if (winbind_messaging_context() == NULL) {
@@ -1414,12 +1475,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);
        }
 
-       if (!directory_exist(lp_piddir())) {
-               mkdir(lp_piddir(), 0755);
+       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. */
@@ -1449,7 +1516,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
        /*
@@ -1486,7 +1553,7 @@ int main(int argc, char **argv, char **envp)
                exit(1);
        }
 
-       winbindd_register_handlers(!Fork);
+       winbindd_register_handlers(winbind_messaging_context(), !Fork);
 
        status = init_system_session_info();
        if (!NT_STATUS_IS_OK(status)) {