void cli_shutdown(struct cli_state *cli) { cli_nt_pipes_close(cli); /* * tell our peer to free his resources. Wihtout this, when an * application attempts to do a graceful shutdown and calls * smbc_free_context() to clean up all connections, some connections * can remain active on the peer end, until some (long) timeout period * later. This tree disconnect forces the peer to clean up, since the * connection will be going away. * * Also, do not do tree disconnect when cli->smb_rw_error is SMB_DO_NOT_DO_TDIS * the only user for this so far is smbmount which passes opened connection * down to kernel's smbfs module. */ if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != SMB_DO_NOT_DO_TDIS ) ) { cli_tdis(cli); } SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); cli_free_signing_context(cli); data_blob_free(&cli->secblob); data_blob_free(&cli->user_session_key); if (cli->fd != -1) { close(cli->fd); } cli->fd = -1; cli->smb_rw_error = SMB_READ_OK; TALLOC_FREE(cli); }
BOOL cli_check_msdfs_proxy( struct cli_state *cli, const char *sharename, fstring newserver, fstring newshare ) { CLIENT_DFS_REFERRAL *refs = NULL; size_t num_refs; uint16 consumed; pstring fullpath; BOOL res; uint16 cnum; pstring newextrapath; if ( !cli || !sharename ) return False; cnum = cli->cnum; /* special case. never check for a referral on the IPC$ share */ if ( strequal( sharename, "IPC$" ) ) { return False; } /* send a trans2_query_path_info to check for a referral */ pstr_sprintf( fullpath, "\\%s\\%s", cli->desthost, sharename ); /* check for the referral */ if (!cli_send_tconX(cli, "IPC$", "IPC", NULL, 0)) { return False; } res = cli_dfs_get_referral(cli, fullpath, &refs, &num_refs, &consumed); if (!cli_tdis(cli)) { SAFE_FREE( refs ); return False; } cli->cnum = cnum; if (!res || !num_refs ) { SAFE_FREE( refs ); return False; } split_dfs_path( refs[0].dfspath, newserver, newshare, newextrapath ); /* check that this is not a self-referral */ if ( strequal( cli->desthost, newserver ) && strequal( sharename, newshare ) ) { SAFE_FREE( refs ); return False; } SAFE_FREE( refs ); return True; }
static void _cli_shutdown(struct cli_state *cli) { cli_nt_pipes_close(cli); /* * tell our peer to free his resources. Wihtout this, when an * application attempts to do a graceful shutdown and calls * smbc_free_context() to clean up all connections, some connections * can remain active on the peer end, until some (long) timeout period * later. This tree disconnect forces the peer to clean up, since the * connection will be going away. */ if (cli_state_has_tcon(cli)) { cli_tdis(cli); } smbXcli_conn_disconnect(cli->conn, NT_STATUS_OK); TALLOC_FREE(cli); }
bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, struct cli_state *cli, const char *sharename, char **pp_newserver, char **pp_newshare, bool force_encrypt, const char *username, const char *password, const char *domain) { struct client_dfs_referral *refs = NULL; size_t num_refs = 0; size_t consumed = 0; char *fullpath = NULL; bool res; uint16 cnum; char *newextrapath = NULL; NTSTATUS status; const char *remote_name; if (!cli || !sharename) { return false; } remote_name = cli_state_remote_name(cli); cnum = cli_state_get_tid(cli); /* special case. never check for a referral on the IPC$ share */ if (strequal(sharename, "IPC$")) { return false; } /* send a trans2_query_path_info to check for a referral */ fullpath = talloc_asprintf(ctx, "\\%s\\%s", remote_name, sharename); if (!fullpath) { return false; } /* check for the referral */ if (!NT_STATUS_IS_OK(cli_tree_connect(cli, "IPC$", "IPC", NULL, 0))) { return false; } if (force_encrypt) { status = cli_cm_force_encryption(cli, username, password, lp_workgroup(), "IPC$"); if (!NT_STATUS_IS_OK(status)) { return false; } } status = cli_dfs_get_referral(ctx, cli, fullpath, &refs, &num_refs, &consumed); res = NT_STATUS_IS_OK(status); status = cli_tdis(cli); if (!NT_STATUS_IS_OK(status)) { return false; } cli_state_set_tid(cli, cnum); if (!res || !num_refs) { return false; } if (!refs[0].dfspath) { return false; } if (!split_dfs_path(ctx, refs[0].dfspath, pp_newserver, pp_newshare, &newextrapath)) { return false; } /* check that this is not a self-referral */ if (strequal(remote_name, *pp_newserver) && strequal(sharename, *pp_newshare)) { return false; } return true; }
void cli_shutdown(struct cli_state *cli) { if (cli == NULL) { return; } 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); /* * tell our peer to free his resources. Wihtout this, when an * application attempts to do a graceful shutdown and calls * smbc_free_context() to clean up all connections, some connections * can remain active on the peer end, until some (long) timeout period * later. This tree disconnect forces the peer to clean up, since the * connection will be going away. * * Also, do not do tree disconnect when cli->smb_rw_error is SMB_DO_NOT_DO_TDIS * the only user for this so far is smbmount which passes opened connection * down to kernel's smbfs module. */ if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != SMB_DO_NOT_DO_TDIS ) ) { cli_tdis(cli); } SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); data_blob_free(&cli->secblob); data_blob_free(&cli->user_session_key); if (cli->fd != -1) { close(cli->fd); } cli->fd = -1; cli->smb_rw_error = SMB_READ_OK; /* * Need to free pending first, they remove themselves */ while (cli->pending) { talloc_free(cli->pending[0]); } TALLOC_FREE(cli); }