[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-unstable-970-gf02bf41

Jeremy Allison jra at samba.org
Sun Dec 30 06:52:20 GMT 2007


The branch, v3-2-test has been updated
       via  f02bf419282419950471deae74c4a6fe1543ed26 (commit)
      from  5d424cb3060af89bde50bc7fe2989e3c1b8e91b2 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-test


- Log -----------------------------------------------------------------
commit f02bf419282419950471deae74c4a6fe1543ed26
Author: Jeremy Allison <jra at samba.org>
Date:   Sat Dec 29 22:39:52 2007 -0800

    Added -e, --encrypt option to smbclient that immediately
    forces encrypted smb after initial connect. Will document
    for 3.2 official release.
    Jeremy.

-----------------------------------------------------------------------

Summary of changes:
 source/client/client.c |   45 ++++++++++++++----
 source/libsmb/clidfs.c |  121 +++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 145 insertions(+), 21 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/client/client.c b/source/client/client.c
index 53669bc..3d52998 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -93,6 +93,9 @@ static unsigned int put_total_time_ms = 0;
 /* totals globals */
 static double dir_total;
 
+/* encrypted state. */
+static bool smb_encrypt;
+
 /* root cli_state connection */
 
 struct cli_state *cli;
@@ -2215,6 +2218,7 @@ static int cmd_posix_encrypt(void)
 		d_printf("posix_encrypt failed with error %s\n", nt_errstr(status));
 	} else {
 		d_printf("encryption on\n");
+		smb_encrypt = true;
 	}
 
 	return 0;
@@ -3786,16 +3790,28 @@ int cmd_iosize(void)
 	int iosize;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
-		d_printf("iosize <n> or iosize 0x<n>. "
-			"Minimum is 16384 (0x4000), "
-			"max is 16776960 (0xFFFF00)\n");
+		if (!smb_encrypt) {
+			d_printf("iosize <n> or iosize 0x<n>. "
+				"Minimum is 16384 (0x4000), "
+				"max is 16776960 (0xFFFF00)\n");
+		} else {
+			d_printf("iosize <n> or iosize 0x<n>. "
+				"(Encrypted connection) ,"
+				"Minimum is 16384 (0x4000), "
+				"max is 64512 (0xFC00)\n");
+		}
 		return 1;
 	}
 
 	iosize = strtol(buf,NULL,0);
-	if (iosize < 0 || iosize > 0xFFFF00) {
+	if (smb_encrypt && (iosize < 0x4000 || iosize > 0xFC00)) {
+		d_printf("iosize out of range for encrypted "
+			"connection (min = 16384 (0x4000), "
+			"max = 16776960 (0xFC00)");
+		return 1;
+	} else if (!smb_encrypt && (iosize < 0x4000 || iosize > 0xFFFF00)) {
 		d_printf("iosize out of range (min = 16384 (0x4000), "
-			"max = 16776960 (0x0xFFFF00)");
+			"max = 16776960 (0xFFFF00)");
 		return 1;
 	}
 
