The branch, v3-6-test has been updated
       via  c68f4af Remove all uses of "./" in pathnames - make canonical. This 
will become important when we need to guarantee canonical names for hashing. 
(cherry picked from commit f278cc1a1f253b6492ef60c2879bdae6a2730084)
       via  4f84d67 Ensure we don't use "./" in findfirst pathnames. Use a 
directory open of "." instead. (cherry picked from commit 
de4b09ca01b1747c49bb0058147977ff39d054bb)
       via  f97f6a0 Make processing of incoming stream rename paths common 
between reply_mv and ntrename. Ensure we don't depend on "./" in the streams 
module. (cherry picked from commit bb54f72b94dca9206bf377b0d6a4b669e389e339)
      from  fabfc89 s3:smbd: use anonymous_shared_free() for shared memory 
signing state

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


- Log -----------------------------------------------------------------
commit c68f4af4f9c4e580ec4192a6e1c0e67fbba52455
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jan 20 16:32:57 2011 -0800

    Remove all uses of "./" in pathnames - make canonical. This will become 
important when we need to guarantee canonical names for hashing.
    (cherry picked from commit f278cc1a1f253b6492ef60c2879bdae6a2730084)

commit 4f84d6720779bf1a3cc855e9d4508a7026eb4e59
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jan 20 16:30:28 2011 -0800

    Ensure we don't use "./" in findfirst pathnames. Use a directory open of 
"." instead.
    (cherry picked from commit de4b09ca01b1747c49bb0058147977ff39d054bb)

commit f97f6a061ef497de3eade580bcf0a008bba33002
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Jan 20 16:27:56 2011 -0800

    Make processing of incoming stream rename paths common between reply_mv and 
ntrename. Ensure we don't depend on "./" in the streams module.
    (cherry picked from commit bb54f72b94dca9206bf377b0d6a4b669e389e339)

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

Summary of changes:
 source3/modules/vfs_streams_depot.c |   20 +-----
 source3/smbd/nttrans.c              |   26 +++++-
 source3/smbd/reply.c                |  153 +++++++++++++++++++++++-----------
 source3/smbd/trans2.c               |   12 ++-
 4 files changed, 134 insertions(+), 77 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/modules/vfs_streams_depot.c 
