diff options
author | Gerald Carter <jerry@samba.org> | 2007-06-22 04:09:38 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2007-06-22 04:09:38 +0000 |
commit | 74656050cd63ba6e78b50e8634041b60858a1bbb (patch) | |
tree | e48a0f70ae53af38b02f57934095439cafd70770 | |
parent | 432b88e0b65accb4657771651994dd64801f35fc (diff) | |
download | samba-74656050cd63ba6e78b50e8634041b60858a1bbb.tar.gz |
r23580: Merge bug fix for 4720 and Jeremy's winbindd_dual.c changes (still testing these)
-rw-r--r-- | WHATSNEW.txt | 5 | ||||
-rw-r--r-- | source/client/client.c | 26 | ||||
-rw-r--r-- | source/nsswitch/winbindd_dual.c | 95 |
3 files changed, 63 insertions, 63 deletions
diff --git a/WHATSNEW.txt b/WHATSNEW.txt index 58680368788..30f17c156e6 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -55,6 +55,11 @@ o Guenther Deschner <gd@samba.org> * Add more netlogon GetDcName() client calls. +o SATOH Fumiyasu <fumiyas@osstech.co.jp> + * BUG 4720: Fix smbclient connections to share names containing + multibyte characters. + + o Steve Langasek <vorlon@debian.org> * Allow SIGTERM to cause nmbd to exit on awaiting an interface to come up. diff --git a/source/client/client.c b/source/client/client.c index f0ee12aa793..727e8db1f11 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -3915,14 +3915,6 @@ static int do_message_op(void) /* if the service has not yet been specified lets see if it is available in the popt stack */ if (!service_opt && poptPeekArg(pc)) { pstrcpy(service, poptGetArg(pc)); - /* Convert any '/' characters in the service name to '\' characters */ - string_replace(service, '/','\\'); - - if (count_chars(service,'\\') < 3) { - d_printf("\n%s: Not enough '\\' characters in service\n",service); - poptPrintUsage(pc, stderr, 0); - exit(1); - } service_opt = True; } @@ -4010,14 +4002,6 @@ static int do_message_op(void) /* if the service has not yet been specified lets see if it is available in the popt stack */ if (!service_opt && poptPeekArg(pc)) { pstrcpy(service, poptGetArg(pc)); - /* Convert any '/' characters in the service name to '\' characters */ - string_replace(service, '/','\\'); - - if (count_chars(service,'\\') < 3) { - d_printf("\n%s: Not enough '\\' characters in service\n",service); - poptPrintUsage(pc, stderr, 0); - exit(1); - } service_opt = True; } @@ -4056,6 +4040,16 @@ static int do_message_op(void) } load_interfaces(); + + if (service_opt) { + /* Convert any '/' characters in the service name to '\' characters */ + string_replace(service, '/','\\'); + if (count_chars(service,'\\') < 3) { + d_printf("\n%s: Not enough '\\' characters in service\n",service); + poptPrintUsage(pc, stderr, 0); + exit(1); + } + } if ( strlen(new_workgroup) != 0 ) set_global_myworkgroup( new_workgroup ); diff --git a/source/nsswitch/winbindd_dual.c b/source/nsswitch/winbindd_dual.c index 169ea5e6882..ffbedfa9bf2 100644 --- a/source/nsswitch/winbindd_dual.c +++ b/source/nsswitch/winbindd_dual.c @@ -97,6 +97,8 @@ struct winbindd_async_request { struct winbindd_response *response; void (*continuation)(void *private_data, BOOL success); struct timed_event *reply_timeout_event; + pid_t child_pid; /* pid of the child we're waiting on. Used to detect + a restart of the child (child->pid != child_pid). */ void *private_data; }; @@ -174,36 +176,51 @@ static void async_request_timeout_handler(struct event_context *ctx, struct winbindd_async_request *state = talloc_get_type_abort(private_data, struct winbindd_async_request); - /* Deal with the reply - set to error. */ + DEBUG(0,("async_request_timeout_handler: child pid %u is not responding. " + "Closing connection to it.\n", + state->child_pid )); + /* Deal with the reply - set to error. */ async_reply_recv(private_data, False); +} - DEBUG(0,("async_request_timeout_handler: child pid %u is not responding. " - "Closing connection to it.\n", - state->child->pid )); +/************************************************************** + Common function called on both async send and recv fail. + Cleans up the child and schedules the next request. +**************************************************************/ - /* Send kill signal to child. */ - kill(state->child->pid, SIGTERM); +static void async_request_fail(struct winbindd_async_request *state) +{ + DLIST_REMOVE(state->child->requests, state); - /* - * Close the socket to the child. - */ + TALLOC_FREE(state->reply_timeout_event); + + SMB_ASSERT(state->child_pid != (pid_t)0); + + /* If not already reaped, send kill signal to child. */ + if (state->child->pid == state->child_pid) { + kill(state->child_pid, SIGTERM); + + /* + * Close the socket to the child. + */ + winbind_child_died(state->child_pid); + } - winbind_child_died(state->child->pid); + state->response->length = sizeof(struct winbindd_response); + state->response->result = WINBINDD_ERROR; + state->continuation(state->private_data, False); } static void async_request_sent(void *private_data_data, BOOL success) { - uint32_t timeout = 30; 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); + DEBUG(5, ("Could not send async request to child pid %u\n", + (unsigned int)state->child_pid )); + async_request_fail(state); return; } @@ -215,25 +232,14 @@ static void async_request_sent(void *private_data_data, BOOL success) async_reply_recv, state); /* - * Normal timeouts are 30s, but auth requests may take a long - * time to timeout. - */ - - if (state->request->cmd == WINBINDD_PAM_AUTH || - state->request->cmd == WINBINDD_PAM_AUTH_CRAP ) { - - timeout = 300; - } - - /* - * Set up a timeout of 30 seconds for the response. + * Set up a timeout of 300 seconds for the response. * If we don't get it close the child socket and * report failure. */ state->reply_timeout_event = event_add_timed(winbind_event_context(), NULL, - timeval_current_ofs(timeout,0), + timeval_current_ofs(300,0), "async_request_timeout", async_request_timeout_handler, state); @@ -248,27 +254,23 @@ static void async_reply_recv(void *private_data, BOOL success) talloc_get_type_abort(private_data, struct winbindd_async_request); struct winbindd_child *child = state->child; - if (state->reply_timeout_event) { - TALLOC_FREE(state->reply_timeout_event); - } + TALLOC_FREE(state->reply_timeout_event); state->response->length = sizeof(struct winbindd_response); if (!success) { - DEBUG(5, ("Could not receive async reply\n")); + DEBUG(5, ("Could not receive async reply from child pid %u\n", + (unsigned int)state->child_pid )); - cache_cleanup_response(child->pid); - DLIST_REMOVE(child->requests, state); - - state->response->result = WINBINDD_ERROR; - state->continuation(state->private_data, False); + cache_cleanup_response(state->child_pid); + async_request_fail(state); return; } - SMB_ASSERT(cache_retrieve_response(child->pid, + SMB_ASSERT(cache_retrieve_response(state->child_pid, state->response)); - cache_cleanup_response(child->pid); + cache_cleanup_response(state->child_pid); DLIST_REMOVE(child->requests, state); @@ -303,6 +305,9 @@ static void schedule_async_request(struct winbindd_child *child) return; } + /* Now we know who we're sending to - remember the pid. */ + request->child_pid = child->pid; + setup_async_write(&child->event, request->request, sizeof(*request->request), async_main_request_sent, request); @@ -517,7 +522,7 @@ void winbind_child_died(pid_t pid) } if (child == NULL) { - DEBUG(0, ("Unknown child %d died!\n", pid)); + DEBUG(5, ("Already reaped child %u died\n", (unsigned int)pid)); return; } @@ -713,9 +718,7 @@ static void account_lockout_policy_handler(struct event_context *ctx, DEBUG(10,("account_lockout_policy_handler called\n")); - if (child->lockout_policy_event) { - TALLOC_FREE(child->lockout_policy_event); - } + TALLOC_FREE(child->lockout_policy_event); methods = child->domain->methods; @@ -962,9 +965,7 @@ static BOOL fork_domain_child(struct winbindd_child *child) for (domain = domain_list(); domain; domain = domain->next) { if (domain != child->domain) { - if (domain->check_online_event) { - TALLOC_FREE(domain->check_online_event); - } + TALLOC_FREE(domain->check_online_event); } } |