Determine case sensitivity based on file system attributes.
authorDerrell Lipman <derrell.lipman@unwireduniverse.com>
Sat, 17 Jan 2009 18:33:25 +0000 (13:33 -0500)
committerDerrell Lipman <derrell.lipman@unwireduniverse.com>
Sat, 17 Jan 2009 18:33:39 +0000 (13:33 -0500)
- Most of the time, we can determine from the file system we're connecting to
  whether it supports case sensitivity. In those cases, we now set the
  internal case sensitivity flag automatically. For those cases where the
  request to retrieve file system attributes fails, we'll use the
  user-specified option value.

Derrell

source3/include/libsmbclient.h
source3/libsmb/libsmb_context.c
source3/libsmb/libsmb_server.c
source3/libsmb/libsmb_setget.c

index 4a8accbf4e54977d26860f3fa709a150b91cb3e6..b2d9483a0b9ad9098a7ed143dae521ec0012aaf4 100644 (file)
@@ -550,11 +550,23 @@ smbc_getOptionSmbEncryptionLevel(SMBCCTX *c);
 void
 smbc_setOptionSmbEncryptionLevel(SMBCCTX *c, smbc_smb_encrypt_level level);
 
 void
 smbc_setOptionSmbEncryptionLevel(SMBCCTX *c, smbc_smb_encrypt_level level);
 
-/** Get whether to treat file names as case-sensitive. */
+/**
+ * Get whether to treat file names as case-sensitive if we can't determine
+ * when connecting to the remote share whether the file system is case
+ * sensitive. This defaults to FALSE since it's most likely that if we can't
+ * retrieve the file system attributes, it's a very old file system that does
+ * not support case sensitivity.
+ */
 smbc_bool
 smbc_getOptionCaseSensitive(SMBCCTX *c);
 
 smbc_bool
 smbc_getOptionCaseSensitive(SMBCCTX *c);
 
-/** Set whether to treat file names as case-sensitive. */
+/**
+ * Set whether to treat file names as case-sensitive if we can't determine
+ * when connecting to the remote share whether the file system is case
+ * sensitive. This defaults to FALSE since it's most likely that if we can't
+ * retrieve the file system attributes, it's a very old file system that does
+ * not support case sensitivity.
+ */
 void
 smbc_setOptionCaseSensitive(SMBCCTX *c, smbc_bool b);
 
 void
 smbc_setOptionCaseSensitive(SMBCCTX *c, smbc_bool b);
 
index ca8ceedbc2354bff6c167583167d7e9ee325ed1d..c2c33e53025903c6a3a2ff02c4cd781f8fdebee2 100644 (file)
@@ -69,7 +69,7 @@ smbc_new_context(void)
         smbc_setOptionFullTimeNames(context, False);
         smbc_setOptionOpenShareMode(context, SMBC_SHAREMODE_DENY_NONE);
         smbc_setOptionSmbEncryptionLevel(context, SMBC_ENCRYPTLEVEL_NONE);
         smbc_setOptionFullTimeNames(context, False);
         smbc_setOptionOpenShareMode(context, SMBC_SHAREMODE_DENY_NONE);
         smbc_setOptionSmbEncryptionLevel(context, SMBC_ENCRYPTLEVEL_NONE);
-        smbc_setOptionCaseSensitive(context, True);
+        smbc_setOptionCaseSensitive(context, False);
         smbc_setOptionBrowseMaxLmbCount(context, 3);    /* # LMBs to query */
         smbc_setOptionUrlEncodeReaddirEntries(context, False);
         smbc_setOptionOneSharePerServer(context, False);
         smbc_setOptionBrowseMaxLmbCount(context, 3);    /* # LMBs to query */
         smbc_setOptionUrlEncodeReaddirEntries(context, False);
         smbc_setOptionOneSharePerServer(context, False);
index e2cc07118b73e0a215f3f1dafb56b946696871f7..0ece5bb649e194b60055812683d98c5b7c9c6a83 100644 (file)
@@ -245,6 +245,8 @@ SMBC_server(TALLOC_CTX *ctx,
        int tried_reverse = 0;
         int port_try_first;
         int port_try_next;
        int tried_reverse = 0;
         int port_try_first;
         int port_try_next;
+        int is_ipc = (share != NULL && strcmp(share, "IPC$") == 0);
+       uint32 fs_attrs = 0;
         const char *username_used;
        NTSTATUS status;
 
         const char *username_used;
        NTSTATUS status;
 
@@ -310,6 +312,38 @@ SMBC_server(TALLOC_CTX *ctx,
                                 srv = NULL;
                         }
 
                                 srv = NULL;
                         }
 
