Add general '-e' option to enable smb encryption
authorJeremy Allison <jra@samba.org>
Sat, 5 Jan 2008 08:23:35 +0000 (00:23 -0800)
committerJeremy Allison <jra@samba.org>
Sat, 5 Jan 2008 08:23:35 +0000 (00:23 -0800)
on tools.
Jeremy.
(This used to be commit 757653966fc1384159bd2d57c5670cd8af0cae96)

source3/client/smbspool.c
source3/include/popt_common.h
source3/lib/popt_common.c
source3/lib/util.c
source3/libsmb/clidfs.c
source3/libsmb/clifsinfo.c
source3/rpcclient/rpcclient.c
source3/utils/net.c
source3/utils/net_help.c
source3/utils/smbcacls.c

index 4270eb427208774f1bf8cf038711bdb3dc9fa984..e7df22c2bcbe8a364182892934b2c820493b1d56 100644 (file)
@@ -47,7 +47,9 @@ static struct cli_state *smb_complete_connection(const char *, const char *,int
 static struct cli_state        *smb_connect(const char *, const char *, int, const char *, const char *, const char *, const char *);
 static int             smb_print(struct cli_state *, char *, FILE *);
 static char *          uri_unescape_alloc(const char *);
-
+#if 0
+static bool smb_encrypt;
+#endif
 
 /*
  * 'main()' - Main entry for SMB backend.
@@ -468,6 +470,23 @@ static struct cli_state
     return NULL;
   }
     
+#if 0
+  /* Need to work out how to specify this on the URL. */
+  if (smb_encrypt)
+  {
+    if (!cli_cm_force_encryption(cli,
+                       username,
+                       password,
+                       workgroup,
+                       share))
+    {
+      fprintf(stderr, "ERROR: encryption setup failed\n");
+      cli_shutdown(cli);
+      return NULL;
+    }
+  }
+#endif
+
   return cli;
 }
 
index 1d3cc57acde68238e6a27fc1c47eedf5728eaec1..9e5503f2701f09b368edd063c8df09a15d85ff6c 100644 (file)
@@ -49,6 +49,7 @@ struct user_auth_info {
        bool got_pass;
        bool use_kerberos;
        int signing_state;
+       bool smb_encrypt;
 };
 
 #endif /* _POPT_COMMON_H */
index b3a84a6f7cad019ed9c2ae7920d9a1d4a57338db..5a9d39d181a36e57093d8ddf7092c01fe8872205 100644 (file)
@@ -414,6 +414,7 @@ static void get_credentials_file(const char *file)
  *             -N,--no-pass
  *             -S,--signing
  *              -P --machine-pass
+ *             -e --encrypt
  */
 
 
@@ -532,6 +533,10 @@ static void popt_common_credentials_callback(poptContext con,
        case 'N':
                set_cmdline_auth_info_password("");
                break;
+       case 'e':
+               set_cmdline_auth_info_smb_encrypt();
+               break;
+
        }
 }
 
@@ -543,5 +548,6 @@ struct poptOption popt_common_credentials[] = {
        { "authentication-file", 'A', POPT_ARG_STRING, NULL, 'A', "Get the credentials from a file", "FILE" },
        { "signing", 'S', POPT_ARG_STRING, NULL, 'S', "Set the client signing state", "on|off|required" },
        {"machine-pass", 'P', POPT_ARG_NONE, NULL, 'P', "Use stored machine account password" },
+       {"encrypt", 'e', POPT_ARG_NONE, NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" },
        POPT_TABLEEND
 };
index 7f8a297facac6979cf17a947330e914f73f4d518..81b9fc817b3bd096039b8e4c89b402b41a8eac67 100644 (file)
@@ -289,7 +289,8 @@ static struct user_auth_info cmdline_auth_info = {
        NULL,   /* password */
        false,  /* got_pass */
        false,  /* use_kerberos */
-       Undefined /* signing state */
+       Undefined, /* signing state */
+       false   /* smb_encrypt */
 };
 
 const char *get_cmdline_auth_info_username(void)
@@ -362,11 +363,22 @@ void set_cmdline_auth_info_use_krb5_ticket(void)
        cmdline_auth_info.got_pass = true;
 }
 
