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