summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2012-05-22 16:25:14 -0700
committerJeremy Allison <jra@samba.org>2012-05-22 16:25:14 -0700
commitd6734029924e849dcd336728dde8d24141e8ccc3 (patch)
tree6c9140be039bff749cea88213b0b33a47c51243d /source3
parentf9e4105f4170181989c44a2326a8a8a89314fc98 (diff)
downloadsamba-d6734029924e849dcd336728dde8d24141e8ccc3.tar.gz
samba-d6734029924e849dcd336728dde8d24141e8ccc3.tar.bz2
samba-d6734029924e849dcd336728dde8d24141e8ccc3.zip
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.
Diffstat (limited to 'source3')
-rw-r--r--source3/libsmb/clidgram.c12
-rw-r--r--source3/libsmb/clidgram.h1
-rw-r--r--source3/libsmb/dsgetdcname.c2
-rw-r--r--source3/winbindd/winbindd_cm.c2
4 files changed, 15 insertions, 2 deletions
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)) {
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index 4188b5e6ed..cf1eb8bd0e 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -1161,7 +1161,7 @@ static bool dcip_to_name(TALLOC_CTX *mem_ctx,
}
#endif
- status = nbt_getdc(winbind_messaging_context(), pss, domain->name,
+ status = nbt_getdc(winbind_messaging_context(), 10, pss, domain->name,
&domain->sid, nt_version, mem_ctx, &nt_version,
&dc_name, NULL);
if (NT_STATUS_IS_OK(status)) {