Fix bug #8953 - winbind can hang as nbt_getdc() has no timeout.
authorJeremy Allison <jra@samba.org>
Tue, 22 May 2012 23:25:14 +0000 (16:25 -0700)
committerJeremy Allison <jra@samba.org>
Tue, 22 May 2012 23:25:14 +0000 (16:25 -0700)
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
source3/libsmb/clidgram.h
source3/libsmb/dsgetdcname.c
source3/winbindd/winbindd_cm.c

index 04964bd3f0e4a6f2b40c713f4a99f5f1d66a6e30..cfed06794d90b6e06e485495473cbe0ba563c731 100644 (file)
@@ -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;
 }
index a449724a41a7517636ce8d3b6aa4fa5048a5bee7..6cd6222df68bdf44ea2ee3bc1fbd5c91959af580 100644 (file)
@@ -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,
index 5df833f40f843040db30446e34fef72fee6d7371..05be272450210739bf76bf9a425f523543029482 100644 (file)
@@ -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)) {
index 4188b5e6edba62f61ec5135d89b06e2a8c783788..cf1eb8bd0e93a114e6c062c6ee15cb4313b7e274 100644 (file)
@@ -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)) {