diff options
author | Volker Lendecke <vl@samba.org> | 2011-05-26 22:00:07 +0200 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2011-05-28 10:29:53 +0200 |
commit | defcd409a38e0c9c624424a47becb45cb792ce76 (patch) | |
tree | 94832174e255eb46ba93e9a36bf09a289e707bbf /source3/libsmb | |
parent | 51b43a4c3e87031c8be8405ac6e5182db21320ba (diff) | |
download | samba-defcd409a38e0c9c624424a47becb45cb792ce76.tar.gz samba-defcd409a38e0c9c624424a47becb45cb792ce76.tar.bz2 samba-defcd409a38e0c9c624424a47becb45cb792ce76.zip |
s3: Add cli_connect_nb
This builds up a cli_state until after the netbios session setup. It makes use
of smbsock_connect, so it connects to 139 and 445 simultaneously. This improves
the connection to Windows 2008 which does not listen on *SMBSERVER anymore.
Diffstat (limited to 'source3/libsmb')
-rw-r--r-- | source3/libsmb/cliconnect.c | 133 | ||||
-rw-r--r-- | source3/libsmb/proto.h | 3 |
2 files changed, 136 insertions, 0 deletions
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index a4a3c11559..3f1be7bf18 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -3079,6 +3079,139 @@ NTSTATUS cli_connect(struct cli_state *cli, return NT_STATUS_OK; } +static NTSTATUS cli_connect_sock(const char *host, int name_type, + const struct sockaddr_storage *pss, + const char *myname, uint16_t port, + int sec_timeout, int *pfd, uint16_t *pport) +{ + TALLOC_CTX *frame = talloc_stackframe(); + const char *prog; + unsigned int i, num_addrs; + const char **called_names; + const char **calling_names; + int *called_types; + NTSTATUS status; + int fd; + + prog = getenv("LIBSMB_PROG"); + if (prog != NULL) { + fd = sock_exec(prog); + if (fd == -1) { + return map_nt_error_from_unix(errno); + } + port = 0; + goto done; + } + + if ((pss == NULL) || is_zero_addr(pss)) { + struct sockaddr_storage *addrs; + status = resolve_name_list(talloc_tos(), host, name_type, + &addrs, &num_addrs); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + pss = addrs; + } else { + num_addrs = 1; + } + + called_names = talloc_array(talloc_tos(), const char *, num_addrs); + if (called_names == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + called_types = talloc_array(talloc_tos(), int, num_addrs); + if (called_types == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + calling_names = talloc_array(talloc_tos(), const char *, num_addrs); + if (calling_names == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + for (i=0; i<num_addrs; i++) { + called_names[i] = host; + called_types[i] = name_type; + calling_names[i] = myname; + } + status = smbsock_any_connect(pss, called_names, called_types, + calling_names, NULL, num_addrs, port, + sec_timeout, &fd, NULL, &port); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } +done: + *pfd = fd; + *pport = port; + status = NT_STATUS_OK; +fail: + TALLOC_FREE(frame); + return status; +} + +NTSTATUS cli_connect_nb(const char *host, struct sockaddr_storage *pss, + uint16_t port, const char *myname, + int signing_state, struct cli_state **pcli) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct cli_state *cli; + NTSTATUS status = NT_STATUS_NO_MEMORY; + int name_type = 0x20; + int fd = -1; + char *desthost; + char *p; + socklen_t length; + int ret; + + desthost = talloc_strdup(talloc_tos(), host); + if (desthost == NULL) { + goto fail; + } + + p = strchr(host, '#'); + if (p != NULL) { + name_type = strtol(p+1, NULL, 16); + host = talloc_strndup(talloc_tos(), host, p - host); + if (host == NULL) { + goto fail; + } + } + + cli = cli_initialise_ex(signing_state); + if (cli == NULL) { + goto fail; + } + cli->desthost = talloc_move(cli, &desthost); + + status = cli_connect_sock(host, name_type, pss, myname, port, 20, &fd, + &port); + if (!NT_STATUS_IS_OK(status)) { + cli_shutdown(cli); + goto fail; + } + cli->fd = fd; + cli->port = port; + + length = sizeof(cli->dest_ss); + ret = getpeername(fd, (struct sockaddr *)&cli->dest_ss, &length); + if (ret == -1) { + status = map_nt_error_from_unix(errno); + cli_shutdown(cli); + goto fail; + } + + if (pss != NULL) { + *pss = cli->dest_ss; + } + + *pcli = cli; + status = NT_STATUS_OK; +fail: + TALLOC_FREE(frame); + return status; +} + /** establishes a connection to after the negprot. @param output_cli A fully initialised cli structure, non-null only on success diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index 213b81129e..3a34486c04 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -73,6 +73,9 @@ bool cli_session_request(struct cli_state *cli, NTSTATUS cli_connect(struct cli_state *cli, const char *host, struct sockaddr_storage *dest_ss); +NTSTATUS cli_connect_nb(const char *host, struct sockaddr_storage *pss, + uint16_t port, const char *myname, + int signing_state, struct cli_state **pcli); NTSTATUS cli_start_connection(struct cli_state **output_cli, const char *my_name, const char *dest_host, |