summaryrefslogtreecommitdiff
path: root/source3/libsmb/clidfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb/clidfs.c')
-rw-r--r--source3/libsmb/clidfs.c109
1 files changed, 98 insertions, 11 deletions
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index e0c40b52ed..77419b4a1a 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -58,6 +58,52 @@ static struct sockaddr_storage dest_ss;
static struct client_connection *connections;
+static 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);
+
+/********************************************************************
+ Ensure a connection is encrypted.
+********************************************************************/
+
+NTSTATUS cli_cm_force_encryption(struct cli_state *c,
+ const char *username,
+ const char *password,
+ const char *domain,
+ const char *sharename)
+{
+ NTSTATUS status = cli_force_encryption(c,
+ username,
+ password,
+ domain);
+
+ if (NT_STATUS_EQUAL(status,NT_STATUS_NOT_SUPPORTED)) {
+ d_printf("Encryption required and "
+ "server that doesn't support "
+ "UNIX extensions - failing connect\n");
+ } else if (NT_STATUS_EQUAL(status,NT_STATUS_UNKNOWN_REVISION)) {
+ d_printf("Encryption required and "
+ "can't get UNIX CIFS extensions "
+ "version from server.\n");
+ } else if (NT_STATUS_EQUAL(status,NT_STATUS_UNSUPPORTED_COMPRESSION)) {
+ d_printf("Encryption required and "
+ "share %s doesn't support "
+ "encryption.\n", sharename);
+ } else if (!NT_STATUS_IS_OK(status)) {
+ d_printf("Encryption required and "
+ "setup failed with error %s.\n",
+ nt_errstr(status));
+ }
+
+ return status;
+}
+
/********************************************************************
Return a connection to a server.
********************************************************************/
@@ -65,7 +111,8 @@ static struct client_connection *connections;
static struct cli_state *do_connect(TALLOC_CTX *ctx,
const char *server,
const char *share,
- bool show_sessetup)
+ bool show_sessetup,
+ bool force_encrypt)
{
struct cli_state *c = NULL;
struct nmb_name called, calling;
@@ -197,9 +244,14 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
if ((c->capabilities & CAP_DFS) &&
cli_check_msdfs_proxy(ctx, c, sharename,
- &newserver, &newshare)) {
+ &newserver, &newshare,
+ force_encrypt,
+ username,
+ password,
+ lp_workgroup())) {
cli_shutdown(c);
- return do_connect(ctx, newserver, newshare, false);
+ return do_connect(ctx, newserver,
+ newshare, false, force_encrypt);
}
/* must be a normal share */
@@ -211,6 +263,18 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
return NULL;
}
+ if (force_encrypt) {
+ status = cli_cm_force_encryption(c,
+ username,
+ password,
+ lp_workgroup(),
+ sharename);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_shutdown(c);
+ return NULL;
+ }
+ }
+
DEBUG(4,(" tconx ok\n"));
return c;
}
@@ -269,7 +333,8 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
struct cli_state *referring_cli,
const char *server,
const char *share,
- bool show_hdr)
+ bool show_hdr,
+ bool force_encrypt)
{
struct client_connection *node;
@@ -279,7 +344,7 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
return NULL;
}
- node->cli = do_connect(ctx, server, share, show_hdr);
+ node->cli = do_connect(ctx, server, share, show_hdr, force_encrypt);
if ( !node->cli ) {
TALLOC_FREE( node );
@@ -331,7 +396,8 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
struct cli_state *referring_cli,
const char *server,
const char *share,
- bool show_hdr)
+ bool show_hdr,
+ bool force_encrypt)
{
struct cli_state *c;
@@ -339,7 +405,8 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
c = cli_cm_find(server, share);
if (!c) {
- c = cli_cm_connect(ctx, referring_cli, server, share, show_hdr);
+ c = cli_cm_connect(ctx, referring_cli,
+ server, share, show_hdr, force_encrypt);
}
return c;
@@ -776,7 +843,9 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
/* Check for the referral. */
if (!(cli_ipc = cli_cm_open(ctx, rootcli,
- rootcli->desthost, "IPC$", false))) {
+ rootcli->desthost,
+ "IPC$", false,
+ (rootcli->trans_enc_state != NULL)))) {
return false;
}
@@ -818,7 +887,10 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
/* Open the connection to the target server & share */
if ((*targetcli = cli_cm_open(ctx, rootcli,
- server, share, false)) == NULL) {
+ server,
+ share,
+ false,
+ (rootcli->trans_enc_state != NULL))) == NULL) {
d_printf("Unable to follow dfs referral [\\%s\\%s]\n",
server, share );
return false;
@@ -905,11 +977,15 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
/********************************************************************
********************************************************************/
-bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
+static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
struct cli_state *cli,
const char *sharename,
char **pp_newserver,
- char **pp_newshare )
+ char **pp_newshare,
+ bool force_encrypt,
+ const char *username,
+ const char *password,
+ const char *domain)
{
CLIENT_DFS_REFERRAL *refs = NULL;
size_t num_refs = 0;
@@ -944,6 +1020,17 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
return false;
}
+ if (force_encrypt) {
+ NTSTATUS status = cli_cm_force_encryption(cli,
+ username,
+ password,
+ lp_workgroup(),
+ "IPC$");
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+ }
+
res = cli_dfs_get_referral(ctx, cli, fullpath, &refs, &num_refs, &consumed);
if (!cli_tdis(cli)) {