summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/async_smb.c2
-rw-r--r--source3/libsmb/cliconnect.c97
-rw-r--r--source3/libsmb/clidfs.c20
-rw-r--r--source3/libsmb/clireadwrite.c10
-rw-r--r--source3/libsmb/smb_share_modes.c43
5 files changed, 118 insertions, 54 deletions
diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c
index 82a919455a..a1fcf8eb07 100644
--- a/source3/libsmb/async_smb.c
+++ b/source3/libsmb/async_smb.c
@@ -435,7 +435,7 @@ static struct async_req *cli_request_chain(TALLOC_CTX *mem_ctx,
req->async = tmp_reqs;
req->num_async += 1;
- req->async[req->num_async-1] = async_req_new(mem_ctx, ev);
+ req->async[req->num_async-1] = async_req_new(mem_ctx);
if (req->async[req->num_async-1] == NULL) {
DEBUG(0, ("async_req_new failed\n"));
req->num_async -= 1;
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 5892bdc859..6ddc249c04 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -1494,17 +1494,17 @@ bool cli_session_request(struct cli_state *cli,
*/
uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
struct in_addr dest_ip;
+ NTSTATUS status;
/* SESSION RETARGET */
putip((char *)&dest_ip,cli->inbuf+4);
in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
- cli->fd = open_socket_out(SOCK_STREAM,
- &cli->dest_ss,
- port,
- LONG_CONNECT_TIMEOUT);
- if (cli->fd == -1)
+ status = open_socket_out(&cli->dest_ss, port,
+ LONG_CONNECT_TIMEOUT, &cli->fd);
+ if (!NT_STATUS_IS_OK(status)) {
return False;
+ }
DEBUG(3,("Retargeted\n"));
@@ -1533,6 +1533,78 @@ bool cli_session_request(struct cli_state *cli,
return(True);
}
+static void smb_sock_connected(struct async_req *req)
+{
+ int *pfd = (int *)req->async.priv;
+ int fd;
+ NTSTATUS status;
+
+ status = open_socket_out_defer_recv(req, &fd);
+ if (NT_STATUS_IS_OK(status)) {
+ *pfd = fd;
+ }
+}
+
+static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
+ uint16_t *port, int timeout, int *pfd)
+{
+ struct event_context *ev;
+ struct async_req *r139, *r445;
+ int fd139 = -1;
+ int fd445 = -1;
+ NTSTATUS status;
+
+ if (*port != 0) {
+ return open_socket_out(pss, *port, timeout, pfd);
+ }
+
+ ev = event_context_init(talloc_tos());
+ if (ev == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
+ pss, 445, timeout);
+ r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
+ pss, 139, timeout);
+ if ((r445 == NULL) || (r139 == NULL)) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ r445->async.fn = smb_sock_connected;
+ r445->async.priv = &fd445;
+ r139->async.fn = smb_sock_connected;
+ r139->async.priv = &fd139;
+
+ while ((fd139 == -1) && (r139->state < ASYNC_REQ_DONE)
+ && (fd445 == -1) && (r445->state < ASYNC_REQ_DONE)) {
+ event_loop_once(ev);
+ }
+
+ if ((fd139 != -1) && (fd445 != -1)) {
+ close(fd139);
+ fd139 = -1;
+ }
+
+ if (fd445 != -1) {
+ *port = 445;
+ *pfd = fd445;
+ status = NT_STATUS_OK;
+ goto done;
+ }
+ if (fd139 != -1) {
+ *port = 139;
+ *pfd = fd139;
+ status = NT_STATUS_OK;
+ goto done;
+ }
+
+ status = open_socket_out_defer_recv(r445, &fd445);
+ done:
+ TALLOC_FREE(ev);
+ return status;
+}
+
/****************************************************************************
Open the client sockets.
****************************************************************************/
@@ -1587,16 +1659,11 @@ NTSTATUS cli_connect(struct cli_state *cli,
if (getenv("LIBSMB_PROG")) {
cli->fd = sock_exec(getenv("LIBSMB_PROG"));
} else {
- /* try 445 first, then 139 */
- uint16_t port = cli->port?cli->port:445;
- cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
- port, cli->timeout);
- if (cli->fd == -1 && cli->port == 0) {
- port = 139;
- cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
- port, cli->timeout);
- }
- if (cli->fd != -1) {
+ uint16_t port = cli->port;
+ NTSTATUS status;
+ status = open_smb_socket(&cli->dest_ss, &port,
+ cli->timeout, &cli->fd);
+ if (NT_STATUS_IS_OK(status)) {
cli->port = port;
}
}
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 4597e63c98..ac68700fd0 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -54,8 +54,6 @@ static void cm_set_password(const char *newpass);
static int port;
static int name_type = 0x20;
-static bool have_ip;
-static struct sockaddr_storage dest_ss;
static struct client_connection *connections;
@@ -133,8 +131,11 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
}
sharename = servicename;
if (*sharename == '\\') {
- server = sharename+2;
- sharename = strchr_m(server,'\\');
+ sharename += 2;
+ if (server == NULL) {
+ server = sharename;
+ }
+ sharename = strchr_m(sharename,'\\');
if (!sharename) {
return NULL;
}
@@ -151,8 +152,6 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
again:
zero_sockaddr(&ss);
- if (have_ip)
- ss = dest_ss;
/* have to open a new connection */
if (!(c=cli_initialise()) || (cli_set_port(c, port) != port)) {
@@ -550,15 +549,6 @@ void cli_cm_set_fallback_after_kerberos(void)
cm_creds.fallback_after_kerberos = true;
}
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_set_dest_ss(struct sockaddr_storage *pss)
-{
- dest_ss = *pss;
- have_ip = true;
-}
-
/**********************************************************************
split a dfs path into the server, share name, and extrapath components
**********************************************************************/
diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c
index b33d0f0938..1d5582e61d 100644
--- a/source3/libsmb/clireadwrite.c
+++ b/source3/libsmb/clireadwrite.c
@@ -278,7 +278,7 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx,
struct cli_pull_state *state;
int i;
- result = async_req_new(mem_ctx, ev);
+ result = async_req_new(mem_ctx);
if (result == NULL) {
goto failed;
}
@@ -302,7 +302,7 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx,
state->top_req = 0;
if (size == 0) {
- if (!async_post_status(result, NT_STATUS_OK)) {
+ if (!async_post_status(result, ev, NT_STATUS_OK)) {
goto failed;
}
return result;
@@ -843,7 +843,7 @@ static struct async_req *cli_writeall_send(TALLOC_CTX *mem_ctx,
struct async_req *subreq;
struct cli_writeall_state *state;
- result = async_req_new(mem_ctx, ev);
+ result = async_req_new(mem_ctx);
if (result == NULL) {
goto fail;
}
@@ -969,7 +969,7 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
struct cli_push_state *state;
int i;
- result = async_req_new(mem_ctx, ev);
+ result = async_req_new(mem_ctx);
if (result == NULL) {
goto failed;
}
@@ -1034,7 +1034,7 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
}
if (i == 0) {
- if (!async_post_status(result, NT_STATUS_OK)) {
+ if (!async_post_status(result, ev, NT_STATUS_OK)) {
goto failed;
}
return result;
diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c
index 16b3b10925..af3f7b0dd5 100644
--- a/source3/libsmb/smb_share_modes.c
+++ b/source3/libsmb/smb_share_modes.c
@@ -1,7 +1,7 @@
/*
Samba share mode database library external interface library.
Used by non-Samba products needing access to the Samba share mode db.
-
+
Copyright (C) Jeremy Allison 2005 - 2006
sharemodes_procid functions (C) Copyright (C) Volker Lendecke 2005
@@ -9,17 +9,17 @@
** NOTE! The following LGPL license applies to this module only.
** This does NOT imply that all of Samba is released
** under the LGPL
-
+
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
-
+
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
@@ -92,16 +92,16 @@ int smb_share_mode_db_close(struct smbdb_ctx *db_ctx)
return ret;
}
-static TDB_DATA get_locking_key(uint64_t dev, uint64_t ino)
+static TDB_DATA get_locking_key(struct locking_key *lk, uint64_t dev,
+ uint64_t ino)
{
- static struct locking_key lk;
TDB_DATA ld;
- memset(&lk, '\0', sizeof(struct locking_key));
- lk.dev = (SMB_DEV_T)dev;
- lk.inode = (SMB_INO_T)ino;
- ld.dptr = (uint8 *)&lk;
- ld.dsize = sizeof(lk);
+ memset(lk, '\0', sizeof(*lk));
+ lk->dev = (SMB_DEV_T)dev;
+ lk->inode = (SMB_INO_T)ino;
+ ld.dptr = (uint8 *)lk;
+ ld.dsize = sizeof(*lk);
return ld;
}
@@ -113,14 +113,17 @@ int smb_lock_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino)
{
- return tdb_chainlock(db_ctx->smb_tdb, get_locking_key(dev, ino));
+ struct locking_key lk;
+ return tdb_chainlock(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino));
}
-
+
int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino)
{
- return tdb_chainunlock(db_ctx->smb_tdb, get_locking_key(dev, ino));
+ struct locking_key lk;
+ return tdb_chainunlock(db_ctx->smb_tdb,
+ get_locking_key(&lk, dev, ino));
}
/*
@@ -172,6 +175,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
struct smb_share_mode_entry **pp_list,
unsigned char *p_delete_on_close)
{
+ struct locking_key lk;
TDB_DATA db_data;
struct smb_share_mode_entry *list = NULL;
int num_share_modes = 0;
@@ -183,7 +187,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
*pp_list = NULL;
*p_delete_on_close = 0;
- db_data = tdb_fetch(db_ctx->smb_tdb, get_locking_key(dev, ino));
+ db_data = tdb_fetch(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino));
if (!db_data.dptr) {
return 0;
}
@@ -258,7 +262,8 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
const char *filename) /* Must be relative utf8 path. */
{
TDB_DATA db_data;
- TDB_DATA locking_key = get_locking_key(dev, ino);
+ struct locking_key lk;
+ TDB_DATA locking_key = get_locking_key(&lk, dev, ino);
int orig_num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
struct share_mode_entry *shares = NULL;
@@ -371,7 +376,8 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
const struct smb_share_mode_entry *del_entry)
{
TDB_DATA db_data;
- TDB_DATA locking_key = get_locking_key(dev, ino);
+ struct locking_key lk;
+ TDB_DATA locking_key = get_locking_key(&lk, dev, ino);
int orig_num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
struct share_mode_entry *shares = NULL;
@@ -473,7 +479,8 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx,
const struct smb_share_mode_entry *new_entry)
{
TDB_DATA db_data;
- TDB_DATA locking_key = get_locking_key(dev, ino);
+ struct locking_key lk;
+ TDB_DATA locking_key = get_locking_key(&lk, dev, ino);
int num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
struct share_mode_entry *shares = NULL;