+/* This should only be used by lib/popt_common.c JRA */
+bool set_cmdline_auth_info_smb_encrypt(void)
+{
+       cmdline_auth_info.smb_encrypt = true;
+}
+
 bool get_cmdline_auth_info_got_pass(void)
 {
        return cmdline_auth_info.got_pass;
 }
 
+bool get_cmdline_auth_info_smb_encrypt(void)
+{
+       return cmdline_auth_info.smb_encrypt;
+}
+
 bool get_cmdline_auth_info_copy(struct user_auth_info *info)
 {
        *info = cmdline_auth_info;
index 7800d10e8be39e39b643316020f4118cd79dcc90..77419b4a1ad7d1b54fbad777964292e8defc30c5 100644 (file)
@@ -72,54 +72,36 @@ static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
  Ensure a connection is encrypted.
 ********************************************************************/
 
-static bool force_cli_encryption(struct cli_state *c,
+NTSTATUS cli_cm_force_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;
+       NTSTATUS status = cli_force_encryption(c,
+                                       username,
+                                       password,
+                                       domain);
 
-       if (!SERVER_HAS_UNIX_CIFS(c)) {
+       if (NT_STATUS_EQUAL(status,NT_STATUS_NOT_SUPPORTED)) {
                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)) {
+       } 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");
-               return false;
-       }
-
-       if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
+       } else if (NT_STATUS_EQUAL(status,NT_STATUS_UNSUPPORTED_COMPRESSION)) {
                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)) {
+       } else 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 status;
 }
        
 /********************************************************************
@@ -281,13 +263,16 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
                return NULL;
        }
 
-       if (force_encrypt && !force_cli_encryption(c,
+       if (force_encrypt) {
+               status = cli_cm_force_encryption(c,
                                        username,
                                        password,
                                        lp_workgroup(),
-                                       sharename)) {
-               cli_shutdown(c);
-               return NULL;
+                                       sharename);
+               if (!NT_STATUS_IS_OK(status)) {
+                       cli_shutdown(c);
+                       return NULL;
+               }
        }
 
        DEBUG(4,(" tconx ok\n"));
@@ -1035,12 +1020,15 @@ static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
                return false;
        }
 
-       if (force_encrypt && !force_cli_encryption(cli,
+       if (force_encrypt) {
+               NTSTATUS status = cli_cm_force_encryption(cli,
                                        username,
                                        password,
                                        lp_workgroup(),
-                                       "IPC$")) {
-               return false;
+                                       "IPC$");
+               if (!NT_STATUS_IS_OK(status)) {
+                       return false;
+               }
        }
 
        res = cli_dfs_get_referral(ctx, cli, fullpath, &refs, &num_refs, &consumed);
index 107613c618537552028c1d4a2036fd77dfe7d06e..fb923378ab46e18e3fa237e0412cf38beba6b668 100644 (file)
@@ -634,3 +634,36 @@ NTSTATUS cli_gss_smb_encryption_start(struct cli_state *cli)
        return NT_STATUS_NOT_SUPPORTED;
 }
 #endif
+
+/********************************************************************
+ Ensure a connection is encrypted.
+********************************************************************/
+
+NTSTATUS cli_force_encryption(struct cli_state *c,
+                       const char *username,
+                       const char *password,
+                       const char *domain)
+{
+       uint16 major, minor;
+       uint32 caplow, caphigh;
+
+       if (!SERVER_HAS_UNIX_CIFS(c)) {
+               return NT_STATUS_NOT_SUPPORTED;
+       }
+
+       if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) {
+               return NT_STATUS_UNKNOWN_REVISION;
+       }
+
+       if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
+               return NT_STATUS_UNSUPPORTED_COMPRESSION;
+       }
+
+       if (c->use_kerberos) {
+               return cli_gss_smb_encryption_start(c);
+       }
+       return cli_raw_ntlm_smb_encryption_start(c,
+                                       username,
+                                       password,
+                                       domain);
+}
index 6f6e1e64743df91940690a943b7a94a175682aef..dd8b911bb8d11a925961a8d19369dfae24c9ff72 100644 (file)
@@ -850,6 +850,18 @@ out_free:
                goto done;
        }
 
