s3-winbind: only pass needed args to child_read_request
[metze/samba-autobuild/.git] / source3 / winbindd / winbindd_dual.c
index 08f3dda5f77aff983225ce448b9f31285d1d25fa..18ec3dd90086feb1c98da9ea1383f2c634317770 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "includes.h"
 #include "winbindd.h"
+#include "rpc_client/rpc_client.h"
 #include "nsswitch/wb_reqtrans.h"
 #include "secrets.h"
 #include "../lib/util/select.h"
@@ -48,42 +49,34 @@ static struct winbindd_child *winbindd_children = NULL;
 
 /* Read some data from a client connection */
 
-static NTSTATUS child_read_request(struct winbindd_cli_state *state)
+static NTSTATUS child_read_request(int sock, struct winbindd_request *wreq)
 {
        NTSTATUS status;
 
-       /* Read data */
-
-       status = read_data(state->sock, (char *)state->request,
-                          sizeof(*state->request));
-
+       status = read_data(sock, (char *)wreq, sizeof(*wreq));
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(3, ("child_read_request: read_data failed: %s\n",
                          nt_errstr(status)));
                return status;
        }
 
-       if (state->request->extra_len == 0) {
-               state->request->extra_data.data = NULL;
+       if (wreq->extra_len == 0) {
+               wreq->extra_data.data = NULL;
                return NT_STATUS_OK;
        }
 
-       DEBUG(10, ("Need to read %d extra bytes\n", (int)state->request->extra_len));
-
-       state->request->extra_data.data =
-               SMB_MALLOC_ARRAY(char, state->request->extra_len + 1);
+       DEBUG(10, ("Need to read %d extra bytes\n", (int)wreq->extra_len));
 
-       if (state->request->extra_data.data == NULL) {
+       wreq->extra_data.data = SMB_MALLOC_ARRAY(char, wreq->extra_len + 1);
+       if (wreq->extra_data.data == NULL) {
                DEBUG(0, ("malloc failed\n"));
                return NT_STATUS_NO_MEMORY;
        }
 
        /* Ensure null termination */
-       state->request->extra_data.data[state->request->extra_len] = '\0';
-
-       status= read_data(state->sock, state->request->extra_data.data,
-                         state->request->extra_len);
+       wreq->extra_data.data[wreq->extra_len] = '\0';
 
+       status = read_data(sock, wreq->extra_data.data, wreq->extra_len);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("Could not read extra data: %s\n",
                          nt_errstr(status)));
@@ -369,8 +362,26 @@ static void wb_domain_request_initialized(struct tevent_req *subreq)
                tevent_req_error(req, EINVAL);
                return;
        }
-       fstrcpy(state->domain->name, response->data.domain_info.name);
-       fstrcpy(state->domain->alt_name, response->data.domain_info.alt_name);
+
+       talloc_free(state->domain->name);
+       state->domain->name = talloc_strdup(state->domain,
+                                           response->data.domain_info.name);
+       if (state->domain->name == NULL) {
+               tevent_req_error(req, ENOMEM);
+               return;
+       }
+
+       if (response->data.domain_info.alt_name[0] != '\0') {
+               talloc_free(state->domain->alt_name);
+
+               state->domain->alt_name = talloc_strdup(state->domain,
+                               response->data.domain_info.alt_name);
+               if (state->domain->alt_name == NULL) {
+                       tevent_req_error(req, ENOMEM);
+                       return;
+               }
+       }
+
        state->domain->native_mode = response->data.domain_info.native_mode;
        state->domain->active_directory =
                response->data.domain_info.active_directory;
@@ -524,7 +535,7 @@ void winbind_child_died(pid_t pid)
 void winbindd_flush_negative_conn_cache(struct winbindd_domain *domain)
 {
        flush_negative_conn_cache_for_domain(domain->name);
-       if (*domain->alt_name) {
+       if (domain->alt_name != NULL) {
                flush_negative_conn_cache_for_domain(domain->alt_name);
        }
 }
@@ -608,11 +619,11 @@ void winbind_msg_offline(struct messaging_context *msg_ctx,
                   we only set it online / offline for that domain. */
 
                DEBUG(10,("winbind_msg_offline: sending message to pid %u for domain %s.\n",
-                       (unsigned int)child->pid, domain->name ));
+                       (unsigned int)child->pid, child->domain->name ));
 
                messaging_send_buf(msg_ctx, pid_to_procid(child->pid),
                                   MSG_WINBIND_OFFLINE,
-                                  (uint8 *)child->domain->name,
+                                  (const uint8_t *)child->domain->name,
                                   strlen(child->domain->name)+1);
        }
 }