+                        /* Determine if this share supports case sensitivity */
+                        if (is_ipc) {
+                                DEBUG(4,
+                                      ("IPC$ so ignore case sensitivity\n"));
+                        } else if (!cli_get_fs_attr_info(c, &fs_attrs)) {
+                                DEBUG(4, ("Could not retrieve "
+                                          "case sensitivity flag: %s.\n",
+                                          cli_errstr(c)));
+
+                                /*
+                                 * We can't determine the case sensitivity of
+                                 * the share. We have no choice but to use the
+                                 * user-specified case sensitivity setting.
+                                 */
+                                if (smbc_getOptionCaseSensitive(context)) {
+                                        cli_set_case_sensitive(c, True);
+                                } else {
+                                        cli_set_case_sensitive(c, False);
+                                }
+                        } else {
+                                DEBUG(4,
+                                      ("Case sensitive: %s\n",
+                                       (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
+                                        ? "True"
+                                        : "False")));
+                                cli_set_case_sensitive(
+                                        c,
+                                        (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
+                                         ? True
+                                         : False));
+                        }
+
                         /*
                          * Regenerate the dev value since it's based on both
                          * server and share
                         /*
                          * Regenerate the dev value since it's based on both
                          * server and share
@@ -356,13 +390,6 @@ again:
                return NULL;
        }
 
                return NULL;
        }
 
-       /* POSIX-like - always request case-sensitivity by default. */        
-        if (smbc_getOptionCaseSensitive(context)) {
-            cli_set_case_sensitive(c, True);
-        } else {
-            cli_set_case_sensitive(c, False);
-        }
-
         if (smbc_getOptionUseKerberos(context)) {
                c->use_kerberos = True;
        }
         if (smbc_getOptionUseKerberos(context)) {
                c->use_kerberos = True;
        }
@@ -377,7 +404,7 @@ again:
          * Force use of port 139 for first try if share is $IPC, empty, or
          * null, so browse lists can work
          */
          * Force use of port 139 for first try if share is $IPC, empty, or
          * null, so browse lists can work
          */
-        if (share == NULL || *share == '\0' || strcmp(share, "IPC$") == 0) {
+        if (share == NULL || *share == '\0' || is_ipc) {
                 port_try_first = 139;
                 port_try_next = 445;
         } else {
                 port_try_first = 139;
                 port_try_next = 445;
         } else {
@@ -483,6 +510,34 @@ again:
 
        DEBUG(4,(" tconx ok\n"));
 
 
        DEBUG(4,(" tconx ok\n"));
 
+        /* Determine if this share supports case sensitivity */
+       if (is_ipc) {
+                DEBUG(4, ("IPC$ so ignore case sensitivity\n"));
+        } else if (!cli_get_fs_attr_info(c, &fs_attrs)) {
+                DEBUG(4, ("Could not retrieve case sensitivity flag: %s.\n",
+                          cli_errstr(c)));
+
+                /*
+                 * We can't determine the case sensitivity of the share. We
+                 * have no choice but to use the user-specified case
+                 * sensitivity setting.
+                 */
+                if (smbc_getOptionCaseSensitive(context)) {
+                        cli_set_case_sensitive(c, True);
+                } else {
+                        cli_set_case_sensitive(c, False);
+                }
+       } else {
+                DEBUG(4, ("Case sensitive: %s\n",
+                          (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
+                           ? "True"
+                           : "False")));
+                cli_set_case_sensitive(c,
+                                       (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
+                                        ? True
+                                        : False));
+        }
+
        if (context->internal->smb_encryption_level) {
                /* Attempt UNIX smb encryption. */
                if (!NT_STATUS_IS_OK(cli_force_encryption(c,
        if (context->internal->smb_encryption_level) {
                /* Attempt UNIX smb encryption. */
                if (!NT_STATUS_IS_OK(cli_force_encryption(c,
index bca2a80d14bfe0ecbf25f8f15b48591d542db284..9de49a5b3f6dca753fb9be9f403c1ce3db95a310 100644 (file)
@@ -193,14 +193,26 @@ smbc_setOptionSmbEncryptionLevel(SMBCCTX *c, smbc_smb_encrypt_level level)
         c->internal->smb_encryption_level = level;
 }
 
         c->internal->smb_encryption_level = level;
 }
 
-/** Get whether to treat file names as case-sensitive. */
+/**
+ * Get whether to treat file names as case-sensitive if we can't determine
+ * when connecting to the remote share whether the file system is case
+ * sensitive. This defaults to FALSE since it's most likely that if we can't
+ * retrieve the file system attributes, it's a very old file system that does
+ * not support case sensitivity.
+ */
 smbc_bool
 smbc_getOptionCaseSensitive(SMBCCTX *c)
 {
         return c->internal->case_sensitive;
 }
 
 smbc_bool
 smbc_getOptionCaseSensitive(SMBCCTX *c)
 {
         return c->internal->case_sensitive;
 }
 
-/** Set whether to treat file names as case-sensitive. */
+/**
+ * Set whether to treat file names as case-sensitive if we can't determine
+ * when connecting to the remote share whether the file system is case
+ * sensitive. This defaults to FALSE since it's most likely that if we can't
+ * retrieve the file system attributes, it's a very old file system that does
+ * not support case sensitivity.
+ */
 void
 smbc_setOptionCaseSensitive(SMBCCTX *c, smbc_bool b)
 {
 void
 smbc_setOptionCaseSensitive(SMBCCTX *c, smbc_bool b)
 {