The branch, master has been updated via cd5133b1127579fa47152e4c38f4a6534bdf37c7 (commit) via 10324b177ed2c5de07039f035905b8272f51fbf7 (commit) from c472bca42c587d46bd9d11a1c02fe53808cee08e (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit cd5133b1127579fa47152e4c38f4a6534bdf37c7 Author: Tim Prouty <tpro...@samba.org> Date: Fri Jul 24 11:39:56 2009 -0700 s3: Simplify rename_internals() by passing in smb_filename structs commit 10324b177ed2c5de07039f035905b8272f51fbf7 Author: Tim Prouty <tpro...@samba.org> Date: Fri Jul 24 12:13:07 2009 -0700 s3: Allow filename_convert() to pass through unix_convert_flags and let the caller know if the path has a wildcard This also eliminates the need for resolve_dfspath(). ----------------------------------------------------------------------- Summary of changes: source3/include/proto.h | 6 +- source3/rpc_server/srv_srvsvc_nt.c | 4 + source3/smbd/filename.c | 41 ++++++++++-- source3/smbd/msdfs.c | 45 +++---------- source3/smbd/nttrans.c | 121 +++++++++++++++++------------------- source3/smbd/reply.c | 106 ++++++++++++++++--------------- source3/smbd/smb2_create.c | 2 + source3/smbd/trans2.c | 81 ++++++++++++++---------- 8 files changed, 211 insertions(+), 195 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/include/proto.h b/source3/include/proto.h index 63a82a8..a79c7eb 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6320,6 +6320,8 @@ NTSTATUS filename_convert(TALLOC_CTX *mem_ctx, connection_struct *conn, bool dfs_path, const char *name_in, + uint32_t ucf_flags, + bool *ppath_contains_wcard, struct smb_filename **pp_smb_fname); /* The following definitions come from smbd/filename_utils.c */ @@ -6882,8 +6884,8 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, NTSTATUS rename_internals(TALLOC_CTX *ctx, connection_struct *conn, struct smb_request *req, - const char *name_in, - const char *newname_in, + struct smb_filename *smb_fname_src, + struct smb_filename *smb_fname_dst, uint32 attrs, bool replace_if_exists, bool src_has_wild, diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index b9d1ed6..15b2290 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -2072,6 +2072,8 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, conn, false, r->in.file, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(nt_status)) { werr = ntstatus_to_werror(nt_status); @@ -2200,6 +2202,8 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, conn, false, r->in.file, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(nt_status)) { werr = ntstatus_to_werror(nt_status); diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 09f9a41..a13c66c 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -1027,14 +1027,30 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx, return status; } -/**************************************************************************** - Go through all the steps to validate a filename. -****************************************************************************/ - +/** + * Go through all the steps to validate a filename. + * + * @param ctx talloc_ctx to allocate memory with. + * @param conn connection struct for vfs calls. + * @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. + * @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 + * return is NT_STATUS_OK. + * + * @return NT_STATUS_OK if all operations completed succesfully, appropriate + * error otherwise. + */ NTSTATUS filename_convert(TALLOC_CTX *ctx, connection_struct *conn, bool dfs_path, const char *name_in, + uint32_t ucf_flags, + bool *ppath_contains_wcard, struct smb_filename **pp_smb_fname) { NTSTATUS status; @@ -1042,10 +1058,11 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, *pp_smb_fname = NULL; - status = resolve_dfspath(ctx, conn, + status = resolve_dfspath_wcard(ctx, conn, dfs_path, name_in, - &fname); + &fname, + ppath_contains_wcard); if (!NT_STATUS_IS_OK(status)) { DEBUG(10,("filename_convert: resolve_dfspath failed " "for name %s with %s\n", @@ -1053,7 +1070,17 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, nt_errstr(status) )); return status; } - status = unix_convert(ctx, conn, fname, pp_smb_fname, 0); + + /* + * Strip out the UCF_ALLOW_WCARD_LCOMP if the path doesn't contain a + * wildcard. + */ + if (ppath_contains_wcard != NULL && !*ppath_contains_wcard && + ucf_flags & UCF_ALLOW_WCARD_LCOMP) { + ucf_flags &= ~UCF_ALLOW_WCARD_LCOMP; + } + + status = unix_convert(ctx, conn, fname, pp_smb_fname, ucf_flags); if (!NT_STATUS_IS_OK(status)) { DEBUG(10,("filename_convert: unix_convert failed " "for name %s with %s\n", diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index 2b63eb1..3641e8d 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -1718,40 +1718,9 @@ struct junction_map *enum_msdfs_links(TALLOC_CTX *ctx, size_t *p_num_jn) } /****************************************************************************** - Core function to resolve a dfs pathname. -******************************************************************************/ - -NTSTATUS resolve_dfspath(TALLOC_CTX *ctx, - connection_struct *conn, - bool dfs_pathnames, - const char *name_in, - char **pp_name_out) -{ - NTSTATUS status = NT_STATUS_OK; - bool dummy; - if (dfs_pathnames) { - status = dfs_redirect(ctx, - conn, - name_in, - False, - pp_name_out, - &dummy); - } else { - /* - * Cheat and just return a copy of the in ptr. - * Once srvstr_get_path() uses talloc it'll - * be a talloced ptr anyway. - */ - *pp_name_out = CONST_DISCARD(char *,name_in); - } - return status; -} - -/****************************************************************************** - Core function to resolve a dfs pathname possibly containing a wildcard. - This function is identical to the above except for the bool param to - dfs_redirect but I need this to be separate so it's really clear when - we're allowing wildcards and when we're not. JRA. + Core function to resolve a dfs pathname possibly containing a wildcard. If + ppath_contains_wcard != NULL, it will be set to true if a wildcard is + detected during dfs resolution. ******************************************************************************/ NTSTATUS resolve_dfspath_wcard(TALLOC_CTX *ctx, @@ -1761,14 +1730,20 @@ NTSTATUS resolve_dfspath_wcard(TALLOC_CTX *ctx, char **pp_name_out, bool *ppath_contains_wcard) { + bool path_contains_wcard; NTSTATUS status = NT_STATUS_OK; + if (dfs_pathnames) { status = dfs_redirect(ctx, conn, name_in, True, pp_name_out, - ppath_contains_wcard); + &path_contains_wcard); + + if (NT_STATUS_IS_OK(status) && ppath_contains_wcard != NULL) { + *ppath_contains_wcard = path_contains_wcard; + } } else { /* * Cheat and just return a copy of the in ptr. diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 43212dc..dd4ef97 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -478,6 +478,8 @@ void reply_ntcreate_and_X(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { @@ -967,6 +969,8 @@ static void call_nt_transact_create(connection_struct *conn, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { @@ -1308,6 +1312,8 @@ void reply_ntrename(struct smb_request *req) bool src_has_wcard = False; bool dest_has_wcard = False; uint32 attrs; + uint32_t ucf_flags_src = 0; + uint32_t ucf_flags_dst = 0; uint16 rename_type; TALLOC_CTX *ctx = talloc_tos(); @@ -1348,87 +1354,72 @@ void reply_ntrename(struct smb_request *req) goto out; } + /* + * If this is a rename operation, allow wildcards and save the + * 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; + } + /* rename_internals() calls unix_convert(), so don't call it here. */ - if (rename_type != RENAME_FLAG_RENAME) { - status = filename_convert(ctx, conn, - req->flags2 & FLAGS2_DFS_PATHNAMES, - oldname, - &smb_fname_old); - 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); - goto out; - } - reply_nterror(req, status); + status = filename_convert(ctx, conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + oldname, + ucf_flags_src, + NULL, + &smb_fname_old); + 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); goto out; } + reply_nterror(req, status); + goto out; + } - status = filename_convert(ctx, conn, - req->flags2 & FLAGS2_DFS_PATHNAMES, - newname, - &smb_fname_new); - 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); - goto out; - } - reply_nterror(req, status); + status = filename_convert(ctx, conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + newname, + ucf_flags_dst, + &dest_has_wcard, + &smb_fname_new); + 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); goto out; } - - DEBUG(3,("reply_ntrename: %s -> %s\n", - smb_fname_str_dbg(smb_fname_old), - smb_fname_str_dbg(smb_fname_new))); + reply_nterror(req, status); + goto out; } + DEBUG(3,("reply_ntrename: %s -> %s\n", + smb_fname_str_dbg(smb_fname_old), + smb_fname_str_dbg(smb_fname_new))); + switch(rename_type) { case RENAME_FLAG_RENAME: - status = resolve_dfspath(ctx, conn, - (req->flags2 & - FLAGS2_DFS_PATHNAMES), - oldname, &oldname); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10,("resolve_dfspath failed for name %s " - "with %s\n", oldname, - nt_errstr(status))); - reply_nterror(req, status); - goto out; - } - - status = resolve_dfspath(ctx, conn, - (req->flags2 & - FLAGS2_DFS_PATHNAMES), - newname, &newname); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10,("resolve_dfspath failed for name %s " - "with %s\n", newname, - nt_errstr(status))); - reply_nterror(req, status); - goto out; - } - - DEBUG(3,("reply_ntrename: %s -> %s\n", oldname, - newname)); - - status = rename_internals(ctx, conn, req, oldname, - newname, attrs, False, src_has_wcard, - dest_has_wcard, DELETE_ACCESS); + status = rename_internals(ctx, conn, req, + smb_fname_old, smb_fname_new, + attrs, False, src_has_wcard, + dest_has_wcard, + DELETE_ACCESS); break; case RENAME_FLAG_HARD_LINK: if (src_has_wcard || dest_has_wcard) { /* No wildcards. */ status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD; } else { - status = hardlink_internals(ctx, - conn, - smb_fname_old, - smb_fname_new); + status = hardlink_internals(ctx, conn, + smb_fname_old, + smb_fname_new); } break; case RENAME_FLAG_COPY: diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 76d32a2..03bca82 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -994,6 +994,8 @@ void reply_checkpath(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, name, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { @@ -1090,6 +1092,8 @@ void reply_getatr(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -1191,6 +1195,8 @@ void reply_setatr(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -1724,6 +1730,8 @@ void reply_open(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -1894,6 +1902,8 @@ void reply_open_and_X(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -2103,6 +2113,8 @@ void reply_mknew(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -2235,6 +2247,8 @@ void reply_ctemp(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -5240,6 +5254,8 @@ void reply_mkdir(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, directory, + 0, + NULL, &smb_dname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -5547,6 +5563,8 @@ void reply_rmdir(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, directory, + 0, + NULL, &smb_dname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -6119,16 +6137,14 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, NTSTATUS rename_internals(TALLOC_CTX *ctx, connection_struct *conn, struct smb_request *req, - const char *name_in, - const char *newname_in, + struct smb_filename *smb_fname_src, + struct smb_filename *smb_fname_dst, uint32 attrs, bool replace_if_exists, bool src_has_wild, bool dest_has_wild, uint32_t access_mask) { - struct smb_filename *smb_fname_src = NULL; - struct smb_filename *smb_fname_dst = NULL; char *fname_src_dir = NULL; char *fname_src_mask = NULL; int count=0; @@ -6139,19 +6155,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, int create_options = 0; bool posix_pathnames = lp_posix_pathnames(); - status = unix_convert(ctx, conn, name_in, &smb_fname_src, - src_has_wild ? UCF_ALLOW_WCARD_LCOMP : 0); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - - status = unix_convert(ctx, conn, newname_in, &smb_fname_dst, - (UCF_SAVE_LCOMP | - (dest_has_wild ? UCF_ALLOW_WCARD_LCOMP : 0))); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - /* * Split the old name into directory and last component * strings. Note that unix_convert may have stripped off a @@ -6452,8 +6455,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, } out: - TALLOC_FREE(smb_fname_src); - TALLOC_FREE(smb_fname_dst); TALLOC_FREE(fname_src_dir); TALLOC_FREE(fname_src_mask); return status; @@ -6474,13 +6475,14 @@ void reply_mv(struct smb_request *req) bool src_has_wcard = False; bool dest_has_wcard = False; TALLOC_CTX *ctx = talloc_tos(); + struct smb_filename *smb_fname_src = NULL; + struct smb_filename *smb_fname_dst = NULL; START_PROFILE(SMBmv); if (req->wct < 1) { -- Samba Shared Repository