From d6734029924e849dcd336728dde8d24141e8ccc3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 22 May 2012 16:25:14 -0700 Subject: Fix bug #8953 - winbind can hang as nbt_getdc() has no timeout. Add a timeout_in_seconds parameter to nbt_getdc() to make it fail after that time with NT_STATUS_IO_TIMEOUT. --- source3/libsmb/clidgram.c | 12 ++++++++++++ source3/libsmb/clidgram.h | 1 + source3/libsmb/dsgetdcname.c | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 04964bd3f0..cfed06794d 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -437,6 +437,7 @@ NTSTATUS nbt_getdc_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, } NTSTATUS nbt_getdc(struct messaging_context *msg_ctx, + uint32_t timeout_in_seconds, const struct sockaddr_storage *dc_addr, const char *domain_name, const struct dom_sid *sid, @@ -449,6 +450,8 @@ NTSTATUS nbt_getdc(struct messaging_context *msg_ctx, TALLOC_CTX *frame = talloc_stackframe(); struct tevent_context *ev; struct tevent_req *req; + enum tevent_req_state err_state; + uint64_t error; NTSTATUS status = NT_STATUS_NO_MEMORY; ev = tevent_context_init(frame); @@ -460,12 +463,21 @@ NTSTATUS nbt_getdc(struct messaging_context *msg_ctx, if (req == NULL) { goto fail; } + if (!tevent_req_set_endtime(req, ev, + timeval_current_ofs(timeout_in_seconds, 0))) { + goto fail; + } if (!tevent_req_poll_ntstatus(req, ev, &status)) { goto fail; } status = nbt_getdc_recv(req, mem_ctx, pnt_version, dc_name, samlogon_response); fail: + if (ev && req && + tevent_req_is_error(req, &err_state, &error) && + err_state == TEVENT_REQ_TIMED_OUT) { + status = NT_STATUS_IO_TIMEOUT; + } TALLOC_FREE(frame); return status; } diff --git a/source3/libsmb/clidgram.h b/source3/libsmb/clidgram.h index a449724a41..6cd6222df6 100644 --- a/source3/libsmb/clidgram.h +++ b/source3/libsmb/clidgram.h @@ -37,6 +37,7 @@ NTSTATUS nbt_getdc_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint32_t *nt_version, const char **dc_name, struct netlogon_samlogon_response **samlogon_response); NTSTATUS nbt_getdc(struct messaging_context *msg_ctx, + uint32_t timeout_in_seconds, const struct sockaddr_storage *dc_addr, const char *domain_name, const struct dom_sid *sid, diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 5df833f40f..05be272450 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -946,7 +946,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, return NT_STATUS_UNSUCCESSFUL; } - status = nbt_getdc(msg_ctx, &dclist[i].ss, domain_name, + status = nbt_getdc(msg_ctx, 10, &dclist[i].ss, domain_name, NULL, nt_version, mem_ctx, &nt_version, &dc_name, &r); if (NT_STATUS_IS_OK(status)) { -- cgit