+       if (get_cmdline_auth_info_smb_encrypt()) {
+               nt_status = cli_cm_force_encryption(cli,
+                                       get_cmdline_auth_info_username(),
+                                       get_cmdline_auth_info_password(),
+                                       lp_workgroup(),
+                                       "IPC$");
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       result = 1;
+                       goto done;
+               }
+       }
+
 #if 0  /* COMMENT OUT FOR TESTING */
        memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password));
 #endif
index bf70d08d8b42aa567c468089688547bb00b657b1..59316091bad85e1093e1433853063d25613fe8a1 100644 (file)
@@ -88,6 +88,7 @@ int opt_testmode = False;
 
 int opt_have_ip = False;
 struct sockaddr_storage opt_dest_ip;
+bool smb_encrypt;
 
 extern bool AllowDebugChange;
 
@@ -178,9 +179,7 @@ NTSTATUS connect_to_service(struct cli_state **c,
                                        service_name, service_type,
                                        opt_user_name, opt_workgroup,
                                        opt_password, 0, Undefined, NULL);
-       if (NT_STATUS_IS_OK(nt_status)) {
-               return nt_status;
-       } else {
+       if (!NT_STATUS_IS_OK(nt_status)) {
                d_fprintf(stderr, "Could not connect to server %s\n", server_name);
 
                /* Display a nicer message depending on the result */
@@ -196,9 +195,41 @@ NTSTATUS connect_to_service(struct cli_state **c,
                if (NT_STATUS_V(nt_status) ==
                    NT_STATUS_V(NT_STATUS_ACCOUNT_DISABLED))
                        d_fprintf(stderr, "The account was disabled.\n");
-
                return nt_status;
        }
+
+       if (smb_encrypt) {
+               nt_status = cli_force_encryption(*c,
+                                       opt_user_name,
+                                       opt_password,
+                                       opt_workgroup,
+                                       service_name);
+
+               if (NT_STATUS_EQUAL(nt_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(nt_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(nt_status,NT_STATUS_UNSUPPORTED_COMPRESSION)) {
+                       d_printf("Encryption required and "
+                               "share %s doesn't support "
+                               "encryption.\n", service_name);
+               } else if (!NT_STATUS_IS_OK(nt_status)) {
+                       d_printf("Encryption required and "
+                               "setup failed with error %s.\n",
+                               nt_errstr(nt_status));
+               }
+
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       cli_shutdown(*c);
+                       *c = NULL;
+               }
+       }
+
+       return nt_status;
 }
 
 /****************************************************************************
@@ -287,12 +318,24 @@ NTSTATUS connect_to_ipc_krb5(struct cli_state **c,
 
        SAFE_FREE(user_and_realm);
 
-       if (NT_STATUS_IS_OK(nt_status)) {
-               return nt_status;
-       } else {
+       if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(1,("Cannot connect to server using kerberos.  Error was %s\n", nt_errstr(nt_status)));
                return nt_status;
        }
+
+        if (smb_encrypt) {
+               nt_status = cli_cm_force_encryption(*c,
+                                       user_and_realm,
+                                       opt_password,
+                                       opt_workgroup,
+                                        "IPC$");
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       cli_shutdown(*c);
+                       *c = NULL;
+               }
+       }
+
+       return nt_status;
 }
 
 /**
@@ -988,6 +1031,7 @@ static struct functable net_func[] = {
                {"port",        'p', POPT_ARG_INT,    &opt_port},
                {"myname",      'n', POPT_ARG_STRING, &opt_requester_name},
                {"server",      'S', POPT_ARG_STRING, &opt_host},
+               {"encrypt",     'e', POPT_ARG_NONE,   NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" },
                {"container",   'c', POPT_ARG_STRING, &opt_container},
                {"comment",     'C', POPT_ARG_STRING, &opt_comment},
                {"maxusers",    'M', POPT_ARG_INT,    &opt_maxusers},
@@ -1010,7 +1054,7 @@ static struct functable net_func[] = {
                {"acls",        0, POPT_ARG_NONE,     &opt_acls},
                {"attrs",       0, POPT_ARG_NONE,     &opt_attrs},
                {"timestamps",  0, POPT_ARG_NONE,     &opt_timestamps},
-               {"exclude",     'e', POPT_ARG_STRING, &opt_exclude},
+               {"exclude",     'X', POPT_ARG_STRING, &opt_exclude},
                {"destination", 0, POPT_ARG_STRING,   &opt_destination},
                {"tallocreport", 0, POPT_ARG_NONE, &do_talloc_report},
 
@@ -1037,6 +1081,9 @@ static struct functable net_func[] = {
                        net_help(argc, argv);
                        exit(0);
                        break;
+               case 'e':
+                       smb_encrypt=true;
+                       break;
                case 'I':
                        if (!interpret_string_addr(&opt_dest_ip,
                                                poptGetOptArg(pc), 0)) {
index 2cb601f9172cc00fceeb06603e24a8a9f7ad7519..908be0512a1f2687359140d572a45b173f8c5b1a 100644 (file)
@@ -48,6 +48,7 @@ int net_common_flags_usage(int argc, const char **argv)
        d_printf("\t-l or --long\t\t\tDisplay full information\n");
        d_printf("\t-V or --version\t\t\tPrint samba version information\n");
        d_printf("\t-P or --machine-pass\t\tAuthenticate as machine account\n");
+       d_printf("\t-e or --encrypt\t\tEncrypt SMB transport (UNIX extended servers only)\n");
        return -1;
 }
 
index ef4254ead211d6fe850d22e0996d4fbdb14c3766..134f5617603ffc44f35ac81af6c24ad08e9c69d7 100644 (file)
@@ -822,7 +822,7 @@ static int cacl_set(struct cli_state *cli, char *filename,
 *******************************************************/
 static struct cli_state *connect_one(const char *server, const char *share)
 {
-       struct cli_state *c;
+       struct cli_state *c = NULL;
        struct sockaddr_storage ss;
        NTSTATUS nt_status;
        zero_addr(&ss);
@@ -834,20 +834,33 @@ static struct cli_state *connect_one(const char *server, const char *share)
                }
        }
 
-       if (NT_STATUS_IS_OK(nt_status = cli_full_connection(&c, global_myname(), server, 
-                                                           &ss, 0,
-                                                           share, "?????",
-                                                           get_cmdline_auth_info_username(),
-                                                           lp_workgroup(),
-                                                           get_cmdline_auth_info_password(),
-                                                            get_cmdline_auth_info_use_kerberos() ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
-                                                           get_cmdline_auth_info_signing_state(),
-                                                           NULL))) {
-               return c;
-       } else {
+       nt_status = cli_full_connection(&c, global_myname(), server, 
+                               &ss, 0,
+                               share, "?????",
+                               get_cmdline_auth_info_username(),
+                               lp_workgroup(),
+                               get_cmdline_auth_info_password(),
+                               get_cmdline_auth_info_use_kerberos() ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
+                               get_cmdline_auth_info_signing_state(),
+                               NULL);
+       if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status)));
                return NULL;
        }
+
+       if (get_cmdline_auth_info_smb_encrypt()) {
+               nt_status = cli_cm_force_encryption(c,
+                                       get_cmdline_auth_info_username(),
+                                       get_cmdline_auth_info_password(),
+                                       lp_workgroup(),
+                                       share);
+                if (!NT_STATUS_IS_OK(nt_status)) {
+                       cli_shutdown(c);
+                       c = NULL;
+                }
+       }
+
+       return c;
 }
 
 /****************************************************************************