summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h31
-rw-r--r--source3/libsmb/smbsock_connect.c113
-rw-r--r--source3/torture/test_smbsock_any_connect.c5
-rw-r--r--source3/winbindd/winbindd_cm.c7
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;