From c049d098d1e56a56378bc105d1df89c34cc06ddb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 9 May 2009 20:04:27 +0200 Subject: Convert the main winbind client communication to wb_reqtrans.c --- source3/Makefile.in | 1 + source3/winbindd/winbindd.c | 188 +++++++++++++++----------------------------- source3/winbindd/winbindd.h | 2 +- 3 files changed, 66 insertions(+), 125 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 24117d345d..4115ffaf21 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1132,6 +1132,7 @@ WINBINDD_OBJ1 = \ winbindd/winbindd_locator.o \ winbindd/winbindd_ndr.o \ auth/token_util.o \ + ../nsswitch/libwbclient/wb_reqtrans.o \ smbd/connection.o WINBINDD_OBJ = \ diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index 9538a6391d..cb796eb7f4 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -24,6 +24,7 @@ #include "includes.h" #include "winbindd.h" +#include "../../nsswitch/libwbclient/wbc_async.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND @@ -656,58 +657,52 @@ void setup_async_write(struct winbindd_fd_event *event, void *data, size_t lengt * to call request_finished which schedules sending the response. */ -static void request_len_recv(void *private_data, bool success); -static void request_recv(void *private_data, bool success); -static void request_main_recv(void *private_data, bool success); static void request_finished(struct winbindd_cli_state *state); -static void response_main_sent(void *private_data, bool success); -static void response_extra_sent(void *private_data, bool success); -static void response_extra_sent(void *private_data, bool success) +static void winbind_client_request_read(struct tevent_req *req); +static void winbind_client_response_written(struct tevent_req *req); + +static void request_finished(struct winbindd_cli_state *state) { - struct winbindd_cli_state *state = - talloc_get_type_abort(private_data, struct winbindd_cli_state); + struct tevent_req *req; - TALLOC_FREE(state->mem_ctx); + TALLOC_FREE(state->request); - if (!success) { - state->finished = True; + req = wb_resp_write_send(state, winbind_event_context(), + state->out_queue, state->sock, + &state->response); + if (req == NULL) { + state->finished = true; return; } - - setup_async_read(&state->fd_event, state->request, sizeof(uint32), - request_len_recv, state); + tevent_req_set_callback(req, winbind_client_response_written, state); } -static void response_main_sent(void *private_data, bool success) +static void winbind_client_response_written(struct tevent_req *req) { - struct winbindd_cli_state *state = - talloc_get_type_abort(private_data, struct winbindd_cli_state); - - if (!success) { - state->finished = True; + struct winbindd_cli_state *state = tevent_req_callback_data( + req, struct winbindd_cli_state); + ssize_t ret; + int err; + + ret = wb_resp_write_recv(req, &err); + TALLOC_FREE(req); + if (ret == -1) { + DEBUG(2, ("Could not write response to client: %s\n", + strerror(err))); + state->finished = true; return; } - if (state->response.length == sizeof(state->response)) { - TALLOC_FREE(state->mem_ctx); + TALLOC_FREE(state->mem_ctx); - setup_async_read(&state->fd_event, state->request, - sizeof(uint32), request_len_recv, state); + req = wb_req_read_send(state, winbind_event_context(), state->sock, + WINBINDD_MAX_EXTRA_DATA); + if (req == NULL) { + state->finished = true; return; } - - setup_async_write(&state->fd_event, state->response.extra_data.data, - state->response.length - sizeof(state->response), - response_extra_sent, state); -} - -static void request_finished(struct winbindd_cli_state *state) -{ - /* Make sure request.extra_data is freed when finish processing a request */ - SAFE_FREE(state->request->extra_data.data); - setup_async_write(&state->fd_event, &state->response, - sizeof(state->response), response_main_sent, state); + tevent_req_set_callback(req, winbind_client_request_read, state); } void request_error(struct winbindd_cli_state *state) @@ -724,90 +719,13 @@ void request_ok(struct winbindd_cli_state *state) request_finished(state); } -static void request_len_recv(void *private_data, bool success) -{ - struct winbindd_cli_state *state = - talloc_get_type_abort(private_data, struct winbindd_cli_state); - - if (!success) { - state->finished = True; - return; - } - - if (*(uint32 *)(state->request) != sizeof(*state->request)) { - DEBUG(0,("request_len_recv: Invalid request size received: %d (expected %u)\n", - *(uint32_t *)(state->request), - (uint32_t)sizeof(*state->request))); - state->finished = True; - return; - } - - setup_async_read(&state->fd_event, (uint32 *)(state->request)+1, - sizeof(*state->request) - sizeof(uint32), - request_main_recv, state); -} - -static void request_main_recv(void *private_data, bool success) -{ - struct winbindd_cli_state *state = - talloc_get_type_abort(private_data, struct winbindd_cli_state); - - if (!success) { - state->finished = True; - return; - } - - if (state->request->extra_len == 0) { - state->request->extra_data.data = NULL; - request_recv(state, True); - return; - } - - if ((!state->privileged) && - (state->request->extra_len > WINBINDD_MAX_EXTRA_DATA)) { - DEBUG(3, ("Got request with %d bytes extra data on " - "unprivileged socket\n", - (int)state->request->extra_len)); - state->request->extra_data.data = NULL; - state->finished = True; - return; - } - - state->request->extra_data.data = - SMB_MALLOC_ARRAY(char, state->request->extra_len + 1); - - if (state->request->extra_data.data == NULL) { - DEBUG(0, ("malloc failed\n")); - state->finished = True; - return; - } - - /* Ensure null termination */ - state->request->extra_data.data[state->request->extra_len] = '\0'; - - setup_async_read(&state->fd_event, state->request->extra_data.data, - state->request->extra_len, request_recv, state); -} - -static void request_recv(void *private_data, bool success) -{ - struct winbindd_cli_state *state = - talloc_get_type_abort(private_data, struct winbindd_cli_state); - - if (!success) { - state->finished = True; - return; - } - - process_request(state); -} - /* Process a new connection by adding it to the client connection list */ static void new_connection(int listen_sock, bool privileged) { struct sockaddr_un sunaddr; struct winbindd_cli_state *state; + struct tevent_req *req; socklen_t len; int sock; @@ -831,26 +749,51 @@ static void new_connection(int listen_sock, bool privileged) close(sock); return; } - state->request = &state->_request; state->sock = sock; + state->out_queue = tevent_queue_create(state, "winbind client reply"); + if (state->out_queue == NULL) { + close(sock); + TALLOC_FREE(state); + return; + } + state->last_access = time(NULL); state->privileged = privileged; - state->fd_event.fd = state->sock; - state->fd_event.flags = 0; - add_fd_event(&state->fd_event); - - setup_async_read(&state->fd_event, state->request, sizeof(uint32), - request_len_recv, state); + req = wb_req_read_send(state, winbind_event_context(), state->sock, + WINBINDD_MAX_EXTRA_DATA); + if (req == NULL) { + TALLOC_FREE(state); + close(sock); + return; + } + tevent_req_set_callback(req, winbind_client_request_read, state); /* Add to connection list */ winbindd_add_client(state); } +static void winbind_client_request_read(struct tevent_req *req) +{ + struct winbindd_cli_state *state = tevent_req_callback_data( + req, struct winbindd_cli_state); + ssize_t ret; + int err; + + ret = wb_req_read_recv(req, state, &state->request, &err); + if (ret == -1) { + DEBUG(2, ("Could not read client request: %s\n", + strerror(err))); + state->finished = true; + return; + } + process_request(state); +} + /* Remove a client connection from client connection list */ static void remove_client(struct winbindd_cli_state *state) @@ -888,8 +831,6 @@ static void remove_client(struct winbindd_cli_state *state) TALLOC_FREE(state->mem_ctx); - remove_fd_event(&state->fd_event); - /* Remove from list and free */ winbindd_remove_client(state); @@ -906,7 +847,6 @@ static bool remove_idle_client(void) for (state = winbindd_client_list(); state; state = state->next) { if (state->response.result != WINBINDD_PENDING && - state->fd_event.flags == EVENT_FD_READ && !state->getpwent_state && !state->getgrent_state) { nidle++; if (!last_access || state->last_access < last_access) { diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h index 31d73a5cc8..314643c4e1 100644 --- a/source3/winbindd/winbindd.h +++ b/source3/winbindd/winbindd.h @@ -61,7 +61,6 @@ struct sid_ctr { struct winbindd_cli_state { struct winbindd_cli_state *prev, *next; /* Linked list pointers */ int sock; /* Open socket from client */ - struct winbindd_fd_event fd_event; pid_t pid; /* pid of client */ bool finished; /* Can delete from list */ bool write_extra_data; /* Write extra_data field */ @@ -71,6 +70,7 @@ struct winbindd_cli_state { TALLOC_CTX *mem_ctx; /* memory per request */ struct winbindd_request *request; /* Request from client */ struct winbindd_request _request; + struct tevent_queue *out_queue; struct winbindd_response response; /* Respose to client */ bool getpwent_initialized; /* Has getpwent_state been * initialized? */ -- cgit