@@ -661,7 +672,7 @@ void winbind_msg_online(struct messaging_context *msg_ctx,
                                messaging_send_buf(msg_ctx,
                                                   pid_to_procid(idmap->pid), 
                                                   MSG_WINBIND_ONLINE,
-                                                  (uint8 *)domain->name,
+                                                  (const uint8_t *)domain->name,
                                                   strlen(domain->name)+1);
                        }
                }
@@ -686,7 +697,7 @@ void winbind_msg_online(struct messaging_context *msg_ctx,
 
                messaging_send_buf(msg_ctx, pid_to_procid(child->pid),
                                   MSG_WINBIND_ONLINE,
-                                  (uint8 *)child->domain->name,
+                                  (const uint8_t *)child->domain->name,
                                   strlen(child->domain->name)+1);
        }
 }
@@ -981,10 +992,10 @@ static void machine_password_change_handler(struct tevent_context *ctx,
                                            struct timeval now,
                                            void *private_data)
 {
+       struct messaging_context *msg_ctx = winbind_messaging_context();
        struct winbindd_child *child =
                (struct winbindd_child *)private_data;
        struct rpc_pipe_client *netlogon_pipe = NULL;
-       TALLOC_CTX *frame;
        NTSTATUS result;
        struct timeval next_change;
 
@@ -1021,15 +1032,14 @@ static void machine_password_change_handler(struct tevent_context *ctx,
                return;
        }
 
-       frame = talloc_stackframe();
-
-       result = trust_pw_find_change_and_store_it(netlogon_pipe,
-                                                  frame,
-                                                  child->domain->name);
-       TALLOC_FREE(frame);
+       result = trust_pw_change(child->domain->conn.netlogon_creds,
+                                msg_ctx,
+                                netlogon_pipe->binding_handle,
+                                child->domain->name,
+                                false); /* force */
 
        DEBUG(10, ("machine_password_change_handler: "
-                  "trust_pw_find_change_and_store_it returned %s\n",
+                  "trust_pw_change returned %s\n",
                   nt_errstr(result)));
 
        if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) ) {
@@ -1038,7 +1048,7 @@ static void machine_password_change_handler(struct tevent_context *ctx,
                         "password was changed and we didn't know it. "
                         "Killing connections to domain %s\n",
                         child->domain->name));
-               TALLOC_FREE(child->domain->conn.netlogon_pipe);
+               invalidate_cm_connection(&child->domain->conn);
        }
 
        if (!calculate_next_machine_pwd_change(child->domain->name,
@@ -1223,6 +1233,11 @@ NTSTATUS winbindd_reinit_after_fork(const struct winbindd_child *myself,
        messaging_deregister(winbind_messaging_context(),
                             MSG_DEBUG, NULL);
 
+       messaging_deregister(winbind_messaging_context(),
+                            MSG_WINBIND_DOMAIN_OFFLINE, NULL);
+       messaging_deregister(winbind_messaging_context(),
+                            MSG_WINBIND_DOMAIN_ONLINE, NULL);
+
        /* We have destroyed all events in the winbindd_event_context
         * in reinit_after_fork(), so clean out all possible pending
         * event pointers. */
@@ -1304,7 +1319,7 @@ static void child_handler(struct tevent_context *ev, struct tevent_fd *fde,
        int iov_count;
 
        /* fetch a request from the main daemon */
-       status = child_read_request(&state->cli);
+       status = child_read_request(state->cli.sock, state->cli.request);
 
        if (!NT_STATUS_IS_OK(status)) {
                /* we lost contact with our parent */
@@ -1380,6 +1395,8 @@ static bool fork_domain_child(struct winbindd_child *child)
 
        if (child->pid == -1) {
                DEBUG(0, ("Could not fork: %s\n", strerror(errno)));
+               close(fdpair[0]);
+               close(fdpair[1]);
                return False;
        }