@@ -3971,7 +3987,8 @@ static int process_command_string(const char *cmd_in)
 	/* establish the connection if not already */
 
 	if (!cli) {
-		cli = cli_cm_open(talloc_tos(), NULL, desthost, service, true);
+		cli = cli_cm_open(talloc_tos(), NULL, desthost,
+				service, true, smb_encrypt);
 		if (!cli) {
 			return 1;
 		}
@@ -4396,7 +4413,8 @@ static int process(const char *base_directory)
 {
 	int rc = 0;
 
-	cli = cli_cm_open(talloc_tos(), NULL, desthost, service, true);
+	cli = cli_cm_open(talloc_tos(), NULL,
+			desthost, service, true, smb_encrypt);
 	if (!cli) {
 		return 1;
 	}
@@ -4425,7 +4443,8 @@ static int process(const char *base_directory)
 
 static int do_host_query(const char *query_host)
 {
-	cli = cli_cm_open(talloc_tos(), NULL, query_host, "IPC$", true);
+	cli = cli_cm_open(talloc_tos(), NULL,
+			query_host, "IPC$", true, smb_encrypt);
 	if (!cli)
 		return 1;
 
@@ -4438,7 +4457,8 @@ static int do_host_query(const char *query_host)
 
 		cli_cm_shutdown();
 		cli_cm_set_port( 139 );
-		cli = cli_cm_open(talloc_tos(), NULL, query_host, "IPC$", true);
+		cli = cli_cm_open(talloc_tos(), NULL,
+				query_host, "IPC$", true, smb_encrypt);
 	}
 
 	if (cli == NULL) {
@@ -4463,7 +4483,8 @@ static int do_tar_op(const char *base_directory)
 
 	/* do we already have a connection? */
 	if (!cli) {
-		cli = cli_cm_open(talloc_tos(), NULL, desthost, service, true);
+		cli = cli_cm_open(talloc_tos(), NULL,
+			desthost, service, true, smb_encrypt);
 		if (!cli)
 			return 1;
 	}
@@ -4571,6 +4592,7 @@ static int do_message_op(void)
 		{ "port", 'p', POPT_ARG_INT, &port, 'p', "Port to connect to", "PORT" },
 		{ "grepable", 'g', POPT_ARG_NONE, NULL, 'g', "Produce grepable output" },
                 { "browse", 'B', POPT_ARG_NONE, NULL, 'B', "Browse SMB servers using DNS" },
+		{ "encrypt", 'e', POPT_ARG_NONE, NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" },
 		POPT_COMMON_SAMBA
 		POPT_COMMON_CONNECTION
 		POPT_COMMON_CREDENTIALS
@@ -4713,6 +4735,9 @@ static int do_message_op(void)
 		case 'g':
 			grepable=true;
 			break;
+		case 'e':
+			smb_encrypt=true;
+			break;
 		case 'B':
 			return(do_smb_browse());
 
diff --git a/source/libsmb/clidfs.c b/source/libsmb/clidfs.c
index e0c40b5..7800d10 100644
--- a/source/libsmb/clidfs.c
+++ b/source/libsmb/clidfs.c
@@ -58,6 +58,70 @@ 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.
+********************************************************************/
+
+static bool force_cli_encryption(struct cli_state *c,
+			const char *username,
+			const char *password,
+			const char *domain,
+			const char *sharename)
+{
+	uint16 major, minor;
+	uint32 caplow, caphigh;
+	NTSTATUS status;
+
+	if (!SERVER_HAS_UNIX_CIFS(c)) {
+		d_printf("Encryption required and "
+			"server that doesn't support "
+			"UNIX extensions - failing connect\n");
+		return false;
+	}
+
+	if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) {
+		d_printf("Encryption required and "
+			"can't get UNIX CIFS extensions "
+			"version from server.\n");
+		return false;
+	}
+
+	if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
+		d_printf("Encryption required and "
+			"share %s doesn't support "
+			"encryption.\n", sharename);
+		return false;
+	}
+
+	if (c->use_kerberos) {
+		status = cli_gss_smb_encryption_start(c);
+	} else {
+		status = cli_raw_ntlm_smb_encryption_start(c,
+						username,
+						password,
+						domain);
+	}
+
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("Encryption required and "
+			"setup failed with error %s.\n",
+			nt_errstr(status));
+		return false;
+	}
+
+	return true;
+}
+	
 /********************************************************************
  Return a connection to a server.
 ********************************************************************/
@@ -65,7 +129,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 +262,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 +281,15 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
 		return NULL;
 	}
 
+	if (force_encrypt && !force_cli_encryption(c,
+					username,
+					password,
+					lp_workgroup(),
+					sharename)) {
+		cli_shutdown(c);
+		return NULL;
+	}
+
 	DEBUG(4,(" tconx ok\n"));
 	return c;
 }
@@ -269,7 +348,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 +359,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 +411,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 +420,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 +858,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 +902,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 +992,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 +1035,14 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
 		return false;
 	}
 
+	if (force_encrypt && !force_cli_encryption(cli,
+					username,
+					password,
+					lp_workgroup(),
+					"IPC$")) {
+		return false;
+	}
+
 	res = cli_dfs_get_referral(ctx, cli, fullpath, &refs, &num_refs, &consumed);
 
 	if (!cli_tdis(cli)) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list