From 7c388656cbe57b8abd52325cc01137dd9dbc06cf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Jun 2017 16:00:30 +0200 Subject: [PATCH] TODO: s3:libsmb: add cli_state_dup() This can be used to create a 2nd cli_state for a different tcon on the same connection/session. Signed-off-by: Stefan Metzmacher --- source3/include/client.h | 1 + source3/libsmb/clientgen.c | 71 ++++++++++++++++++++++++++++++++++++-- source3/libsmb/proto.h | 2 ++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/source3/include/client.h b/source3/include/client.h index 23ba86d2a2c4..dcc33e01d009 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -86,6 +86,7 @@ struct cli_state { /* Where (if anywhere) this is mounted under DFS. */ char *dfs_mountpoint; + struct cli_state *primary_state; struct smbXcli_conn *conn; struct { diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2e4dd15ab628..b2eccfe9f55a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -235,6 +235,68 @@ struct cli_state *cli_state_create(TALLOC_CTX *mem_ctx, return NULL; } +struct cli_state *cli_state_dup(TALLOC_CTX *mem_ctx, + struct cli_state *primary) +{ + struct cli_state *cli = NULL; + + cli = talloc_zero(mem_ctx, struct cli_state); + if (!cli) { + return NULL; + } + + cli->raw_status = NT_STATUS_INTERNAL_ERROR; + cli->map_dos_errors = true; /* remove this */ + cli->timeout = CLIENT_TIMEOUT; + + cli->server_domain = talloc_strdup(cli, primary->server_domain); + if (!cli->server_domain) { + goto error; + } + cli->server_os = talloc_strdup(cli, primary->server_os); + if (!cli->server_os) { + goto error; + } + cli->server_type = talloc_strdup(cli, primary->server_type); + if (!cli->server_type) { + goto error; + } + + cli->dfs_mountpoint = talloc_strdup(cli, primary->dfs_mountpoint); + if (!cli->dfs_mountpoint) { + goto error; + } + + cli->use_kerberos = primary->use_kerberos; + cli->fallback_after_kerberos = primary->fallback_after_kerberos; + cli->use_ccache = primary->use_ccache; + cli->pw_nt_hash = primary->pw_nt_hash; + cli->use_oplocks = primary->use_oplocks; + + /* + * We reference the connection and session details from the primary + * connection. + */ + cli->primary_state = primary; + cli->conn = primary->conn; + cli->smb1.pid = primary->smb1.pid; + cli->smb1.vc_num = primary->smb1.vc_num; + cli->smb1.session = primary->smb1.session; + cli->smb2.session = primary->smb2.session; + + cli->initialised = 1; + + DLIST_ADD_END(primary, cli); + return cli; + + /* Clean up after malloc() error */ + + error: + + TALLOC_FREE(cli); + return NULL; +} + /**************************************************************************** Close all pipes open on this session. ****************************************************************************/ @@ -269,7 +331,12 @@ static void _cli_shutdown(struct cli_state *cli) cli_tdis(cli); } - smbXcli_conn_disconnect(cli->conn, NT_STATUS_OK); + if (cli->primary_state == NULL) { + /* + * We only disconnect if it's the primary cli_state. + */ + smbXcli_conn_disconnect(cli->conn, NT_STATUS_OK); + } TALLOC_FREE(cli); } @@ -281,7 +348,7 @@ void cli_shutdown(struct cli_state *cli) return; } DLIST_HEAD(cli, cli_head); - if (cli_head == cli) { + if (cli->primary_state == NULL && cli_head == cli) { /* * head of a DFS list, shutdown all subsidiary DFS * connections. diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index b0cfcb5aa90b..2fae76aa6336 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -195,6 +195,8 @@ struct cli_state *cli_state_create(TALLOC_CTX *mem_ctx, const char *remote_name, int signing_state, int flags); +struct cli_state *cli_state_dup(TALLOC_CTX *mem_ctx, + struct cli_state *primary); void cli_nt_pipes_close(struct cli_state *cli); void cli_shutdown(struct cli_state *cli); uint16_t cli_state_get_vc_num(struct cli_state *cli); -- 2.34.1