r3288: - updated the path processing in pvfs to pass the RAW-CHKPATH test. This
authorAndrew Tridgell <tridge@samba.org>
Wed, 27 Oct 2004 08:36:51 +0000 (08:36 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:04:50 +0000 (13:04 -0500)
  rather extensive test reveals some really bizarre error code
  handling in w2k3.

- extended and simplified the RAW-CHKPATH test, making it easier to
  read (note that Samba3 fails the new tests - jra may wish to look)

- marked RAW-CHKPATH as pass for pvfs
(This used to be commit 32dccf91cfa5b57f84dd6307720b3f45faa10ae0)

source4/ntvfs/posix/pvfs_resolve.c
source4/ntvfs/posix/vfs_posix.c
source4/script/tests/test_posix.sh
source4/torture/raw/chkpath.c

index a7a693b21703f7e1116c11efc9d3a96789425212..75fbeb39a5f2359417d9e174e42906c5cab5a7a6 100644 (file)
@@ -116,7 +116,7 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename *
                /* check if this component exists as-is */
                if (stat(test_name, &name->st) == 0) {
                        if (i<num_components-1 && !S_ISDIR(name->st.st_mode)) {
-                               return NT_STATUS_NOT_A_DIRECTORY;
+                               return NT_STATUS_OBJECT_PATH_NOT_FOUND;
                        }
                        talloc_free(partial_name);
                        partial_name = test_name;
@@ -193,7 +193,6 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
                               uint_t flags, struct pvfs_filename *name)
 {
        char *ret, *p, *p_start;
-       size_t len;
 
        name->original_name = talloc_strdup(name, cifs_name);
        name->stream_name = NULL;
@@ -218,18 +217,10 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
 
        p = ret + strlen(pvfs->base_directory) + 1;
 
-       len = strlen(cifs_name);
-       if (len>0 && p[len-1] == '\\') {
-               p[len-1] = 0;
-               len--;
-       }
-       if (len>1 && p[len-1] == '.' && p[len-2] == '\\') {
-               return NT_STATUS_OBJECT_NAME_INVALID;
-       }
-
        /* now do an in-place conversion of '\' to '/', checking
           for legal characters */
        p_start = p;
+
        while (*p) {
                size_t c_size;
                codepoint_t c = next_codepoint(p, &c_size);
@@ -240,7 +231,11 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
                                   of a name */
                                return NT_STATUS_ILLEGAL_CHARACTER;
                        }
-                       *p = '/';
+                       if (p > p_start && p[1] == 0) {
+                               *p = 0;
+                       } else {
+                               *p = '/';
+                       }
                        break;
                case ':':
                        if (!(flags & PVFS_RESOLVE_STREAMS)) {
@@ -258,7 +253,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
                case '?':
                case '"':
                        if (flags & PVFS_RESOLVE_NO_WILDCARD) {
-                               return NT_STATUS_ILLEGAL_CHARACTER;
+                               return NT_STATUS_OBJECT_NAME_INVALID;
                        }
                        name->has_wildcard = True;
                        break;
@@ -297,30 +292,26 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
   reduce a name that contains .. components or repeated \ separators
   return NULL if it can't be reduced
 */
-const char *pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char *fname)
+static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t flags)
 {
        codepoint_t c;
        size_t c_size, len;
-       int i, num_components;
+       int i, num_components, err_count;
        char **components;
        char *p, *s, *ret;
 
-       s = talloc_strdup(mem_ctx, fname);
-       if (s == NULL) return NULL;
+       s = talloc_strdup(mem_ctx, *fname);
+       if (s == NULL) return NT_STATUS_NO_MEMORY;
 
        for (num_components=1, p=s; *p; p += c_size) {
                c = next_codepoint(p, &c_size);
                if (c == '\\') num_components++;
        }
-       if (num_components < 2) {
-               talloc_free(s);
-               return NULL;
-       }
 
        components = talloc_array_p(s, char *, num_components+1);
        if (components == NULL) {
                talloc_free(s);
-               return NULL;
+               return NT_STATUS_NO_MEMORY;
        }
 
        components[0] = s;
@@ -333,16 +324,40 @@ const char *pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char *fname)
        }
        components[i+1] = NULL;
 
