#include "trans2.h"
#include "libsmb/nmblib.h"
#include "../libcli/smb/smbXcli_base.h"
+#include "auth/credentials/credentials.h"
/********************************************************************
Important point.
static NTSTATUS do_connect(TALLOC_CTX *ctx,
const char *server,
+ const struct sockaddr_storage *dest_ss,
const char *share,
const struct user_auth_info *auth_info,
bool show_sessetup,
char *servicename;
char *sharename;
char *newserver, *newshare;
- const char *username;
- const char *password;
- const char *domain;
NTSTATUS status;
int flags = 0;
+ enum protocol_types protocol = PROTOCOL_NONE;
int signing_state = get_cmdline_auth_info_signing_state(auth_info);
struct cli_credentials *creds = NULL;
}
status = cli_connect_nb(
- server, NULL, port, name_type, NULL,
+ server, dest_ss, port, name_type, NULL,
signing_state,
flags, &c);
if (!NT_STATUS_IS_OK(status)) {
- d_printf("Connection to %s failed (Error %s)\n",
- server,
- nt_errstr(status));
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
+ DBG_ERR("NetBIOS support disabled, unable to connect");
+ }
+
+ DBG_WARNING("Connection to %s failed (Error %s)\n",
+ server,
+ nt_errstr(status));
return status;
}
if (max_protocol == 0) {
- max_protocol = PROTOCOL_NT1;
+ max_protocol = PROTOCOL_LATEST;
}
DEBUG(4,(" session request ok\n"));
cli_shutdown(c);
return status;
}
+ protocol = smbXcli_conn_protocol(c->conn);
+ DEBUG(4,(" negotiated dialect[%s] against server[%s]\n",
+ smb_protocol_types_string(protocol),
+ smbXcli_conn_remote_name(c->conn)));
- if (smbXcli_conn_protocol(c->conn) >= PROTOCOL_SMB2_02) {
+ if (protocol >= PROTOCOL_SMB2_02) {
/* Ensure we ask for some initial credits. */
smb2cli_conn_set_max_credits(c->conn, DEFAULT_SMB2_MAX_CREDITS);
}
- username = get_cmdline_auth_info_username(auth_info);
- password = get_cmdline_auth_info_password(auth_info);
- domain = get_cmdline_auth_info_domain(auth_info);
- if ((domain == NULL) || (domain[0] == '\0')) {
- domain = lp_workgroup();
- }
-
creds = get_cmdline_auth_info_creds(auth_info);
status = cli_session_setup_creds(c, creds);
if (!NT_STATUS_IS_OK(status)) {
/* If a password was not supplied then
* try again with a null username. */
- if (password[0] || !username[0] ||
- get_cmdline_auth_info_use_kerberos(auth_info) ||
+ if (force_encrypt || smbXcli_conn_signing_mandatory(c->conn) ||
+ cli_credentials_authentication_requested(creds) ||
+ cli_credentials_is_anonymous(creds) ||
!NT_STATUS_IS_OK(status = cli_session_setup_anon(c)))
{
d_printf("session setup failed: %s\n",
}
if ( show_sessetup ) {
- if (*c->server_domain) {
- DEBUG(0,("Domain=[%s] OS=[%s] Server=[%s]\n",
- c->server_domain,c->server_os,c->server_type));
- } else if (*c->server_os || *c->server_type) {
- DEBUG(0,("OS=[%s] Server=[%s]\n",
- c->server_os,c->server_type));
- }
+ const char *server_name = NULL;
+ enum protocol_types protocol;
+ const char *protocol_name = NULL;
+
+ server_name = smbXcli_conn_remote_name(c->conn);
+ protocol = smbXcli_conn_protocol(c->conn);
+ protocol_name = smb_protocol_types_string(protocol);
+
+ DEBUG(0,("Server=[%s] Protocol=[%s]\n",
+ server_name, protocol_name));
}
DEBUG(4,(" session setup ok\n"));
if (smbXcli_conn_dfs_supported(c->conn) &&
cli_check_msdfs_proxy(ctx, c, sharename,
&newserver, &newshare,
- force_encrypt,
- username,
- password,
- domain)) {
+ force_encrypt, creds)) {
cli_shutdown(c);
- return do_connect(ctx, newserver,
+ return do_connect(ctx, newserver, NULL,
newshare, auth_info, false,
force_encrypt, max_protocol,
port, name_type, pcli);
static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx,
struct cli_state *referring_cli,
const char *server,
+ const struct sockaddr_storage *dest_ss,
const char *share,
const struct user_auth_info *auth_info,
- bool show_hdr,
bool force_encrypt,
int max_protocol,
int port,
struct cli_state *cli;
NTSTATUS status;
- status = do_connect(ctx, server, share,
+ status = do_connect(ctx, server, dest_ss, share,
auth_info,
show_hdr, force_encrypt, max_protocol,
port, name_type, &cli);
NTSTATUS cli_cm_open(TALLOC_CTX *ctx,
struct cli_state *referring_cli,
const char *server,
+ const struct sockaddr_storage *dest_ss,
const char *share,
const struct user_auth_info *auth_info,
- bool show_hdr,
bool force_encrypt,
int max_protocol,
int port,
status = cli_cm_connect(ctx,
referring_cli,
server,
+ dest_ss,
share,
auth_info,
- show_hdr,
force_encrypt,
max_protocol,
port,
Get the dfs referral link.
********************************************************************/
-NTSTATUS cli_dfs_get_referral(TALLOC_CTX *ctx,
+NTSTATUS cli_dfs_get_referral_ex(TALLOC_CTX *ctx,
struct cli_state *cli,
const char *path,
+ uint16_t max_referral_level,
struct client_dfs_referral **refs,
size_t *num_refs,
size_t *consumed)
status = NT_STATUS_NO_MEMORY;
goto out;
}
- SSVAL(param, 0, 0x03); /* max referral level */
+ SSVAL(param, 0, max_referral_level);
param = trans2_bytes_push_str(param, smbXcli_conn_use_unicode(cli->conn),
path, strlen(path)+1,
return status;
}
+NTSTATUS cli_dfs_get_referral(TALLOC_CTX *ctx,
+ struct cli_state *cli,
+ const char *path,
+ struct client_dfs_referral **refs,
+ size_t *num_refs,
+ size_t *consumed)
+{
+ return cli_dfs_get_referral_ex(ctx,
+ cli,
+ path,
+ 3,
+ refs, /* Max referral level we want */
+ num_refs,
+ consumed);
+}
+
/********************************************************************
********************************************************************/
struct cli_dfs_path_split {
SMB_STRUCT_STAT sbuf;
uint32_t attributes;
NTSTATUS status;
+ struct cli_credentials *dfs_creds = NULL;
+ bool force_encryption = true;
struct smbXcli_tcon *root_tcon = NULL;
struct smbXcli_tcon *target_tcon = NULL;
struct cli_dfs_path_split *dfs_refs = NULL;
if (smbXcli_conn_protocol(rootcli->conn) >= PROTOCOL_SMB2_02) {
root_tcon = rootcli->smb2.tcon;
+ force_encryption = smb2cli_tcon_is_encryption_on(root_tcon);
} else {
root_tcon = rootcli->smb1.tcon;
+ force_encryption = smb1cli_conn_encryption_on(rootcli->conn);
+ }
+
+ /*
+ * Avoid more than one leading directory separator
+ */
+ while (IS_DIRECTORY_SEP(path[0]) && IS_DIRECTORY_SEP(path[1])) {
+ path++;
}
if (!smbXcli_tcon_is_dfs_share(root_tcon)) {
/* Check for the referral. */
- status = cli_cm_open(ctx,
- rootcli,
- smbXcli_conn_remote_name(rootcli->conn),
- "IPC$",
- dfs_auth_info,
- false,
- smb1cli_conn_encryption_on(rootcli->conn),
- smbXcli_conn_protocol(rootcli->conn),
- 0,
- 0x20,
- &cli_ipc);
+ cli_ipc = cli_state_dup(ctx, rootcli);
+ if (cli_ipc == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ dfs_creds = get_cmdline_auth_info_creds(auth_info);
+
+ status = cli_tree_connect_creds(cli_ipc, "IPC$", "IPC", dfs_creds);
if (!NT_STATUS_IS_OK(status)) {
+ d_printf("tree connect failed: %s\n", nt_errstr(status));
+ cli_shutdown(cli_ipc);
return status;
}
+ if (force_encrypt) {
+ status = cli_cm_force_encryption_creds(cli_ipc,
+ dfs_creds,
+ "IPC$");
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_shutdown(cli_ipc);
+ return status;
+ }
+ }
+
status = cli_dfs_get_referral(ctx, cli_ipc, dfs_path, &refs,
&num_refs, &consumed);
if (!NT_STATUS_IS_OK(status)) {
/* Connect to the target server & share */
status = cli_cm_connect(ctx, rootcli,
dfs_refs[count].server,
+ NULL,
dfs_refs[count].share,
dfs_auth_info,
- false,
- smb1cli_conn_encryption_on(rootcli->conn),
+ cli_state_is_encryption_on(rootcli),
smbXcli_conn_protocol(rootcli->conn),
0,
0x20,
char **pp_newserver,
char **pp_newshare,
bool force_encrypt,
- const char *username,
- const char *password,
- const char *domain)
+ struct cli_credentials *creds)
{
struct client_dfs_referral *refs = NULL;
size_t num_refs = 0;
size_t consumed = 0;
char *fullpath = NULL;
bool res;
- uint16_t cnum;
+ struct smbXcli_tcon *orig_tcon = NULL;
char *newextrapath = NULL;
NTSTATUS status;
const char *remote_name;
}
remote_name = smbXcli_conn_remote_name(cli->conn);
- cnum = cli_state_get_tid(cli);
/* special case. never check for a referral on the IPC$ share */
return false;
}
+ /* Store tcon state. */
+ if (cli_state_has_tcon(cli)) {
+ orig_tcon = cli_state_save_tcon(cli);
+ if (orig_tcon == NULL) {
+ return false;
+ }
+ }
+
/* check for the referral */
if (!NT_STATUS_IS_OK(cli_tree_connect(cli, "IPC$", "IPC", NULL))) {
+ cli_state_restore_tcon(cli, orig_tcon);
return false;
}
if (force_encrypt) {
- status = cli_cm_force_encryption(cli,
- username,
- password,
- domain,
- "IPC$");
+ status = cli_cm_force_encryption_creds(cli, creds, "IPC$");
if (!NT_STATUS_IS_OK(status)) {
+ cli_state_restore_tcon(cli, orig_tcon);
return false;
}
}
res = NT_STATUS_IS_OK(status);
status = cli_tdis(cli);
+
+ cli_state_restore_tcon(cli, orig_tcon);
+
if (!NT_STATUS_IS_OK(status)) {
return false;
}
- cli_state_set_tid(cli, cnum);
-
if (!res || !num_refs) {
return false;
}