summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/clidfs.c162
-rw-r--r--source3/libsmb/clientgen.c28
-rw-r--r--source3/libsmb/clilist.c5
3 files changed, 82 insertions, 113 deletions
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 1153d8dc89..8544d5520e 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -3,7 +3,7 @@
client connect/disconnect routines
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Gerald (Jerry) Carter 2004
- Copyright (C) Jeremy Allison 2007
+ Copyright (C) Jeremy Allison 2007-2009
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -32,12 +32,6 @@
as a separator when looking at the pathname part.... JRA.
********************************************************************/
-struct client_connection {
- struct client_connection *prev, *next;
- struct cli_state *cli;
- char *mount;
-};
-
static struct cm_cred_struct {
char *username;
char *password;
@@ -49,8 +43,6 @@ static struct cm_cred_struct {
static void cm_set_password(const char *newpass);
-static struct client_connection *connections;
-
static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
struct cli_state *cli,
const char *sharename,
@@ -96,7 +88,7 @@ NTSTATUS cli_cm_force_encryption(struct cli_state *c,
return status;
}
-
+
/********************************************************************
Return a connection to a server.
********************************************************************/
@@ -301,52 +293,20 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
/****************************************************************************
****************************************************************************/
-static void cli_cm_set_mntpoint(struct cli_state *c, const char *mnt)
-{
- struct client_connection *p;
- int i;
-
- for (p=connections,i=0; p; p=p->next,i++) {
- if (strequal(p->cli->desthost, c->desthost) &&
- strequal(p->cli->share, c->share)) {
- break;
- }
- }
-
- if (p) {
- char *name = clean_name(NULL, mnt);
- if (!name) {
- return;
- }
- TALLOC_FREE(p->mount);
- p->mount = talloc_strdup(p, name);
- TALLOC_FREE(name);
- }
-}
-
-/****************************************************************************
-****************************************************************************/
-
-const char *cli_cm_get_mntpoint(struct cli_state *c)
+static void cli_set_mntpoint(struct cli_state *cli, const char *mnt)
{
- struct client_connection *p;
- int i;
-
- for (p=connections,i=0; p; p=p->next,i++) {
- if (strequal(p->cli->desthost, c->desthost) &&
- strequal(p->cli->share, c->share)) {
- break;
- }
- }
-
- if (p) {
- return p->mount;
+ char *name = clean_name(NULL, mnt);
+ if (!name) {
+ return;
}
- return NULL;
+ TALLOC_FREE(cli->dfs_mountpoint);
+ cli->dfs_mountpoint = talloc_strdup(cli, name);
+ TALLOC_FREE(name);
}
/********************************************************************
- Add a new connection to the list
+ Add a new connection to the list.
+ referring_cli == NULL means a new initial connection.
********************************************************************/
static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
@@ -359,53 +319,62 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
int port,
int name_type)
{
- struct client_connection *node;
-
- /* NB This must be the null context here... JRA. */
- node = TALLOC_ZERO_ARRAY(NULL, struct client_connection, 1);
- if (!node) {
- return NULL;
- }
+ struct cli_state *cli;
- node->cli = do_connect(ctx, server, share,
+ cli = do_connect(ctx, server, share,
show_hdr, force_encrypt, max_protocol,
port, name_type);
- if ( !node->cli ) {
- TALLOC_FREE( node );
+ if (!cli ) {
return NULL;
}
- DLIST_ADD( connections, node );
-
- cli_cm_set_mntpoint(node->cli, "");
+ /* Enter into the list. */
+ if (referring_cli) {
+ DLIST_ADD_END(referring_cli, cli, struct cli_state *);
+ }
if (referring_cli && referring_cli->posix_capabilities) {
uint16 major, minor;
uint32 caplow, caphigh;
- if (cli_unix_extensions_version(node->cli, &major,
+ if (cli_unix_extensions_version(cli, &major,
&minor, &caplow, &caphigh)) {
- cli_set_unix_extensions_capabilities(node->cli,
+ cli_set_unix_extensions_capabilities(cli,
major, minor,
caplow, caphigh);
}
}
- return node->cli;
+ return cli;
}
/********************************************************************
- Return a connection to a server.
+ Return a connection to a server on a particular share.
********************************************************************/
-static struct cli_state *cli_cm_find(const char *server, const char *share)
+static struct cli_state *cli_cm_find(struct cli_state *cli,
+ const char *server,
+ const char *share)
{
- struct client_connection *p;
+ struct cli_state *p;
- for (p=connections; p; p=p->next) {
- if ( strequal(server, p->cli->desthost) &&
- strequal(share,p->cli->share)) {
- return p->cli;
+ if (cli == NULL) {
+ return NULL;
+ }
+
+ /* Search to the start of the list. */
+ for (p = cli; p; p = p->prev) {
+ if (strequal(server, p->desthost) &&
+ strequal(share,p->share)) {
+ return p;
+ }
+ }
+
+ /* Search to the end of the list. */
+ for (p = cli->next; p; p = p->next) {
+ if (strequal(server, p->desthost) &&
+ strequal(share,p->share)) {
+ return p;
}
}
@@ -413,8 +382,7 @@ static struct cli_state *cli_cm_find(const char *server, const char *share)
}
/****************************************************************************
- Open a client connection to a \\server\share. Set's the current *cli
- global variable as a side-effect (but only if the connection is successful).
+ Open a client connection to a \\server\share.
****************************************************************************/
struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
@@ -427,50 +395,28 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
int port,
int name_type)
{
- struct cli_state *c;
+ /* Try to reuse an existing connection in this list. */
+ struct cli_state *c = cli_cm_find(referring_cli, server, share);
- /* try to reuse an existing connection */
+ if (c) {
+ return c;
+ }
- c = cli_cm_find(server, share);
- if (!c) {
- c = cli_cm_connect(ctx, referring_cli,
+ return cli_cm_connect(ctx, referring_cli,
server, share, show_hdr, force_encrypt,
max_protocol, port, name_type);
- }
-
- return c;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_shutdown(void)
-{
- struct client_connection *p, *x;
-
- for (p=connections; p;) {
- cli_shutdown(p->cli);
- x = p;
- p = p->next;
-
- TALLOC_FREE(x);
- }
-
- connections = NULL;
- return;
}
/****************************************************************************
****************************************************************************/
-void cli_cm_display(void)
+void cli_cm_display(const struct cli_state *cli)
{
- struct client_connection *p;
int i;
- for ( p=connections,i=0; p; p=p->next,i++ ) {
+ for (i=0; cli; cli = cli->next,i++ ) {
d_printf("%d:\tserver=%s, share=%s\n",
- i, p->cli->desthost, p->cli->share );
+ i, cli->desthost, cli->share );
}
}
@@ -998,7 +944,7 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
return false;
}
- cli_cm_set_mntpoint(*targetcli, newmount);
+ cli_set_mntpoint(*targetcli, newmount);
/* Check for another dfs referral, note that we are not
checking for loops here. */
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 2983f7771a..7c42da4430 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -425,7 +425,7 @@ void cli_init_creds(struct cli_state *cli, const char *username, const char *dom
}
/****************************************************************************
- Initialise a client structure. Always returns a malloc'ed struct.
+ Initialise a client structure. Always returns a talloc'ed struct.
Set the signing state (used from the command line).
****************************************************************************/
@@ -446,6 +446,11 @@ struct cli_state *cli_initialise_ex(int signing_state)
return NULL;
}
+ cli->dfs_mountpoint = talloc_strdup(cli, "");
+ if (!cli->dfs_mountpoint) {
+ TALLOC_FREE(cli);
+ return NULL;
+ }
cli->port = 0;
cli->fd = -1;
cli->cnum = -1;
@@ -550,6 +555,27 @@ void cli_nt_pipes_close(struct cli_state *cli)
void cli_shutdown(struct cli_state *cli)
{
+ if (cli->prev == NULL) {
+ /*
+ * Possible head of a DFS list,
+ * shutdown all subsidiary DFS
+ * connections.
+ */
+ struct cli_state *p, *next;
+
+ for (p = cli->next; p; p = next) {
+ next = p->next;
+ cli_shutdown(p);
+ }
+ } else {
+ /*
+ * We're a subsidiary connection.
+ * Just remove ourselves from the
+ * DFS list.
+ */
+ DLIST_REMOVE(cli->prev, cli);
+ }
+
cli_nt_pipes_close(cli);
/*
diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c
index e604725493..a84a64794b 100644
--- a/source3/libsmb/clilist.c
+++ b/source3/libsmb/clilist.c
@@ -244,7 +244,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
unsigned int param_len, data_len;
uint16 setup;
char *param;
- const char *mnt;
uint32 resume_key = 0;
TALLOC_CTX *frame = talloc_stackframe();
DATA_BLOB last_name_raw = data_blob(NULL, 0);
@@ -457,8 +456,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
First = False;
}
- mnt = cli_cm_get_mntpoint( cli );
-
/* see if the server disconnected or the connection otherwise failed */
if (cli_is_error(cli)) {
total_received = -1;
@@ -479,7 +476,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
info_level));
break;
}
- fn(mnt,&finfo, Mask, state);
+ fn(cli->dfs_mountpoint, &finfo, Mask, state);
}
}