Skip to content

Commit

Permalink
s4: libcli/finddcs_cldap: continue processing CLDAP until all address…
Browse files Browse the repository at this point in the history
…es are used

This is a subtle bug that causes CLDAP pings to fail if SRV records
discovered cannot be resolved or connection to them cannot be
established. The code that fires up CLDAP ping will silently cancel
the whole tevent request without going to the next server in the queue.

This may happen, for example, when connection to IPv6 addresses couldn't
be established, or when IPv4 address is not online or blocked by
firewall.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11284

Signed-off-by: Alexander Bokovoy <[email protected]>
Reviewed-by: Stefan Metzmacher <[email protected]>
  • Loading branch information
abbra authored and metze-samba committed May 20, 2015
1 parent 47a3f9c commit eb029b3
Showing 1 changed file with 32 additions and 10 deletions.
42 changes: 32 additions & 10 deletions source4/libcli/finddcs_cldap.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct finddcs_cldap_state {
uint32_t srv_address_index;
struct cldap_socket *cldap;
struct cldap_netlogon *netlogon;
NTSTATUS status;
};

static void finddcs_cldap_srv_resolved(struct composite_context *ctx);
Expand Down Expand Up @@ -245,10 +246,15 @@ static void finddcs_cldap_next_server(struct finddcs_cldap_state *state)
struct tevent_req *subreq;
struct tsocket_address *dest;
int ret;
NTSTATUS status;

TALLOC_FREE(state->cldap);

if (state->srv_addresses[state->srv_address_index] == NULL) {
tevent_req_nterror(state->req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
if (NT_STATUS_IS_OK(state->status)) {
tevent_req_nterror(state->req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
} else {
tevent_req_nterror(state->req, state->status);
}
DEBUG(2,("finddcs: No matching CLDAP server found\n"));
return;
}
Expand All @@ -259,22 +265,29 @@ static void finddcs_cldap_next_server(struct finddcs_cldap_state *state)
389,
&dest);
if (ret == 0) {
status = NT_STATUS_OK;
state->status = NT_STATUS_OK;
} else {
status = map_nt_error_from_unix_common(errno);
state->status = map_nt_error_from_unix_common(errno);
}
if (tevent_req_nterror(state->req, status)) {
if (!NT_STATUS_IS_OK(state->status)) {
state->srv_address_index++;
finddcs_cldap_next_server(state);
return;
}

status = cldap_socket_init(state, NULL, dest, &state->cldap);
if (tevent_req_nterror(state->req, status)) {
state->status = cldap_socket_init(state, NULL, dest, &state->cldap);
if (!NT_STATUS_IS_OK(state->status)) {
state->srv_address_index++;
finddcs_cldap_next_server(state);
return;
}

TALLOC_FREE(state->netlogon);
state->netlogon = talloc_zero(state, struct cldap_netlogon);
if (tevent_req_nomem(state->netlogon, state->req)) {
if (state->netlogon == NULL) {
state->status = NT_STATUS_NO_MEMORY;
state->srv_address_index++;
finddcs_cldap_next_server(state);
return;
}

Expand All @@ -283,7 +296,10 @@ static void finddcs_cldap_next_server(struct finddcs_cldap_state *state)
}
if (state->domain_sid) {
state->netlogon->in.domain_sid = dom_sid_string(state, state->domain_sid);
if (tevent_req_nomem(state->netlogon->in.domain_sid, state->req)) {
if (state->netlogon->in.domain_sid == NULL) {
state->status = NT_STATUS_NO_MEMORY;
state->srv_address_index++;
finddcs_cldap_next_server(state);
return;
}
}
Expand All @@ -299,7 +315,10 @@ static void finddcs_cldap_next_server(struct finddcs_cldap_state *state)

subreq = cldap_netlogon_send(state, state->ev,
state->cldap, state->netlogon);
if (tevent_req_nomem(subreq, state->req)) {
if (subreq == NULL) {
state->status = NT_STATUS_NO_MEMORY;
state->srv_address_index++;
finddcs_cldap_next_server(state);
return;
}

Expand All @@ -321,6 +340,7 @@ static void finddcs_cldap_netlogon_replied(struct tevent_req *subreq)
TALLOC_FREE(subreq);
TALLOC_FREE(state->cldap);
if (!NT_STATUS_IS_OK(status)) {
state->status = status;
state->srv_address_index++;
finddcs_cldap_next_server(state);
return;
Expand Down Expand Up @@ -364,6 +384,7 @@ static void finddcs_cldap_name_resolved(struct composite_context *ctx)

state->srv_address_index = 0;

state->status = NT_STATUS_OK;
finddcs_cldap_next_server(state);
}

Expand Down Expand Up @@ -416,6 +437,7 @@ static void finddcs_cldap_srv_resolved(struct composite_context *ctx)

state->srv_address_index = 0;

state->status = NT_STATUS_OK;
finddcs_cldap_next_server(state);
}

Expand Down

0 comments on commit eb029b3

Please sign in to comment.