From f49f3fcb0127b6ed19fec94f93658180ead04ac5 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 24 Jul 2009 18:38:40 -0700 Subject: s3: Convert a few callers of unix_convert() over to filename_convert() This patch also changes the unix convert flags to make sure the correct semantics are preservered for allowing/disallowing wildcards in the last component of the path. --- source3/smbd/filename.c | 22 +++++----- source3/smbd/msdfs.c | 2 +- source3/smbd/nttrans.c | 4 +- source3/smbd/reply.c | 112 +++++++++++++++++------------------------------- source3/smbd/trans2.c | 28 ++++-------- 5 files changed, 63 insertions(+), 105 deletions(-) (limited to 'source3/smbd') diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index a13c66c4e0..1e2ebcf307 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -98,8 +98,8 @@ processing whilst resolving. If the UCF_SAVE_LCOMP flag is passed in, then the unmodified last component of the pathname is set in smb_filename->original_lcomp. -If UCF_ALLOW_WCARD_LCOMP is passed in, then a MS wildcard was detected and -should be allowed in the last component of the path only. +If UCF_ALWAYS_ALLOW_WCARD_LCOMP is passed in, then a MS wildcard was detected +and should be allowed in the last component of the path only. If the orig_path was a stream, smb_filename->base_name will point to the base filename, and smb_filename->stream_name will point to the stream name. If @@ -124,7 +124,8 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, bool component_was_mangled = False; bool name_has_wildcard = False; bool posix_pathnames = false; - bool allow_wcard_last_component = ucf_flags & UCF_ALLOW_WCARD_LCOMP; + bool allow_wcard_last_component = + (ucf_flags & UCF_ALWAYS_ALLOW_WCARD_LCOMP); bool save_last_component = ucf_flags & UCF_SAVE_LCOMP; NTSTATUS status; int ret = -1; @@ -1035,8 +1036,9 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx, * @param dfs_path Whether this path requires dfs resolution. * @param name_in The unconverted name. * @param ucf_flags flags to pass through to unix_convert(). - * UCF_ALLOW_WCARD_LCOMP will be stripped out if - * p_cont_wcard == NULL or is false. + * UCF_ALWAYS_ALLOW_WCARD_LCOMP will be OR'd in if + * p_cont_wcard != NULL and is true and + * UCF_COND_ALLOW_WCARD_LCOMP. * @param p_cont_wcard If not NULL, will be set to true if the dfs path * resolution detects a wildcard. * @param pp_smb_fname The final converted name will be allocated if the @@ -1072,12 +1074,12 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, } /* - * Strip out the UCF_ALLOW_WCARD_LCOMP if the path doesn't contain a - * wildcard. + * If the caller conditionally allows wildcard lookups, only add the + * always allow if the path actually does contain a wildcard. */ - if (ppath_contains_wcard != NULL && !*ppath_contains_wcard && - ucf_flags & UCF_ALLOW_WCARD_LCOMP) { - ucf_flags &= ~UCF_ALLOW_WCARD_LCOMP; + if (ucf_flags & UCF_COND_ALLOW_WCARD_LCOMP && + ppath_contains_wcard != NULL && *ppath_contains_wcard) { + ucf_flags |= UCF_ALWAYS_ALLOW_WCARD_LCOMP; } status = unix_convert(ctx, conn, fname, pp_smb_fname, ucf_flags); diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index f4376d49ce..22fb8c3ad6 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -544,7 +544,7 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx, */ status = unix_convert(ctx, conn, pdp->reqpath, &smb_fname, - search_flag ? UCF_ALLOW_WCARD_LCOMP : 0); + search_flag ? UCF_ALWAYS_ALLOW_WCARD_LCOMP : 0); if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_EQUAL(status, diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index dd4ef97874..b7b2634963 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1359,8 +1359,8 @@ void reply_ntrename(struct smb_request *req) * destination's last component. */ if (rename_type == RENAME_FLAG_RENAME) { - ucf_flags_src = UCF_ALLOW_WCARD_LCOMP; - ucf_flags_dst = UCF_ALLOW_WCARD_LCOMP | UCF_SAVE_LCOMP; + ucf_flags_src = UCF_COND_ALLOW_WCARD_LCOMP; + ucf_flags_dst = UCF_COND_ALLOW_WCARD_LCOMP | UCF_SAVE_LCOMP; } /* rename_internals() calls unix_convert(), so don't call it here. */ diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 03bca827d1..b5882abe9f 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1402,11 +1402,12 @@ void reply_search(struct smb_request *req) /* dirtype &= ~aDIR; */ if (status_len == 0) { - nt_status = resolve_dfspath_wcard(ctx, conn, - req->flags2 & FLAGS2_DFS_PATHNAMES, - path, - &path, - &mask_contains_wcard); + nt_status = filename_convert(ctx, conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + path, + UCF_ALWAYS_ALLOW_WCARD_LCOMP, + &mask_contains_wcard, + &smb_fname); if (!NT_STATUS_IS_OK(nt_status)) { if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, @@ -1417,21 +1418,8 @@ void reply_search(struct smb_request *req) goto out; } - nt_status = unix_convert(ctx, conn, path, &smb_fname, - UCF_ALLOW_WCARD_LCOMP); - if (!NT_STATUS_IS_OK(nt_status)) { - reply_nterror(req, nt_status); - goto out; - } - directory = smb_fname->base_name; - nt_status = check_name(conn, directory); - if (!NT_STATUS_IS_OK(nt_status)) { - reply_nterror(req, nt_status); - goto out; - } - p = strrchr_m(directory,'/'); if ((p != NULL) && (*directory != '/')) { mask = p + 1; @@ -2516,21 +2504,15 @@ static NTSTATUS do_unlink(connection_struct *conn, ****************************************************************************/ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, - uint32 dirtype, const char *name_in, bool has_wild) + uint32 dirtype, struct smb_filename *smb_fname, + bool has_wild) { - struct smb_filename *smb_fname = NULL; char *fname_dir = NULL; char *fname_mask = NULL; int count=0; NTSTATUS status = NT_STATUS_OK; TALLOC_CTX *ctx = talloc_tos(); - status = unix_convert(ctx, conn, name_in, &smb_fname, - has_wild ? UCF_ALLOW_WCARD_LCOMP : 0); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - /* Split up the directory from the filename/mask. */ status = split_fname_dir_mask(ctx, smb_fname->base_name, &fname_dir, &fname_mask); @@ -2687,7 +2669,6 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, } out: - TALLOC_FREE(smb_fname); TALLOC_FREE(fname_dir); TALLOC_FREE(fname_mask); return status; @@ -2701,6 +2682,7 @@ void reply_unlink(struct smb_request *req) { connection_struct *conn = req->conn; char *name = NULL; + struct smb_filename *smb_fname = NULL; uint32 dirtype; NTSTATUS status; bool path_contains_wcard = False; @@ -2710,8 +2692,7 @@ void reply_unlink(struct smb_request *req) if (req->wct < 1) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - END_PROFILE(SMBunlink); - return; + goto out; } dirtype = SVAL(req->vwv+0, 0); @@ -2721,45 +2702,42 @@ void reply_unlink(struct smb_request *req) &path_contains_wcard); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); - END_PROFILE(SMBunlink); - return; + goto out; } - status = resolve_dfspath_wcard(ctx, conn, - req->flags2 & FLAGS2_DFS_PATHNAMES, - name, - &name, - &path_contains_wcard); + status = filename_convert(ctx, conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + name, + UCF_COND_ALLOW_WCARD_LCOMP, + &path_contains_wcard, + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); - END_PROFILE(SMBunlink); - return; + goto out; } reply_nterror(req, status); - END_PROFILE(SMBunlink); - return; + goto out; } - DEBUG(3,("reply_unlink : %s\n",name)); + DEBUG(3,("reply_unlink : %s\n", smb_fname_str_dbg(smb_fname))); - status = unlink_internals(conn, req, dirtype, name, + status = unlink_internals(conn, req, dirtype, smb_fname, path_contains_wcard); if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(req->mid)) { /* We have re-scheduled this call. */ - END_PROFILE(SMBunlink); - return; + goto out; } reply_nterror(req, status); - END_PROFILE(SMBunlink); - return; + goto out; } reply_outbuf(req, 0, 0); + out: + TALLOC_FREE(smb_fname); END_PROFILE(SMBunlink); - return; } @@ -6506,7 +6484,7 @@ void reply_mv(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, name, - UCF_ALLOW_WCARD_LCOMP, + UCF_COND_ALLOW_WCARD_LCOMP, &src_has_wcard, &smb_fname_src); @@ -6524,7 +6502,7 @@ void reply_mv(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, newname, - UCF_ALLOW_WCARD_LCOMP | UCF_SAVE_LCOMP, + UCF_COND_ALLOW_WCARD_LCOMP | UCF_SAVE_LCOMP, &dest_has_wcard, &smb_fname_dst); @@ -6787,11 +6765,12 @@ void reply_copy(struct smb_request *req) goto out; } - status = resolve_dfspath_wcard(ctx, conn, - req->flags2 & FLAGS2_DFS_PATHNAMES, - fname_src, - &fname_src, - &source_has_wild); + status = filename_convert(ctx, conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + fname_src, + UCF_COND_ALLOW_WCARD_LCOMP, + &source_has_wild, + &smb_fname_src); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, @@ -6802,11 +6781,12 @@ void reply_copy(struct smb_request *req) goto out; } - status = resolve_dfspath_wcard(ctx, conn, - req->flags2 & FLAGS2_DFS_PATHNAMES, - fname_dst, - &fname_dst, - &dest_has_wild); + status = filename_convert(ctx, conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + fname_dst, + UCF_COND_ALLOW_WCARD_LCOMP, + &dest_has_wild, + &smb_fname_dst); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, @@ -6817,20 +6797,6 @@ void reply_copy(struct smb_request *req) goto out; } - status = unix_convert(ctx, conn, fname_src, &smb_fname_src, - source_has_wild ? UCF_ALLOW_WCARD_LCOMP : 0); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - goto out; - } - - status = unix_convert(ctx, conn, fname_dst, &smb_fname_dst, - dest_has_wild ? UCF_ALLOW_WCARD_LCOMP : 0); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - goto out; - } - target_is_directory = VALID_STAT_OF_DIR(smb_fname_dst->st); if ((flags&1) && target_is_directory) { diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 50edf466c3..f34e15b1df 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2091,11 +2091,13 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", goto out; } - ntstatus = resolve_dfspath_wcard(ctx, conn, - req->flags2 & FLAGS2_DFS_PATHNAMES, - directory, - &directory, - &mask_contains_wcard); + ntstatus = filename_convert(ctx, conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + directory, + (UCF_SAVE_LCOMP | + UCF_ALWAYS_ALLOW_WCARD_LCOMP), + &mask_contains_wcard, + &smb_dname); if (!NT_STATUS_IS_OK(ntstatus)) { if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, @@ -2106,23 +2108,10 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", goto out; } - ntstatus = unix_convert(ctx, conn, directory, &smb_dname, - (UCF_SAVE_LCOMP | UCF_ALLOW_WCARD_LCOMP)); - if (!NT_STATUS_IS_OK(ntstatus)) { - reply_nterror(req, ntstatus); - goto out; - } - mask = smb_dname->original_lcomp; directory = smb_dname->base_name; - ntstatus = check_name(conn, directory); - if (!NT_STATUS_IS_OK(ntstatus)) { - reply_nterror(req, ntstatus); - goto out; - } - p = strrchr_m(directory,'/'); if(p == NULL) { /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */ @@ -5823,7 +5812,8 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn, status = unix_convert(ctx, conn, base_name, &smb_fname_dst, (UCF_SAVE_LCOMP | (dest_has_wcard ? - UCF_ALLOW_WCARD_LCOMP : 0))); + UCF_ALWAYS_ALLOW_WCARD_LCOMP : + 0))); /* If an error we expect this to be * NT_STATUS_OBJECT_PATH_NOT_FOUND */ -- cgit