diff options
author | Gerald Carter <jerry@samba.org> | 2005-09-30 17:13:37 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2005-09-30 17:13:37 +0000 |
commit | 796cade5585f1237e2c047293ad6a9b8a4e923ba (patch) | |
tree | 5f3a22ba40783ce548328a44b9262a451f33ad27 /source/nsswitch/winbindd_dual.c | |
parent | 38730479cfd0c1d46fcb8950fc30da3fa3f8b154 (diff) | |
download | samba-796cade5585f1237e2c047293ad6a9b8a4e923ba.tar.gz samba-796cade5585f1237e2c047293ad6a9b8a4e923ba.tar.xz samba-796cade5585f1237e2c047293ad6a9b8a4e923ba.zip |
r10656: BIG merge from trunk. Features not copied over
* \PIPE\unixinfo
* winbindd's {group,alias}membership new functions
* winbindd's lookupsids() functionality
* swat (trunk changes to be reverted as per discussion with Deryck)
Diffstat (limited to 'source/nsswitch/winbindd_dual.c')
-rw-r--r-- | source/nsswitch/winbindd_dual.c | 151 |
1 files changed, 92 insertions, 59 deletions
diff --git a/source/nsswitch/winbindd_dual.c b/source/nsswitch/winbindd_dual.c index ec0b7a36e2f..60b74114172 100644 --- a/source/nsswitch/winbindd_dual.c +++ b/source/nsswitch/winbindd_dual.c @@ -38,35 +38,48 @@ /* Read some data from a client connection */ -static void dual_client_read(struct winbindd_cli_state *state) +static void child_read_request(struct winbindd_cli_state *state) { - int n; - + ssize_t len; + /* Read data */ - n = sys_read(state->sock, state->read_buf_len + - (char *)&state->request, - sizeof(state->request) - state->read_buf_len); - - DEBUG(10,("client_read: read %d bytes. Need %ld more for a full " - "request.\n", n, (unsigned long)(sizeof(state->request) - n - - state->read_buf_len) )); + len = read_data(state->sock, (char *)&state->request, + sizeof(state->request)); - /* Read failed, kill client */ - - if (n == -1 || n == 0) { - DEBUG(5,("read failed on sock %d, pid %lu: %s\n", - state->sock, (unsigned long)state->pid, - (n == -1) ? strerror(errno) : "EOF")); - + if (len != sizeof(state->request)) { + DEBUG(0, ("Got invalid request length: %d\n", (int)len)); + state->finished = True; + return; + } + + if (state->request.extra_len == 0) { + state->request.extra_data = NULL; + return; + } + + DEBUG(10, ("Need to read %d extra bytes\n", (int)state->request.extra_len)); + + state->request.extra_data = + SMB_MALLOC_ARRAY(char, state->request.extra_len + 1); + + if (state->request.extra_data == NULL) { + DEBUG(0, ("malloc failed\n")); + state->finished = True; + return; + } + + /* Ensure null termination */ + state->request.extra_data[state->request.extra_len] = '\0'; + + len = read_data(state->sock, state->request.extra_data, + state->request.extra_len); + + if (len != state->request.extra_len) { + DEBUG(0, ("Could not read extra data\n")); state->finished = True; return; } - - /* Update client state */ - - state->read_buf_len += n; - state->last_access = time(NULL); } /* @@ -86,6 +99,7 @@ struct winbindd_async_request { void *private_data; }; +static void async_main_request_sent(void *private_data, BOOL success); static void async_request_sent(void *private_data, BOOL success); static void async_reply_recv(void *private_data, BOOL success); static void schedule_async_request(struct winbindd_child *child); @@ -122,7 +136,7 @@ void async_request(TALLOC_CTX *mem_ctx, struct winbindd_child *child, return; } -static void async_request_sent(void *private_data, BOOL success) +static void async_main_request_sent(void *private_data, BOOL success) { struct winbindd_async_request *state = talloc_get_type_abort(private_data, struct winbindd_async_request); @@ -136,6 +150,30 @@ static void async_request_sent(void *private_data, BOOL success) return; } + if (state->request->extra_len == 0) { + async_request_sent(private_data, True); + return; + } + + setup_async_write(&state->child->event, state->request->extra_data, + state->request->extra_len, + async_request_sent, state); +} + +static void async_request_sent(void *private_data_data, BOOL success) +{ + struct winbindd_async_request *state = + talloc_get_type_abort(private_data_data, struct winbindd_async_request); + + if (!success) { + DEBUG(5, ("Could not send async request\n")); + + state->response->length = sizeof(struct winbindd_response); + state->response->result = WINBINDD_ERROR; + state->continuation(state->private_data, False); + return; + } + /* Request successfully sent to the child, setup the wait for reply */ setup_async_read(&state->child->event, @@ -196,7 +234,7 @@ static void schedule_async_request(struct winbindd_child *child) setup_async_write(&child->event, request->request, sizeof(*request->request), - async_request_sent, request); + async_main_request_sent, request); return; } @@ -205,31 +243,31 @@ struct domain_request_state { struct winbindd_domain *domain; struct winbindd_request *request; struct winbindd_response *response; - void (*continuation)(void *private_data, BOOL success); - void *private_data; + void (*continuation)(void *private_data_data, BOOL success); + void *private_data_data; }; -static void domain_init_recv(void *private_data, BOOL success); +static void domain_init_recv(void *private_data_data, BOOL success); void async_domain_request(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, struct winbindd_request *request, struct winbindd_response *response, - void (*continuation)(void *private_data, BOOL success), - void *private_data) + void (*continuation)(void *private_data_data, BOOL success), + void *private_data_data) { struct domain_request_state *state; if (domain->initialized) { async_request(mem_ctx, &domain->child, request, response, - continuation, private_data); + continuation, private_data_data); return; } state = TALLOC_P(mem_ctx, struct domain_request_state); if (state == NULL) { DEBUG(0, ("talloc failed\n")); - continuation(private_data, False); + continuation(private_data_data, False); return; } @@ -238,15 +276,15 @@ void async_domain_request(TALLOC_CTX *mem_ctx, state->request = request; state->response = response; state->continuation = continuation; - state->private_data = private_data; + state->private_data_data = private_data_data; init_child_connection(domain, domain_init_recv, state); } -static void recvfrom_child(void *private_data, BOOL success) +static void recvfrom_child(void *private_data_data, BOOL success) { struct winbindd_cli_state *state = - talloc_get_type_abort(private_data, struct winbindd_cli_state); + talloc_get_type_abort(private_data_data, struct winbindd_cli_state); enum winbindd_result result = state->response.result; /* This is an optimization: The child has written directly to the @@ -278,20 +316,20 @@ void sendto_domain(struct winbindd_cli_state *state, recvfrom_child, state); } -static void domain_init_recv(void *private_data, BOOL success) +static void domain_init_recv(void *private_data_data, BOOL success) { struct domain_request_state *state = - talloc_get_type_abort(private_data, struct domain_request_state); + talloc_get_type_abort(private_data_data, struct domain_request_state); if (!success) { DEBUG(5, ("Domain init returned an error\n")); - state->continuation(state->private_data, False); + state->continuation(state->private_data_data, False); return; } async_request(state->mem_ctx, &state->domain->child, state->request, state->response, - state->continuation, state->private_data); + state->continuation, state->private_data_data); } struct winbindd_child_dispatch_table { @@ -466,39 +504,34 @@ static BOOL fork_domain_child(struct winbindd_child *child) main_loop_talloc_free(); /* fetch a request from the main daemon */ - dual_client_read(&state); + child_read_request(&state); if (state.finished) { /* we lost contact with our parent */ exit(0); } - /* process full rquests */ - if (state.read_buf_len == sizeof(state.request)) { - DEBUG(4,("child daemon request %d\n", - (int)state.request.cmd)); + DEBUG(4,("child daemon request %d\n", (int)state.request.cmd)); - ZERO_STRUCT(state.response); - state.request.null_term = '\0'; - child_process_request(child->domain, &state); + ZERO_STRUCT(state.response); + state.request.null_term = '\0'; + child_process_request(child->domain, &state); - cache_store_response(sys_getpid(), &state.response); + SAFE_FREE(state.request.extra_data); - SAFE_FREE(state.response.extra_data); + cache_store_response(sys_getpid(), &state.response); - /* We just send the result code back, the result - * structure needs to be fetched via the - * winbindd_cache. Hmm. That needs fixing... */ + SAFE_FREE(state.response.extra_data); - if (write_data(state.sock, - (void *)&state.response.result, - sizeof(state.response.result)) != - sizeof(state.response.result)) { - DEBUG(0, ("Could not write result\n")); - exit(1); - } + /* We just send the result code back, the result + * structure needs to be fetched via the + * winbindd_cache. Hmm. That needs fixing... */ - state.read_buf_len = 0; + if (write_data(state.sock, (void *)&state.response.result, + sizeof(state.response.result)) != + sizeof(state.response.result)) { + DEBUG(0, ("Could not write result\n")); + exit(1); } } } |