diff options
-rw-r--r-- | source3/include/proto.h | 31 | ||||
-rw-r--r-- | source3/libsmb/smbsock_connect.c | 113 | ||||
-rw-r--r-- | source3/torture/test_smbsock_any_connect.c | 5 | ||||
-rw-r--r-- | source3/winbindd/winbindd_cm.c | 7 |
4 files changed, 117 insertions, 39 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index c469888940..385a5371be 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5621,24 +5621,37 @@ int fncall_recv(struct tevent_req *req, int *perr); struct tevent_req *smbsock_connect_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const struct sockaddr_storage *addr, + uint16_t port, const char *called_name, - const char *calling_name); + int called_type, + const char *calling_name, + int calling_type); NTSTATUS smbsock_connect_recv(struct tevent_req *req, int *sock, - uint16_t *port); -NTSTATUS smbsock_connect(const struct sockaddr_storage *addr, - const char *called_name, const char *calling_name, - int *pfd, uint16_t *port); + uint16_t *ret_port); +NTSTATUS smbsock_connect(const struct sockaddr_storage *addr, uint16_t port, + const char *called_name, int called_type, + const char *calling_name, int calling_type, + int *pfd, uint16_t *ret_port); struct tevent_req *smbsock_any_connect_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const struct sockaddr_storage *addrs, const char **called_names, - size_t num_addrs); + int *called_types, + const char **calling_names, + int *calling_types, + size_t num_addrs, uint16_t port); NTSTATUS smbsock_any_connect_recv(struct tevent_req *req, int *pfd, - size_t *chosen_index, uint16_t *port); + size_t *chosen_index, uint16_t *chosen_port); NTSTATUS smbsock_any_connect(const struct sockaddr_storage *addrs, - const char **called_names, size_t num_addrs, - int *pfd, size_t *chosen_index, uint16_t *port); + const char **called_names, + int *called_types, + const char **calling_names, + int *calling_types, + size_t num_addrs, + uint16_t port, + int *pfd, size_t *chosen_index, + uint16_t *chosen_port); /* The following definitions come from rpc_server/srv_samr_nt.c */ NTSTATUS access_check_object( struct security_descriptor *psd, struct security_token *token, diff --git a/source3/libsmb/smbsock_connect.c b/source3/libsmb/smbsock_connect.c index 8ab12c5e2a..174d2aae57 100644 --- a/source3/libsmb/smbsock_connect.c +++ b/source3/libsmb/smbsock_connect.c @@ -176,7 +176,9 @@ struct smbsock_connect_state { struct tevent_context *ev; const struct sockaddr_storage *addr; const char *called_name; + uint8_t called_type; const char *calling_name; + uint8_t calling_type; struct tevent_req *req_139; struct tevent_req *req_445; int sock; @@ -191,8 +193,11 @@ static void smbsock_connect_do_139(struct tevent_req *subreq); struct tevent_req *smbsock_connect_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const struct sockaddr_storage *addr, + uint16_t port, const char *called_name, - const char *calling_name) + int called_type, + const char *calling_name, + int calling_type) { struct tevent_req *req, *subreq; struct smbsock_connect_state *state; @@ -206,11 +211,38 @@ struct tevent_req *smbsock_connect_send(TALLOC_CTX *mem_ctx, state->sock = -1; state->called_name = (called_name != NULL) ? called_name : "*SMBSERVER"; + state->called_type = + (called_type != -1) ? called_type : 0x20; state->calling_name = (calling_name != NULL) ? calling_name : global_myname(); + state->calling_type = + (calling_type != -1) ? calling_type : 0x00; talloc_set_destructor(state, smbsock_connect_state_destructor); + if (port == 139) { + subreq = tevent_wakeup_send(state, ev, timeval_set(0, 0)); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, smbsock_connect_do_139, req); + return req; + } + if (port != 0) { + state->req_445 = open_socket_out_send(state, ev, addr, port, + 5000); + if (tevent_req_nomem(state->req_445, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback( + state->req_445, smbsock_connect_connected, req); + return req; + } + + /* + * port==0, try both + */ + state->req_445 = open_socket_out_send(state, ev, addr, 445, 5000); if (tevent_req_nomem(state->req_445, req)) { return tevent_req_post(req, ev); @@ -254,8 +286,10 @@ static void smbsock_connect_do_139(struct tevent_req *subreq) return; } state->req_139 = nb_connect_send(state, state->ev, state->addr, - state->called_name, 0x20, - state->calling_name, 0x0); + state->called_name, + state->called_type, + state->calling_name, + state->calling_type); if (tevent_req_nomem(state->req_139, req)) { return; } @@ -311,7 +345,7 @@ static void smbsock_connect_connected(struct tevent_req *subreq) } NTSTATUS smbsock_connect_recv(struct tevent_req *req, int *sock, - uint16_t *port) + uint16_t *ret_port) { struct smbsock_connect_state *state = tevent_req_data( req, struct smbsock_connect_state); @@ -322,15 +356,16 @@ NTSTATUS smbsock_connect_recv(struct tevent_req *req, int *sock, } *sock = state->sock; state->sock = -1; - if (port != NULL) { - *port = state->port; + if (ret_port != NULL) { + *ret_port = state->port; } return NT_STATUS_OK; } -NTSTATUS smbsock_connect(const struct sockaddr_storage *addr, - const char *called_name, const char *calling_name, - int *pfd, uint16_t *port) +NTSTATUS smbsock_connect(const struct sockaddr_storage *addr, uint16_t port, + const char *called_name, int called_type, + const char *calling_name, int calling_type, + int *pfd, uint16_t *ret_port) { TALLOC_CTX *frame = talloc_stackframe(); struct event_context *ev; @@ -341,14 +376,16 @@ NTSTATUS smbsock_connect(const struct sockaddr_storage *addr, if (ev == NULL) { goto fail; } - req = smbsock_connect_send(frame, ev, addr, called_name, calling_name); + req = smbsock_connect_send(frame, ev, addr, port, + called_name, called_type, + calling_name, calling_type); if (req == NULL) { goto fail; } if (!tevent_req_poll_ntstatus(req, ev, &status)) { goto fail; } - status = smbsock_connect_recv(req, pfd, port); + status = smbsock_connect_recv(req, pfd, ret_port); fail: TALLOC_FREE(frame); return status; @@ -358,14 +395,18 @@ struct smbsock_any_connect_state { struct tevent_context *ev; const struct sockaddr_storage *addrs; const char **called_names; + int *called_types; + const char **calling_names; + int *calling_types; size_t num_addrs; + uint16_t port; struct tevent_req **requests; size_t num_sent; size_t num_received; int fd; - uint16_t port; + uint16_t chosen_port; size_t chosen_index; }; @@ -378,7 +419,10 @@ struct tevent_req *smbsock_any_connect_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const struct sockaddr_storage *addrs, const char **called_names, - size_t num_addrs) + int *called_types, + const char **calling_names, + int *calling_types, + size_t num_addrs, uint16_t port) { struct tevent_req *req, *subreq; struct smbsock_any_connect_state *state; @@ -392,6 +436,10 @@ struct tevent_req *smbsock_any_connect_send(TALLOC_CTX *mem_ctx, state->addrs = addrs; state->num_addrs = num_addrs; state->called_names = called_names; + state->called_types = called_types; + state->calling_names = calling_names; + state->calling_types = calling_types; + state->port = port; if (num_addrs == 0) { tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -456,9 +504,15 @@ static bool smbsock_any_connect_send_next( } subreq = smbsock_connect_send( state->requests, state->ev, &state->addrs[state->num_sent], + state->port, (state->called_names != NULL) ? state->called_names[state->num_sent] : NULL, - NULL); + (state->called_types != NULL) + ? state->called_types[state->num_sent] : -1, + (state->calling_names != NULL) + ? state->calling_names[state->num_sent] : NULL, + (state->calling_types != NULL) + ? state->calling_types[state->num_sent] : -1); if (tevent_req_nomem(subreq, req)) { return false; } @@ -478,7 +532,7 @@ static void smbsock_any_connect_connected(struct tevent_req *subreq) req, struct smbsock_any_connect_state); NTSTATUS status; int fd; - uint16_t port; + uint16_t chosen_port; size_t i; size_t chosen_index = 0; @@ -493,7 +547,7 @@ static void smbsock_any_connect_connected(struct tevent_req *subreq) return; } - status = smbsock_connect_recv(subreq, &fd, &port); + status = smbsock_connect_recv(subreq, &fd, &chosen_port); TALLOC_FREE(subreq); state->requests[chosen_index] = NULL; @@ -504,7 +558,7 @@ static void smbsock_any_connect_connected(struct tevent_req *subreq) */ TALLOC_FREE(state->requests); state->fd = fd; - state->port = port; + state->chosen_port = chosen_port; state->chosen_index = chosen_index; tevent_req_done(req); return; @@ -526,7 +580,8 @@ static void smbsock_any_connect_connected(struct tevent_req *subreq) } NTSTATUS smbsock_any_connect_recv(struct tevent_req *req, int *pfd, - size_t *chosen_index, uint16_t *port) + size_t *chosen_index, + uint16_t *chosen_port) { struct smbsock_any_connect_state *state = tevent_req_data( req, struct smbsock_any_connect_state); @@ -539,15 +594,21 @@ NTSTATUS smbsock_any_connect_recv(struct tevent_req *req, int *pfd, if (chosen_index != NULL) { *chosen_index = state->chosen_index; } - if (port != NULL) { - *port = state->port; + if (chosen_port != NULL) { + *chosen_port = state->chosen_port; } return NT_STATUS_OK; } NTSTATUS smbsock_any_connect(const struct sockaddr_storage *addrs, - const char **called_names, size_t num_addrs, - int *pfd, size_t *chosen_index, uint16_t *port) + const char **called_names, + int *called_types, + const char **calling_names, + int *calling_types, + size_t num_addrs, + uint16_t port, + int *pfd, size_t *chosen_index, + uint16_t *chosen_port) { TALLOC_CTX *frame = talloc_stackframe(); struct event_context *ev; @@ -558,15 +619,17 @@ NTSTATUS smbsock_any_connect(const struct sockaddr_storage *addrs, if (ev == NULL) { goto fail; } - req = smbsock_any_connect_send(frame, ev, addrs, called_names, - num_addrs); + req = smbsock_any_connect_send(frame, ev, addrs, + called_names, called_types, + calling_names, calling_types, + num_addrs, port); if (req == NULL) { goto fail; } if (!tevent_req_poll_ntstatus(req, ev, &status)) { goto fail; } - status = smbsock_any_connect_recv(req, pfd, chosen_index, port); + status = smbsock_any_connect_recv(req, pfd, chosen_index, chosen_port); fail: TALLOC_FREE(frame); return status; diff --git a/source3/torture/test_smbsock_any_connect.c b/source3/torture/test_smbsock_any_connect.c index 4ebb4f9b39..28a99815e7 100644 --- a/source3/torture/test_smbsock_any_connect.c +++ b/source3/torture/test_smbsock_any_connect.c @@ -34,8 +34,9 @@ bool run_smb_any_connect(int dummy) interpret_string_addr(&addrs[3], "192.168.99.8", 0); interpret_string_addr(&addrs[4], "192.168.99.9", 0); - status = smbsock_any_connect(addrs, NULL, ARRAY_SIZE(addrs), &fd, - &chosen_index, &port); + status = smbsock_any_connect(addrs, NULL, NULL, NULL, NULL, + ARRAY_SIZE(addrs), 0, + &fd, &chosen_index, &port); d_printf("smbsock_any_connect returned %s (fd %d)\n", nt_errstr(status), NT_STATUS_IS_OK(status) ? fd : -1); diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index f3eba90901..5f42120a4c 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -1382,8 +1382,8 @@ static bool find_new_dc(TALLOC_CTX *mem_ctx, if ((addrs == NULL) || (dcnames == NULL)) return False; - status = smbsock_any_connect(addrs, dcnames, num_addrs, - fd, &fd_index, NULL); + status = smbsock_any_connect(addrs, dcnames, NULL, NULL, NULL, + num_addrs, 0, fd, &fd_index, NULL); if (!NT_STATUS_IS_OK(status)) { for (i=0; i<num_dcs; i++) { char ab[INET6_ADDRSTRLEN]; @@ -1494,7 +1494,8 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain, { NTSTATUS status; - status = smbsock_connect(&domain->dcaddr, NULL, NULL, + status = smbsock_connect(&domain->dcaddr, 0, + NULL, -1, NULL, -1, &fd, NULL); if (!NT_STATUS_IS_OK(status)) { fd = -1; |