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/include/proto.h | 3 +- source3/include/smb.h | 3 +- source3/printing/nt_printing.c | 28 +++++++++-- 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 ++++------- 8 files changed, 90 insertions(+), 112 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 92386f5fae..aed2c4c0f7 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6846,7 +6846,8 @@ void reply_ulogoffX(struct smb_request *req); void reply_mknew(struct smb_request *req); void reply_ctemp(struct smb_request *req); 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); void reply_unlink(struct smb_request *req); void reply_readbraw(struct smb_request *req); void reply_lockread(struct smb_request *req); diff --git a/source3/include/smb.h b/source3/include/smb.h index 1c4ac54722..6ccdd968a3 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1900,7 +1900,8 @@ struct smb_file_time { * unix_convert_flags */ #define UCF_SAVE_LCOMP 0x00000001 -#define UCF_ALLOW_WCARD_LCOMP 0x00000002 +#define UCF_ALWAYS_ALLOW_WCARD_LCOMP 0x00000002 +#define UCF_COND_ALLOW_WCARD_LCOMP 0x00000004 /* * smb_filename diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 3e206becf4..26b8d9d81d 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -5145,6 +5145,24 @@ bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) return in_use; } +static NTSTATUS driver_unlink_internals(connection_struct *conn, + const char *name) +{ + struct smb_filename *smb_fname = NULL; + NTSTATUS status; + + status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = unlink_internals(conn, NULL, 0, smb_fname, false); + + TALLOC_FREE(smb_fname); + return status; +} + /**************************************************************************** Actually delete the driver files. Make sure that printer_driver_files_in_use() return False before calling @@ -5197,7 +5215,7 @@ static bool delete_driver_files(struct pipes_struct *rpc_pipe, if ( (s = strchr( &info_3->driverpath[1], '\\' )) != NULL ) { file = s; DEBUG(10,("deleting driverfile [%s]\n", s)); - unlink_internals(conn, NULL, 0, file, False); + driver_unlink_internals(conn, file); } } @@ -5205,7 +5223,7 @@ static bool delete_driver_files(struct pipes_struct *rpc_pipe, if ( (s = strchr( &info_3->configfile[1], '\\' )) != NULL ) { file = s; DEBUG(10,("deleting configfile [%s]\n", s)); - unlink_internals(conn, NULL, 0, file, False); + driver_unlink_internals(conn, file); } } @@ -5213,7 +5231,7 @@ static bool delete_driver_files(struct pipes_struct *rpc_pipe, if ( (s = strchr( &info_3->datafile[1], '\\' )) != NULL ) { file = s; DEBUG(10,("deleting datafile [%s]\n", s)); - unlink_internals(conn, NULL, 0, file, False); + driver_unlink_internals(conn, file); } } @@ -5221,7 +5239,7 @@ static bool delete_driver_files(struct pipes_struct *rpc_pipe, if ( (s = strchr( &info_3->helpfile[1], '\\' )) != NULL ) { file = s; DEBUG(10,("deleting helpfile [%s]\n", s)); - unlink_internals(conn, NULL, 0, file, False); + driver_unlink_internals(conn, file); } } @@ -5236,7 +5254,7 @@ static bool delete_driver_files(struct pipes_struct *rpc_pipe, if ( (p = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) { file = p; DEBUG(10,("deleting dependent file [%s]\n", file)); - unlink_internals(conn, NULL, 0, file, False); + driver_unlink_internals(conn, file); } i++; 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