+       /*
+         rather bizarre!
+
+         '.' components are not allowed, but the rules for what error
+         code to give don't seem to make sense. This is a close
+         approximation.
+       */
+       for (err_count=i=0;components[i];i++) {
+               if (strcmp(components[i], "") == 0) {
+                       continue;
+               }
+               if (strcmp(components[i], ".") == 0 || err_count) {
+                       err_count++;
+               }
+       }
+       if (err_count) {
+               if (!(flags & PVFS_RESOLVE_NO_WILDCARD)) err_count--;
+
+               if (err_count==1) {
+                       return NT_STATUS_OBJECT_NAME_INVALID;
+               } else {
+                       return NT_STATUS_OBJECT_PATH_NOT_FOUND;
+               }
+       }
+
        /* remove any null components */
        for (i=0;components[i];i++) {
-               if (strcmp(components[i], "") == 0 ||
-                   strcmp(components[i], ".") == 0) {
+               if (strcmp(components[i], "") == 0) {
                        memmove(&components[i], &components[i+1], 
                                sizeof(char *)*(num_components-i));
                        i--;
                }
                if (strcmp(components[i], "..") == 0) {
-                       if (i < 1) return NULL;
+                       if (i < 1) return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
                        memmove(&components[i-1], &components[i+1], 
                                sizeof(char *)*(num_components-(i+1)));
                        i -= 2;
@@ -351,7 +366,8 @@ const char *pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char *fname)
 
        if (components[0] == NULL) {
                talloc_free(s);
-               return talloc_strdup(mem_ctx, "\\");
+               *fname = talloc_strdup(mem_ctx, "\\");
+               return NT_STATUS_OK;
        }
 
        for (len=i=0;components[i];i++) {
@@ -362,7 +378,7 @@ const char *pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char *fname)
        ret = talloc(mem_ctx, len+1);
        if (ret == NULL) {
                talloc_free(s);
-               return NULL;
+               return NT_STATUS_NO_MEMORY;
        }
 
        for (len=0,i=0;components[i];i++) {
@@ -374,8 +390,10 @@ const char *pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char *fname)
        ret[len] = 0;
 
        talloc_free(s);
+
+       *fname = ret;
        
-       return ret;
+       return NT_STATUS_OK;
 }
 
 
@@ -408,10 +426,11 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) {
                /* it might contain .. components which need to be reduced */
-               cifs_name = pvfs_reduce_name(*name, cifs_name);
-               if (cifs_name) {
-                       status = pvfs_unix_path(pvfs, cifs_name, flags, *name);
+               status = pvfs_reduce_name(*name, &cifs_name, flags);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
                }
+               status = pvfs_unix_path(pvfs, cifs_name, flags, *name);
        }
 
        if (!NT_STATUS_IS_OK(status)) {
index b83e4c494ec9547e47eb75c5ed27072e64114584..8dc87b160d4424b2ab2b7ab11e102262e64d430d 100644 (file)
@@ -151,7 +151,8 @@ static NTSTATUS pvfs_chkpath(struct ntvfs_module_context *ntvfs,
        NTSTATUS status;
 
        /* resolve the cifs name to a posix name */
-       status = pvfs_resolve_name(pvfs, req, cp->in.path, 0, &name);
+       status = pvfs_resolve_name(pvfs, req, cp->in.path, 
+                                  PVFS_RESOLVE_NO_WILDCARD, &name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
index d298f5d7ce60dbaab45e3cc70defcb5651e45cc4..68e751557ca541faa444f99f105a0563a473aa21 100755 (executable)
@@ -37,12 +37,12 @@ tests="$tests BASE-DELETE BASE-PROPERTIES BASE-MANGLE"
 tests="$tests BASE-CHKPATH BASE-SECLEAK BASE-TRANS2"
 tests="$tests RAW-QFSINFO RAW-QFILEINFO RAW-SFILEINFO-BUG"
 tests="$tests RAW-LOCK RAW-MKDIR RAW-SEEK RAW-CONTEXT BASE-RENAME"
-tests="$tests RAW-UNLINK RAW-READ RAW-CLOSE RAW-IOCTL RAW-SEARCH"
+tests="$tests RAW-UNLINK RAW-READ RAW-CLOSE RAW-IOCTL RAW-SEARCH RAW-CHKPATH"
 tests="$tests LOCAL-ICONV LOCAL-TALLOC LOCAL-MESSAGING LOCAL-BINDING LOCAL-IDTREE"
 
 soon="BASE-DENY1 BASE-DEFER_OPEN BASE-OPENATTR BASE-CHARSET"
 soon="$soon RAW-SFILEINFO RAW-OPEN RAW-OPLOCK RAW-NOTIFY RAW-MUX"
-soon="$soon RAW-CHKPATH RAW-WRITE RAW-RENAME"
+soon="$soon RAW-WRITE RAW-RENAME"
 
 for t in $tests; do
     if [ ! -z "$start" -a "$start" != $t ]; then
index 7749c6194fa8b4bf14e4c9f0ab3c3c7284847b6e..38684add60843f2f1c71104c609913cf0d918af0 100644 (file)
@@ -50,6 +50,23 @@ static NTSTATUS single_search(struct smbcli_state *cli,
         return status;
 }
 
+static BOOL test_path(struct smbcli_state *cli, const char *path, NTSTATUS res)
+{
+       struct smb_chkpath io;
+       NTSTATUS status;
+       io.in.path = path;
+       status = smb_raw_chkpath(cli->tree, &io);
+       if (!NT_STATUS_EQUAL(status, res)) {
+               printf("%-40s FAILED %s should be %s\n", 
+                      path, nt_errstr(status), nt_errstr(res));
+               return False;
+       } else {
+               printf("%-40s correct (%s)\n", path, nt_errstr(res));
+
+       }
+       return True;
+}
+
 static BOOL test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 {
        struct smb_chkpath io;
@@ -63,9 +80,7 @@ static BOOL test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        status = smb_raw_chkpath(cli->tree, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
 
-       io.in.path = BASEDIR "\\nodir";
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+       ret &= test_path(cli, BASEDIR "\\nodir", NT_STATUS_OBJECT_NAME_NOT_FOUND);
 
        fnum = create_complex_file(cli, mem_ctx, BASEDIR "\\test.txt..");
        if (fnum == -1) {
@@ -74,10 +89,7 @@ static BOOL test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
                goto done;
        }
 
-       io.in.path = BASEDIR "\\test.txt..";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_NOT_A_DIRECTORY);
+       ret &= test_path(cli, BASEDIR "\\test.txt..", NT_STATUS_NOT_A_DIRECTORY);
        
        if (!torture_set_file_attribute(cli->tree, BASEDIR, FILE_ATTRIBUTE_HIDDEN)) {
                printf("failed to set basedir hidden\n");
@@ -85,60 +97,22 @@ static BOOL test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
                goto done;
        }
 
-       io.in.path = BASEDIR;
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OK);
-
-       io.in.path = "";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OK);
-
-       io.in.path = ".";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
-
-       io.in.path = ".\\";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
-
-       io.in.path = ".\\.";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-
-       io.in.path = ".\\.\\";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-
-       io.in.path = ".\\.\\.";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-
-       io.in.path = ".\\.\\.aaaaa";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-
-       io.in.path = "\\.\\";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
-
-       io.in.path = "\\.\\\\";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
-
-       io.in.path = "\\.\\\\\\\\\\\\";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_path(cli, BASEDIR, NT_STATUS_OK);
+       ret &= test_path(cli, BASEDIR "\\foo\\..\\test.txt..", NT_STATUS_NOT_A_DIRECTORY);
+       ret &= test_path(cli, "", NT_STATUS_OK);
+       ret &= test_path(cli, ".", NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_path(cli, ".\\", NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_path(cli, "\\\\\\.\\", NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_path(cli, ".\\.", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, "." BASEDIR, NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, BASEDIR "\\.", NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_path(cli, BASEDIR "\\.\\test.txt..", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, ".\\.\\", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, ".\\.\\.", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, ".\\.\\.aaaaa", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, "\\.\\", NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_path(cli, "\\.\\\\", NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_path(cli, "\\.\\\\\\\\\\\\", NT_STATUS_OBJECT_NAME_INVALID);
 
        /* Note that the two following paths are identical but
          give different NT status returns for chkpth and findfirst. */
@@ -147,10 +121,7 @@ static BOOL test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        status = single_search(cli, mem_ctx, "\\.\\\\\\\\\\\\.");
        CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
 
-       io.in.path = "\\.\\\\\\\\\\\\.";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, "\\.\\\\\\\\\\\\.", NT_STATUS_OBJECT_PATH_NOT_FOUND);
 
        /* We expect this open to fail with the same error code as the chkpath below. */
        printf("testing Open on %s\n", "\\.\\\\\\\\\\\\.");
@@ -167,125 +138,31 @@ static BOOL test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
 
 
-       io.in.path = "\\.\\\\xxx";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-
-       io.in.path = "..\\..\\..";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
-
-       io.in.path = "\\..";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
-
-       io.in.path = "\\.\\\\\\\\\\\\xxx";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-
-       io.in.path = BASEDIR"\\.\\";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
-
-       io.in.path = BASEDIR"\\.\\\\";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
-
-       io.in.path = BASEDIR"\\.\\nt";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-
-       io.in.path = BASEDIR"\\.\\.\\nt";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-
-       io.in.path = BASEDIR"\\nt";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OK);
-
-       io.in.path = BASEDIR".\\foo";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-
-       io.in.path = ".\\";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
-
-       io.in.path = ".\\.";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-
-       io.in.path = ".\\.\\.\\.\\foo\\.\\.\\";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-
-       io.in.path = BASEDIR".\\.\\.\\.\\foo\\.\\.\\";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-
-       io.in.path = BASEDIR".\\.\\.\\.\\foo\\..\\.\\";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-
-       io.in.path = BASEDIR".";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
-
-       io.in.path = "\\";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OK);
-
-       io.in.path = "\\.";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
-
-       io.in.path = "\\..\\";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
-
-       io.in.path = "\\..";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
-
-       io.in.path = BASEDIR "\\.";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
-
-       io.in.path = BASEDIR "\\..";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OK);
-
-       io.in.path = BASEDIR "\\nt\\Visual Studio\\VB98\\vb600";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
-
-       io.in.path = BASEDIR "\\nt\\Visual Studio\\VB98\\vb6.exe";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_NOT_A_DIRECTORY);
+       ret &= test_path(cli, "\\.\\\\xxx", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, "..\\..\\..", NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
+       ret &= test_path(cli, "\\..", NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
+       ret &= test_path(cli, "\\.\\\\\\\\\\\\xxx", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, BASEDIR"\\.\\", NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_path(cli, BASEDIR"\\.\\\\", NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_path(cli, BASEDIR"\\.\\nt", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, BASEDIR"\\.\\.\\nt", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, BASEDIR"\\nt", NT_STATUS_OK);
+       ret &= test_path(cli, BASEDIR".\\foo", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, BASEDIR"xx\\foo", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, ".\\", NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_path(cli, ".\\.", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, ".\\.\\.\\.\\foo\\.\\.\\", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, BASEDIR".\\.\\.\\.\\foo\\.\\.\\", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, BASEDIR".\\.\\.\\.\\foo\\..\\.\\", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, BASEDIR".", NT_STATUS_OBJECT_NAME_NOT_FOUND);
+       ret &= test_path(cli, "\\", NT_STATUS_OK);
+       ret &= test_path(cli, "\\.", NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_path(cli, "\\..\\", NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
+       ret &= test_path(cli, "\\..", NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
+       ret &= test_path(cli, BASEDIR "\\.", NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_path(cli, BASEDIR "\\..", NT_STATUS_OK);
+       ret &= test_path(cli, BASEDIR "\\nt\\V S\\VB98\\vb600", NT_STATUS_OBJECT_NAME_NOT_FOUND);
+       ret &= test_path(cli, BASEDIR "\\nt\\V S\\VB98\\vb6.exe", NT_STATUS_NOT_A_DIRECTORY);
 
        /* We expect this open to fail with the same error code as the chkpath below. */
        printf("testing Open on %s\n", BASEDIR".\\.\\.\\.\\foo\\..\\.\\");
@@ -307,8 +184,8 @@ static BOOL test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
        /* We expect this open to fail with the same error code as the chkpath below. */
        /* findfirst seems to fail with a different error. */
-       printf("testing Open on %s\n", BASEDIR "\\nt\\Visual Studio\\VB98\\vb6.exe\\3");
-       fnum1 = smbcli_nt_create_full(cli->tree, BASEDIR "\\nt\\Visual Studio\\VB98\\vb6.exe\\3",
+       printf("testing Open on %s\n", BASEDIR "\\nt\\V S\\VB98\\vb6.exe\\3");
+       fnum1 = smbcli_nt_create_full(cli->tree, BASEDIR "\\nt\\V S\\VB98\\vb6.exe\\3",
                                0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
                                FILE_ATTRIBUTE_NORMAL,
                                NTCREATEX_SHARE_ACCESS_DELETE|
@@ -319,25 +196,11 @@ static BOOL test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        status = smbcli_nt_error(cli->tree);
        CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
 
-       io.in.path = BASEDIR "\\nt\\Visual Studio\\VB98\\vb6.exe\\3";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-
-       io.in.path = BASEDIR "\\nt\\Visual Studio\\VB98\\vb6.exe\\3\\foo";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-
-       io.in.path = BASEDIR "\\nt\\3\\foo";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-
-       io.in.path = BASEDIR "\\nt\\Visual Studio\\*\\vb6.exe\\3";
-       printf("testing %s\n", io.in.path);
-       status = smb_raw_chkpath(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_path(cli, BASEDIR "\\nt\\V S\\VB98\\vb6.exe\\3", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, BASEDIR "\\nt\\V S\\VB98\\vb6.exe\\3\\foo", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, BASEDIR "\\nt\\3\\foo", NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       ret &= test_path(cli, BASEDIR "\\nt\\V S\\*\\vb6.exe\\3", NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_path(cli, BASEDIR "\\nt\\V S\\*\\*\\vb6.exe\\3", NT_STATUS_OBJECT_NAME_INVALID);
 
 done:
        smbcli_close(cli->tree, fnum);
@@ -374,19 +237,19 @@ BOOL torture_raw_chkpath(int dummy)
                return False;
        }
 
-       if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR "\\nt\\Visual Studio"))) {
+       if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR "\\nt\\V S"))) {
                printf("Failed to create " BASEDIR " - %s\n", smbcli_errstr(cli->tree));
                return False;
        }
 
-       if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR "\\nt\\Visual Studio\\VB98"))) {
+       if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR "\\nt\\V S\\VB98"))) {
                printf("Failed to create " BASEDIR " - %s\n", smbcli_errstr(cli->tree));
                return False;
        }
 
-       fnum = create_complex_file(cli, mem_ctx, BASEDIR "\\nt\\Visual Studio\\VB98\\vb6.exe");
+       fnum = create_complex_file(cli, mem_ctx, BASEDIR "\\nt\\V S\\VB98\\vb6.exe");
        if (fnum == -1) {
-               printf("failed to open \\nt\\Visual Studio\\VB98\\vb6.exe - %s\n", smbcli_errstr(cli->tree));
+               printf("failed to open \\nt\\V S\\VB98\\vb6.exe - %s\n", smbcli_errstr(cli->tree));
                ret = False;
                goto done;
        }