b/source3/modules/vfs_streams_depot.c
index 853d7b4..9870d0d 100644
--- a/source3/modules/vfs_streams_depot.c
+++ b/source3/modules/vfs_streams_depot.c
@@ -661,7 +661,6 @@ static int streams_depot_rename(vfs_handle_struct *handle,
 {
        struct smb_filename *smb_fname_src_stream = NULL;
        struct smb_filename *smb_fname_dst_stream = NULL;
-       struct smb_filename *smb_fname_dst_mod = NULL;
        bool src_is_stream, dst_is_stream;
        NTSTATUS status;
        int ret = -1;
@@ -692,23 +691,7 @@ static int streams_depot_rename(vfs_handle_struct *handle,
                goto done;
        }
 
-       /*
-        * Handle passing in a stream name without the base file.  This is
-        * exercised by the NTRENAME streams rename path.
-        */
-       if (StrCaseCmp(smb_fname_dst->base_name, "./") == 0) {
-               status = create_synthetic_smb_fname(talloc_tos(),
-                                                   smb_fname_src->base_name,
-                                                   smb_fname_dst->stream_name,
-                                                   NULL, &smb_fname_dst_mod);
-               if (!NT_STATUS_IS_OK(status)) {
-                       errno = map_errno_from_nt_status(status);
-                       goto done;
-               }
-       }
-
-       status = stream_smb_fname(handle, (smb_fname_dst_mod ?
-                                          smb_fname_dst_mod : smb_fname_dst),
+       status = stream_smb_fname(handle, smb_fname_dst,
                                  &smb_fname_dst_stream, false);
        if (!NT_STATUS_IS_OK(status)) {
                errno = map_errno_from_nt_status(status);
@@ -721,7 +704,6 @@ static int streams_depot_rename(vfs_handle_struct *handle,
 done:
        TALLOC_FREE(smb_fname_src_stream);
        TALLOC_FREE(smb_fname_dst_stream);
-       TALLOC_FREE(smb_fname_dst_mod);
        return ret;
 }
 
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index da1231c..9d6a892 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -1495,6 +1495,7 @@ void reply_ntrename(struct smb_request *req)
        uint32_t ucf_flags_dst = 0;
        uint16 rename_type;
        TALLOC_CTX *ctx = talloc_tos();
+       bool stream_rename = false;
 
        START_PROFILE(SMBntrename);
 
@@ -1527,10 +1528,16 @@ void reply_ntrename(struct smb_request *req)
                goto out;
        }
 
-       /* The newname must begin with a ':' if the oldname contains a ':'. */
-       if (strchr_m(oldname, ':') && (newname[0] != ':')) {
-               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               goto out;
+       if (!lp_posix_pathnames()) {
+               /* The newname must begin with a ':' if the
+                  oldname contains a ':'. */
+               if (strchr_m(oldname, ':')) {
+                       if (newname[0] != ':') {
+                               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                               goto out;
+                       }
+                       stream_rename = true;
+               }
        }
 
        /*
@@ -1579,6 +1586,17 @@ void reply_ntrename(struct smb_request *req)
                goto out;
        }
 
+       if (stream_rename) {
+               /* smb_fname_new must be the same as smb_fname_old. */
+               TALLOC_FREE(smb_fname_new->base_name);
+               smb_fname_new->base_name = talloc_strdup(smb_fname_new,
+                                               smb_fname_old->base_name);
+               if (!smb_fname_new->base_name) {
+                       reply_nterror(req, NT_STATUS_NO_MEMORY);
+                       goto out;
+               }
+       }
+
        DEBUG(3,("reply_ntrename: %s -> %s\n",
                 smb_fname_str_dbg(smb_fname_old),
                 smb_fname_str_dbg(smb_fname_new)));
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index e5067cc..538e22f 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -2587,6 +2587,17 @@ NTSTATUS unlink_internals(connection_struct *conn, 
struct smb_request *req,
                 * onto the directory.
                 */
                TALLOC_FREE(smb_fname->base_name);
+               if (ISDOT(fname_dir)) {
+                       /* Ensure we use canonical names on open. */
+                       smb_fname->base_name = talloc_asprintf(smb_fname,
+                                                       "%s",
+                                                       fname_mask);
+               } else {
+                       smb_fname->base_name = talloc_asprintf(smb_fname,
+                                                       "%s/%s",
+                                                       fname_dir,
+                                                       fname_mask);
+               }
                smb_fname->base_name = talloc_asprintf(smb_fname,
                                                       "%s/%s",
                                                       fname_dir,
@@ -2675,9 +2686,16 @@ NTSTATUS unlink_internals(connection_struct *conn, 
struct smb_request *req,
                        }
 
                        TALLOC_FREE(smb_fname->base_name);
-                       smb_fname->base_name =
-                           talloc_asprintf(smb_fname, "%s/%s",
-                                           fname_dir, dname);
+                       if (ISDOT(fname_dir)) {
+                               /* Ensure we use canonical names on open. */
+                               smb_fname->base_name =
+                                       talloc_asprintf(smb_fname, "%s",
+                                               dname);
+                       } else {
+                               smb_fname->base_name =
+                                       talloc_asprintf(smb_fname, "%s/%s",
+                                               fname_dir, dname);
+                       }
 
                        if (!smb_fname->base_name) {
                                TALLOC_FREE(dir_hnd);
@@ -5929,19 +5947,6 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
                goto out;
        }
 
-       /* Ensure the dst smb_fname contains a '/' */
-       if(strrchr_m(smb_fname_dst->base_name,'/') == 0) {
-               char * tmp;
-               tmp = talloc_asprintf(smb_fname_dst, "./%s",
-                                     smb_fname_dst->base_name);
-               if (!tmp) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto out;
-               }
-               TALLOC_FREE(smb_fname_dst->base_name);
-               smb_fname_dst->base_name = tmp;
-       }
-
        /*
         * Check for special case with case preserving and not
         * case sensitive. If the old last component differs from the original
@@ -5957,12 +5962,14 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
                struct smb_filename *smb_fname_orig_lcomp = NULL;
 
                /*
-                * Get the last component of the destination name.  Note that
-                * we guarantee that destination name contains a '/' character
-                * above.
+                * Get the last component of the destination name.
                 */
                last_slash = strrchr_m(smb_fname_dst->base_name, '/');
-               fname_dst_lcomp_base_mod = talloc_strdup(ctx, last_slash + 1);
+               if (last_slash) {
+                       fname_dst_lcomp_base_mod = talloc_strdup(ctx, 
last_slash + 1);
+               } else {
+                       fname_dst_lcomp_base_mod = talloc_strdup(ctx, 
smb_fname_dst->base_name);
+               }
                if (!fname_dst_lcomp_base_mod) {
                        status = NT_STATUS_NO_MEMORY;
                        goto out;
@@ -5988,11 +5995,17 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
                         * Replace the modified last component with the
                         * original.
                         */
-                       *last_slash = '\0'; /* Truncate at the '/' */
-                       tmp = talloc_asprintf(smb_fname_dst,
+                       if (last_slash) {
+                               *last_slash = '\0'; /* Truncate at the '/' */
+                               tmp = talloc_asprintf(smb_fname_dst,
                                        "%s/%s",
                                        smb_fname_dst->base_name,
                                        smb_fname_orig_lcomp->base_name);
+                       } else {
+                               tmp = talloc_asprintf(smb_fname_dst,
+                                       "%s",
+                                       smb_fname_orig_lcomp->base_name);
+                       }
                        if (tmp == NULL) {
                                status = NT_STATUS_NO_MEMORY;
                                TALLOC_FREE(fname_dst_lcomp_base_mod);
@@ -6247,28 +6260,22 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
                 * onto the directory.
                 */
                TALLOC_FREE(smb_fname_src->base_name);
-               smb_fname_src->base_name = talloc_asprintf(smb_fname_src,
-                                                          "%s/%s",
-                                                          fname_src_dir,
-                                                          fname_src_mask);
+               if (ISDOT(fname_src_dir)) {
+                       /* Ensure we use canonical names on open. */
+                       smb_fname_src->base_name = 
talloc_asprintf(smb_fname_src,
+                                                       "%s",
+                                                       fname_src_mask);
+               } else {
+                       smb_fname_src->base_name = 
talloc_asprintf(smb_fname_src,
+                                                       "%s/%s",
+                                                       fname_src_dir,
+                                                       fname_src_mask);
+               }
                if (!smb_fname_src->base_name) {
                        status = NT_STATUS_NO_MEMORY;
                        goto out;
                }
 
-               /* Ensure dst fname contains a '/' also */
-               if(strrchr_m(smb_fname_dst->base_name, '/') == 0) {
-                       char *tmp;
-                       tmp = talloc_asprintf(smb_fname_dst, "./%s",
-                                             smb_fname_dst->base_name);
-                       if (!tmp) {
-                               status = NT_STATUS_NO_MEMORY;
-                               goto out;
-                       }
-                       TALLOC_FREE(smb_fname_dst->base_name);
-                       smb_fname_dst->base_name = tmp;
-               }
-
                DEBUG(3, ("rename_internals: case_sensitive = %d, "
                          "case_preserve = %d, short case preserve = %d, "
                          "directory = %s, newname = %s, "
@@ -6409,10 +6416,17 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
                }
 
                TALLOC_FREE(smb_fname_src->base_name);
-               smb_fname_src->base_name = talloc_asprintf(smb_fname_src,
-                                                          "%s/%s",
-                                                          fname_src_dir,
-                                                          dname);
+               if (ISDOT(fname_src_dir)) {
+                       /* Ensure we use canonical names on open. */
+                       smb_fname_src->base_name = 
talloc_asprintf(smb_fname_src,
+                                                       "%s",
+                                                       dname);
+               } else {
+                       smb_fname_src->base_name = 
talloc_asprintf(smb_fname_src,
+                                                       "%s/%s",
+                                                       fname_src_dir,
+                                                       dname);
+               }
                if (!smb_fname_src->base_name) {
                        status = NT_STATUS_NO_MEMORY;
                        goto out;
@@ -6532,6 +6546,7 @@ void reply_mv(struct smb_request *req)
        TALLOC_CTX *ctx = talloc_tos();
        struct smb_filename *smb_fname_src = NULL;
        struct smb_filename *smb_fname_dst = NULL;
+       bool stream_rename = false;
 
        START_PROFILE(SMBmv);
 
@@ -6557,6 +6572,18 @@ void reply_mv(struct smb_request *req)
                goto out;
        }
 
+       if (!lp_posix_pathnames()) {
+               /* The newname must begin with a ':' if the
+                  name contains a ':'. */
+               if (strchr_m(name, ':')) {
+                       if (newname[0] != ':') {
+                               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                               goto out;
+                       }
+                       stream_rename = true;
+               }
+        }
+
        status = filename_convert(ctx,
                                  conn,
                                  req->flags2 & FLAGS2_DFS_PATHNAMES,
@@ -6593,6 +6620,18 @@ void reply_mv(struct smb_request *req)
                goto out;
        }
 
+       if (stream_rename) {
+               /* smb_fname_dst->base_name must be the same as
+                  smb_fname_src->base_name. */
+               TALLOC_FREE(smb_fname_dst->base_name);
+               smb_fname_dst->base_name = talloc_strdup(smb_fname_dst,
+                                               smb_fname_src->base_name);
+               if (!smb_fname_dst->base_name) {
+                       reply_nterror(req, NT_STATUS_NO_MEMORY);
+                       goto out;
+               }
+       }
+
        DEBUG(3,("reply_mv : %s -> %s\n", smb_fname_str_dbg(smb_fname_src),
                 smb_fname_str_dbg(smb_fname_dst)));
 
@@ -6932,10 +6971,17 @@ void reply_copy(struct smb_request *req)
                 * the directory.
                 */
                TALLOC_FREE(smb_fname_src->base_name);
-               smb_fname_src->base_name = talloc_asprintf(smb_fname_src,
-                                                          "%s/%s",
-                                                          fname_src_dir,
-                                                          fname_src_mask);
+               if (ISDOT(fname_src_dir)) {
+                       /* Ensure we use canonical names on open. */
+                       smb_fname_src->base_name = 
talloc_asprintf(smb_fname_src,
+                                                       "%s",
+                                                       fname_src_mask);
+               } else {
+                       smb_fname_src->base_name = 
talloc_asprintf(smb_fname_src,
+                                                       "%s/%s",
+                                                       fname_src_dir,
+                                                       fname_src_mask);
+               }
                if (!smb_fname_src->base_name) {
                        reply_nterror(req, NT_STATUS_NO_MEMORY);
                        goto out;
@@ -7043,9 +7089,16 @@ void reply_copy(struct smb_request *req)
 
                        /* Get the src smb_fname struct setup. */
                        TALLOC_FREE(smb_fname_src->base_name);
-                       smb_fname_src->base_name =
-                           talloc_asprintf(smb_fname_src, "%s/%s",
-                                           fname_src_dir, dname);
+                       if (ISDOT(fname_src_dir)) {
+                               /* Ensure we use canonical names on open. */
+                               smb_fname_src->base_name =
+                                       talloc_asprintf(smb_fname_src, "%s",
+                                               dname);
+                       } else {
+                               smb_fname_src->base_name =
+                                       talloc_asprintf(smb_fname_src, "%s/%s",
+                                               fname_src_dir, dname);
+                       }
 
                        if (!smb_fname_src->base_name) {
                                TALLOC_FREE(dir_hnd);
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index ddae99d..90a878d 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -2352,13 +2352,17 @@ close_if_end = %d requires_resume_key = %d level = 
0x%x, max_data_bytes = %d\n",
                        }
                        mask_contains_wcard = True;
                }
-               directory = talloc_strdup(talloc_tos(), "./");
+       } else {
+               *p = 0;
+       }
+
+       if (p == NULL || p == directory) {
+               /* Ensure we don't have a directory name of "". */
+               directory = talloc_strdup(talloc_tos(), ".");
                if (!directory) {
                        reply_nterror(req, NT_STATUS_NO_MEMORY);
                        goto out;
                }
-       } else {
-               *p = 0;
        }
 
        DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
@@ -6238,7 +6242,7 @@ static NTSTATUS 
smb_file_rename_information(connection_struct *conn,
                if (p) {
                        p[1] = '\0';
                } else {
-                       base_name = talloc_strdup(ctx, "./");
+                       base_name = talloc_strdup(ctx, "");
                        if (!base_name) {
                                return NT_STATUS_NO_MEMORY;
                        }


-- 
Samba Shared Repository

Reply via email to