diff options
Diffstat (limited to 'source3/libsmb/clientgen.c')
-rw-r--r-- | source3/libsmb/clientgen.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d117885b8f7..e86f52dac0d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -348,11 +348,37 @@ uint32_t cli_state_set_tid(struct cli_state *cli, uint32_t tid) struct smbXcli_tcon *cli_state_save_tcon(struct cli_state *cli) { + /* + * Note. This used to make a deep copy of either + * cli->smb2.tcon or cli->smb1.tcon, but this leaves + * the original pointer in place which will then get + * TALLOC_FREE()'d when the new connection is made on + * this cli_state. + * + * As there may be pipes open on the old connection with + * talloc'ed state allocated using the tcon pointer as a + * parent we can't deep copy and then free this as that + * closes the open pipes. + * + * This call is used to temporarily swap out a tcon pointer + * to allow a new tcon on the same cli_state. + * + * Just return the raw pointer and set the old value to NULL. + * We know we MUST be calling cli_state_restore_tcon() below + * to restore before closing the session. + * + * See BUG: https://bugzilla.samba.org/show_bug.cgi?id=13992 + */ + struct smbXcli_tcon *tcon_ret = NULL; + if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { - return smbXcli_tcon_copy(cli, cli->smb2.tcon); + tcon_ret = cli->smb2.tcon; + cli->smb2.tcon = NULL; /* *Not* TALLOC_FREE(). */ } else { - return smbXcli_tcon_copy(cli, cli->smb1.tcon); + tcon_ret = cli->smb1.tcon; + cli->smb1.tcon = NULL; /* *Not* TALLOC_FREE(). */ } + return tcon_ret; } void cli_state_restore_tcon(struct cli_state *cli, struct smbXcli_tcon *tcon) |