The branch, master has been updated via 78e4aac76df s3: smbd: Remove unix_convert() and associated functions. via cc638c25e03 s3: smbd: Remove the old dfs_path_lookup() code. via 88e8bfec594 s3: smbd: Switch get_referred_path() over to use the new dfs_path_lookup(). via 22d4f625371 s3: smbd: Add new version of dfs_path_lookup() that uses filename_convert_dirfsp(). via 6b1224b2201 s3: smbd: Remove dfs_redirect(). via d20b60c3200 s3: smbd: Remove call to dfs_redirect() from filename_convert_dirfsp_nosymlink(). via fcf19d91c09 s3: smbd: Remove call to dfs_redirect() from filename_convert_smb1_search_path(). via d80bedc3c41 s3: smbd: In filename_convert_dirfsp_nosymlink(), cope with an MS-DFS link as the terminal component. via 07ef9e3029b s3: smbd: In filename_convert_dirfsp_nosymlink(), allow a NT_STATUS_PATH_NOT_COVERED error to be returned. via b5f68095935 s3: smbd: Allow openat_pathref_dirfsp_nosymlink() to return NT_STATUS_PATH_NOT_COVERED for a DFS link on a DFS share. via a92f4f7af0e s3: smbd: In get create_junction(), make sure check_path_syntax() is called on returned reqpath. via da625e4ab4b s3: smbd: In get referred_path(), make sure check_path_syntax() is called on returned reqpath. via 245d07ab848 s3: smbd: Add dfs_filename_convert(). Simple wrapper around parse_dfs_path(). via a3c9eb7931c s3: smbd: Use helper function msdfs_servicename_matches_connection() in dfs_redirect(). via c0a1d7c7a8a s3: smbd: Use helper function msdfs_servicename_matches_connection() in parse_dfs_path(). via 4f5d02f8c0e s3: smbd: Add helper function msdfs_servicename_matches_connection(). via 6c83c674bab s3: smbd: Remove definition of struct dfs_path. via f92711f000a s3: smbd: Remove use of 'struct dfs_path'. Not needed for a (hostname, servicename, path) tuple. via 2df8a8ab87a s3: smbd: Add TALLOC_CTX * parameter to parse_dfs_path(). via 0a4a27ce48b s3: smbd: Ensure smb2_file_rename_information() uses the SMB2 pathname parsers, not the SMB1 parsers. via a2a097fc3d6 s3: smbd: Make sure we have identical check_path_syntax logic in smbd_smb2_create_durable_lease_check(), as for smb2_create. via 4fafc341893 s3: smbd: In smbd_smb2_create_send() call the helper function check_path_syntax_smb2(). via 7bd7fa0a0b4 s3: smbd: Add helper function check_path_syntax_smb2(). via bcba5502282 s3: smbd: Add new function check_path_syntax_smb2_msdfs() for SMB2 MSDFS paths. via 2818fd69102 s3: smbd: Fix cosmetic bug logging pathnames from Linux kernel clients using SMB1 DFS calls. from 23988f19e7c s4:torture/smb2: add smb2.bench.echo
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 78e4aac76df977cea6cdbcfdf082fd3acdffbd95 Author: Jeremy Allison <j...@samba.org> Date: Mon Aug 8 21:59:14 2022 -0700 s3: smbd: Remove unix_convert() and associated functions. All code now uses filename_convert_dirfsp() for race-free filename conversion. Best viewed with: $ git show --patience ---------------- / \ / REST \ / IN \ / PEACE \ / \ | | | unix_convert | | | | | | 9th August | | 2022 | | | | | *| * * * | * _________)/\\_//(\/(/\)/\//\/\///\/|_)_______ BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Fri Aug 12 19:18:25 UTC 2022 on sn-devel-184 commit cc638c25e0332d366016880d174d9349940cba3f Author: Jeremy Allison <j...@samba.org> Date: Tue Aug 9 12:13:10 2022 -0700 s3: smbd: Remove the old dfs_path_lookup() code. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 88e8bfec59412fdc0e83251fef60b45d2cc3a884 Author: Jeremy Allison <j...@samba.org> Date: Tue Aug 9 12:11:07 2022 -0700 s3: smbd: Switch get_referred_path() over to use the new dfs_path_lookup(). New function doesn't need a TWRP argument and returns NT_STATUS_OK on successful redirect, not NT_STATUS_PATH_NOT_COVERED. Comment out the old dfs_path_lookup(). There are now no more users of unix_convert(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 22d4f62537199d9454be312a546e251f04022497 Author: Jeremy Allison <j...@samba.org> Date: Tue Aug 9 12:07:30 2022 -0700 s3: smbd: Add new version of dfs_path_lookup() that uses filename_convert_dirfsp(). Commented out as not yet used but it's easier to see the new logic this way. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 6b1224b22012b54b1ae20b682daf61c877362a7b Author: Jeremy Allison <j...@samba.org> Date: Wed Aug 10 11:34:24 2022 -0700 s3: smbd: Remove dfs_redirect(). A moment of silence please. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit d20b60c3200b5e1881cdf4b59da154d1af7e3994 Author: Jeremy Allison <j...@samba.org> Date: Wed Aug 10 11:32:30 2022 -0700 s3: smbd: Remove call to dfs_redirect() from filename_convert_dirfsp_nosymlink(). Use dfs_filename_convert() instead. There are now no more callers of dfs_redirect(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit fcf19d91c09edc6dfbf5bd7cbeedcd641030eb31 Author: Jeremy Allison <j...@samba.org> Date: Wed Aug 10 11:29:33 2022 -0700 s3: smbd: Remove call to dfs_redirect() from filename_convert_smb1_search_path(). Use dfs_filename_convert() instead. Code is now much simpler. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit d80bedc3c418b6839b1bde78ba8d3db06611be2a Author: Jeremy Allison <j...@samba.org> Date: Mon Aug 8 13:18:56 2022 -0700 s3: smbd: In filename_convert_dirfsp_nosymlink(), cope with an MS-DFS link as the terminal component. If the terminal component was an MSDFS link, openat_pathref_fsp_case_insensitive() will return NT_STATUS_OBJECT_NAME_NOT_FOUND with a VALID_STAT of a symlink. If this is the case, check if we actually found a terminal MS-DFS link at the end of the pathname and return NT_STATUS_PATH_NOT_COVERED. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 07ef9e3029b8cca1b92d900d6ed684ca0ac6afe4 Author: Jeremy Allison <j...@samba.org> Date: Mon Aug 8 13:15:17 2022 -0700 s3: smbd: In filename_convert_dirfsp_nosymlink(), allow a NT_STATUS_PATH_NOT_COVERED error to be returned. openat_pathref_dirfsp_nosymlink() can now return NT_STATUS_PATH_NOT_COVERED. Don't convert this automatically into NT_STATUS_OBJECT_PATH_NOT_FOUND. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit b5f6809593524e7e9aca1c09ff379e02a1cde61b Author: Jeremy Allison <j...@samba.org> Date: Mon Aug 8 11:31:39 2022 -0700 s3: smbd: Allow openat_pathref_dirfsp_nosymlink() to return NT_STATUS_PATH_NOT_COVERED for a DFS link on a DFS share. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit a92f4f7af0eaa035deebfb1c930ca0cc12d992d5 Author: Jeremy Allison <j...@samba.org> Date: Thu Aug 11 23:57:51 2022 -0700 s3: smbd: In get create_junction(), make sure check_path_syntax() is called on returned reqpath. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit da625e4ab4bc670e44fcb6ad7456aa64d0f1f9d2 Author: Jeremy Allison <j...@samba.org> Date: Thu Aug 11 23:55:58 2022 -0700 s3: smbd: In get referred_path(), make sure check_path_syntax() is called on returned reqpath. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 245d07ab84852b829c029496618e56782d070e83 Author: Jeremy Allison <j...@samba.org> Date: Mon Aug 8 11:16:17 2022 -0700 s3: smbd: Add dfs_filename_convert(). Simple wrapper around parse_dfs_path(). Not yet used. This is what we will use to replace dfs_redirect() in the filename conversion code. Keep as a wrapper for now as we might want to add some error checking around the 'hostname' and 'service' returns. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit a3c9eb7931cb4da0dd5bc5d600125979dd1a7df5 Author: Jeremy Allison <j...@samba.org> Date: Tue Aug 9 10:58:24 2022 -0700 s3: smbd: Use helper function msdfs_servicename_matches_connection() in dfs_redirect(). Replaces ugly complex logic. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit c0a1d7c7a8a7f24890e60c7a371498949dec11c2 Author: Jeremy Allison <j...@samba.org> Date: Tue Aug 9 10:53:18 2022 -0700 s3: smbd: Use helper function msdfs_servicename_matches_connection() in parse_dfs_path(). Replaces ugly complex logic. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 4f5d02f8c0efc1520b2113ce656c78483deb7826 Author: Jeremy Allison <j...@samba.org> Date: Tue Aug 9 10:49:46 2022 -0700 s3: smbd: Add helper function msdfs_servicename_matches_connection(). Not yet used so commented out. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 6c83c674bab8e57ecaf6271eb3a403171bbbacca Author: Jeremy Allison <j...@samba.org> Date: Mon Aug 8 10:27:16 2022 -0700 s3: smbd: Remove definition of struct dfs_path. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit f92711f000a3cb658dfb8fffe92ae6bba78b4f91 Author: Jeremy Allison <j...@samba.org> Date: Wed Aug 10 11:17:49 2022 -0700 s3: smbd: Remove use of 'struct dfs_path'. Not needed for a (hostname, servicename, path) tuple. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 2df8a8ab87a1372f2b67880be4454a0285b3104b Author: Jeremy Allison <j...@samba.org> Date: Wed Aug 10 11:06:47 2022 -0700 s3: smbd: Add TALLOC_CTX * parameter to parse_dfs_path(). Not yet used. Preparing to remove 'struct dfs_path'. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 0a4a27ce48bc7090aa821eea5e56f8d44c686716 Author: Jeremy Allison <j...@samba.org> Date: Tue Aug 9 10:43:45 2022 -0700 s3: smbd: Ensure smb2_file_rename_information() uses the SMB2 pathname parsers, not the SMB1 parsers. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit a2a097fc3d6a89fb970c1ea3ea75fde93ddb545e Author: Jeremy Allison <j...@samba.org> Date: Tue Aug 9 10:41:39 2022 -0700 s3: smbd: Make sure we have identical check_path_syntax logic in smbd_smb2_create_durable_lease_check(), as for smb2_create. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 4fafc3418931de06ea2d91baca1eef8d904cc4e6 Author: Jeremy Allison <j...@samba.org> Date: Tue Aug 9 10:39:41 2022 -0700 s3: smbd: In smbd_smb2_create_send() call the helper function check_path_syntax_smb2(). Previously for DFS names we were skipping this. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 7bd7fa0a0b46ad6826097a1987595e2ab6f83384 Author: Jeremy Allison <j...@samba.org> Date: Tue Aug 9 10:36:00 2022 -0700 s3: smbd: Add helper function check_path_syntax_smb2(). Not yet used, but uses check_path_syntax_smb2_msdfs() so remove the #ifdef's around that. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit bcba5502282eb6dcc346d7c63aa3218cda2f9bb0 Author: Jeremy Allison <j...@samba.org> Date: Fri Aug 5 12:16:44 2022 -0700 s3: smbd: Add new function check_path_syntax_smb2_msdfs() for SMB2 MSDFS paths. #ifdef'ed out as static and not yet used. We can't just call check_path_syntax() on these as they are of the form hostname\share[\extrapath] (where [\extrapath] is optional). hostname here can be an IPv6 ':' separated address, which check_path_syntax() fails on due to the streamname processing. NB. This also has to cope with out existing (broken) libsmbclient libraries that sometimes set the DFS flag and then send a local pathname. Cope by just calling the normal check_path_syntax() on the whole pathname in that case. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 2818fd6910201fd4a18b921933a0b7392a0a8995 Author: Jeremy Allison <j...@samba.org> Date: Fri Aug 5 19:27:33 2022 -0700 s3: smbd: Fix cosmetic bug logging pathnames from Linux kernel clients using SMB1 DFS calls. The Linux kernel SMB1 client has a bug - it sends DFS pathnames as: \\server\share\path instead of: \server\share\path Causing us to mis-parse server,share,remaining_path here and jump into 'goto local_path' at 'share\path' instead of 'path'. This doesn't cause an error as the limits on share names are similar to those on pathnames. parse_dfs_path() which we call before filename parsing copes with this by calling trim_char on the leading '\' characters before processing. Do the same here so logging of pathnames looks better. How did I find this ? Lots and lots of manual testing with the Linux kernel client to make sure all the recent changes haven't broken Linux SMB1/2/3 DFS :-). BUG: https://bugzilla.samba.org/show_bug.cgi?id=15144 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> ----------------------------------------------------------------------- Summary of changes: source3/include/msdfs.h | 7 - source3/smbd/filename.c | 1627 ++++---------------------------------------- source3/smbd/files.c | 12 + source3/smbd/msdfs.c | 714 ++++++++++--------- source3/smbd/proto.h | 25 +- source3/smbd/smb2_create.c | 21 +- source3/smbd/smb2_reply.c | 68 ++ source3/smbd/smb2_trans2.c | 30 +- 8 files changed, 625 insertions(+), 1879 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/include/msdfs.h b/source3/include/msdfs.h index 83265174373..892343fdd9a 100644 --- a/source3/include/msdfs.h +++ b/source3/include/msdfs.h @@ -56,11 +56,4 @@ struct junction_map { size_t referral_count; struct referral* referral_list; }; - -struct dfs_path { - char *hostname; - char *servicename; - char *reqpath; -}; - #endif /* _MSDFS_H */ diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 87abc8be376..f362aee9452 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -31,15 +31,6 @@ #include "smbd/globals.h" #include "lib/util/memcache.h" -static NTSTATUS get_real_filename(connection_struct *conn, - struct smb_filename *path, - const char *name, - TALLOC_CTX *mem_ctx, - char **found_name); - -static NTSTATUS check_name(connection_struct *conn, - const struct smb_filename *smb_fname); - uint32_t ucf_flags_from_smb_request(struct smb_request *req) { uint32_t ucf_flags = 0; @@ -80,10 +71,6 @@ uint32_t filename_create_ucf_flags(struct smb_request *req, uint32_t create_disp return ucf_flags; } -static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx, - connection_struct *conn, - struct smb_filename *smb_fname); - /**************************************************************************** Mangle the 2nd name and check if it is then equal to the first name. ****************************************************************************/ @@ -100,153 +87,6 @@ static bool mangled_equal(const char *name1, return strequal(name1, mname); } -static NTSTATUS check_for_dot_component(const struct smb_filename *smb_fname) -{ - /* Ensure we catch all names with in "/." - this is disallowed under Windows and - in POSIX they've already been removed. */ - const char *p = strstr(smb_fname->base_name, "/."); /*mb safe*/ - if (p) { - if (p[2] == '/') { - /* Error code within a pathname. */ - return NT_STATUS_OBJECT_PATH_NOT_FOUND; - } else if (p[2] == '\0') { - /* Error code at the end of a pathname. */ - return NT_STATUS_OBJECT_NAME_INVALID; - } - } - return NT_STATUS_OK; -} - -/**************************************************************************** - Optimization for common case where the missing part - is in the last component and the client already - sent the correct case. - Returns NT_STATUS_OK to mean continue the tree walk - (possibly with modified start pointer). - Any other NT_STATUS_XXX error means terminate the path - lookup here. -****************************************************************************/ - -static NTSTATUS check_parent_exists(TALLOC_CTX *ctx, - connection_struct *conn, - bool posix_pathnames, - const struct smb_filename *smb_fname, - char **pp_dirpath, - char **pp_start, - int *p_parent_stat_errno) -{ - char *parent_name = NULL; - struct smb_filename *parent_fname = NULL; - const char *last_component = NULL; - NTSTATUS status; - int ret; - - if (!parent_dirname(ctx, smb_fname->base_name, - &parent_name, - &last_component)) { - return NT_STATUS_NO_MEMORY; - } - - if (!posix_pathnames) { - if (ms_has_wild(parent_name)) { - goto no_optimization_out; - } - } - - /* - * If there was no parent component in - * smb_fname->base_name then don't do this - * optimization. - */ - if (smb_fname->base_name == last_component) { - goto no_optimization_out; - } - - parent_fname = synthetic_smb_fname(ctx, - parent_name, - NULL, - NULL, - smb_fname->twrp, - smb_fname->flags); - if (parent_fname == NULL) { - return NT_STATUS_NO_MEMORY; - } - - ret = vfs_stat(conn, parent_fname); - - /* If the parent stat failed, just continue - with the normal tree walk. */ - - if (ret == -1) { - /* - * Optimization. Preserving the - * errno from the STAT/LSTAT here - * will allow us to save a duplicate - * STAT/LSTAT system call of the parent - * pathname in a hot code path in the caller. - */ - if (p_parent_stat_errno != NULL) { - *p_parent_stat_errno = errno; - } - goto no_optimization_out; - } - - status = check_for_dot_component(parent_fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - /* Parent exists - set "start" to be the - * last component to shorten the tree walk. */ - - /* - * Safe to use discard_const_p - * here as last_component points - * into our smb_fname->base_name. - */ - *pp_start = discard_const_p(char, last_component); - - /* Update dirpath. */ - TALLOC_FREE(*pp_dirpath); - *pp_dirpath = talloc_strdup(ctx, parent_fname->base_name); - if (!*pp_dirpath) { - return NT_STATUS_NO_MEMORY; - } - - DEBUG(5,("check_parent_exists: name " - "= %s, dirpath = %s, " - "start = %s\n", - smb_fname->base_name, - *pp_dirpath, - *pp_start)); - - return NT_STATUS_OK; - - no_optimization_out: - - /* - * We must still return an *pp_dirpath - * initialized to ".", and a *pp_start - * pointing at smb_fname->base_name. - */ - - TALLOC_FREE(parent_name); - TALLOC_FREE(parent_fname); - - *pp_dirpath = talloc_strdup(ctx, "."); - if (*pp_dirpath == NULL) { - return NT_STATUS_NO_MEMORY; - } - /* - * Safe to use discard_const_p - * here as by convention smb_fname->base_name - * is allocated off ctx. - */ - *pp_start = discard_const_p(char, smb_fname->base_name); - return NT_STATUS_OK; -} - static bool find_snapshot_token( const char *filename, const char **_start, @@ -288,1105 +128,115 @@ static bool find_snapshot_token( unix_to_nt_time(twrp, t); DBG_DEBUG("Extracted @GMT-Timestamp %s\n", - nt_time_string(talloc_tos(), *twrp)); - - *_start = start; - - if (end[0] == '/') { - end += 1; - } - *_next_component = end; - - return true; -} - -bool extract_snapshot_token(char *fname, NTTIME *twrp) -{ - const char *start = NULL; - const char *next = NULL; - size_t remaining; - bool found; - - found = find_snapshot_token(fname, &start, &next, twrp); - if (!found) { - return false; - } - - remaining = strlen(next); - memmove(discard_const_p(char, start), next, remaining+1); - - return true; -} - -/* - * Strip a valid @GMT-token from any incoming filename path, - * adding any NTTIME encoded in the pathname into the - * twrp field of the passed in smb_fname. - * - * Valid @GMT-tokens look like @GMT-YYYY-MM-DD-HH-MM-SS - * at the *start* of a pathname component. - * - * If twrp is passed in then smb_fname->twrp is set to that - * value, and the @GMT-token part of the filename is removed - * and does not change the stored smb_fname->twrp. - * - */ - -NTSTATUS canonicalize_snapshot_path(struct smb_filename *smb_fname, - uint32_t ucf_flags, - NTTIME twrp) -{ - bool found; - - if (twrp != 0) { - smb_fname->twrp = twrp; - } - - if (!(ucf_flags & UCF_GMT_PATHNAME)) { - return NT_STATUS_OK; - } - - found = extract_snapshot_token(smb_fname->base_name, &twrp); - if (!found) { - return NT_STATUS_OK; - } - - if (smb_fname->twrp == 0) { - smb_fname->twrp = twrp; - } - - return NT_STATUS_OK; -} - -static bool strnorm(char *s, int case_default) -{ - if (case_default == CASE_UPPER) - return strupper_m(s); - else - return strlower_m(s); -} - -/* - * Utility function to normalize case on an incoming client filename - * if required on this connection struct. - * Performs an in-place case conversion guaranteed to stay the same size. - */ - -static NTSTATUS normalize_filename_case(connection_struct *conn, - char *filename, - uint32_t ucf_flags) -{ - bool ok; - - if (ucf_flags & UCF_POSIX_PATHNAMES) { - /* - * POSIX never normalizes filename case. - */ - return NT_STATUS_OK; - } - if (!conn->case_sensitive) { - return NT_STATUS_OK; - } - if (conn->case_preserve) { - return NT_STATUS_OK; - } - if (conn->short_case_preserve) { - return NT_STATUS_OK; - } - ok = strnorm(filename, lp_default_case(SNUM(conn))); - if (!ok) { - return NT_STATUS_INVALID_PARAMETER; - } - return NT_STATUS_OK; -} - -/**************************************************************************** -This routine is called to convert names from the dos namespace to unix -namespace. It needs to handle any case conversions, mangling, format changes, -streams etc. - -We assume that we have already done a chdir() to the right "root" directory -for this service. - -Conversion to basic unix format is already done in check_path_syntax(). - -Names must be relative to the root of the service - any leading /. and -trailing /'s should have been trimmed by check_path_syntax(). - -The function will return an NTSTATUS error if some part of the name except for -the last part cannot be resolved, else NT_STATUS_OK. - -Note NT_STATUS_OK doesn't mean the name exists or is valid, just that we -didn't get any fatal errors that should immediately terminate the calling SMB -processing whilst resolving. - -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 -orig_path was not a stream, then smb_filename->stream_name will be NULL. - -On exit from unix_convert, the smb_filename->st stat struct will be populated -if the file exists and was found, if not this stat struct will be filled with -zeros (and this can be detected by checking for nlinks = 0, which can never be -true for any file). -****************************************************************************/ - -struct uc_state { - TALLOC_CTX *mem_ctx; - struct connection_struct *conn; - struct smb_filename *smb_fname; - const char *orig_path; - uint32_t ucf_flags; - char *name; - char *end; - char *dirpath; - char *stream; - bool component_was_mangled; - bool posix_pathnames; - bool done; - bool case_sensitive; - bool case_preserve; - bool short_case_preserve; -}; - -static NTSTATUS unix_convert_step_search_fail( - struct uc_state *state, NTSTATUS status) -{ - char *unmangled; - - if (state->end) { - /* - * An intermediate part of the name - * can't be found. - */ - DBG_DEBUG("Intermediate [%s] missing\n", - state->name); - *state->end = '/'; - - /* - * We need to return the fact that the - * intermediate name resolution failed. - * This is used to return an error of - * ERRbadpath rather than ERRbadfile. - * Some Windows applications depend on - * the difference between these two - * errors. - */ - - /* - * ENOENT, ENOTDIR and ELOOP all map - * to NT_STATUS_OBJECT_PATH_NOT_FOUND - * in the filename walk. - */ - if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) || - NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK) || - NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) { - status = NT_STATUS_OBJECT_PATH_NOT_FOUND; - } - return status; - } - - /* - * ENOENT/EACCESS are the only valid errors - * here. - */ - - if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { - if ((state->ucf_flags & UCF_PREP_CREATEFILE) == 0) { - /* - * Could be a symlink pointing to - * a directory outside the share - * to which we don't have access. - * If so, we need to know that here - * so we can return the correct error code. - * check_name() is never called if we - * error out of filename_convert(). - */ - int ret; - struct smb_filename dname = (struct smb_filename) { - .base_name = state->dirpath, - .twrp = state->smb_fname->twrp, - }; - - /* handle null paths */ - if ((dname.base_name == NULL) || - (dname.base_name[0] == '\0')) { - return NT_STATUS_ACCESS_DENIED; - } - ret = SMB_VFS_LSTAT(state->conn, &dname); - if (ret != 0) { - return NT_STATUS_ACCESS_DENIED; - } - if (!S_ISLNK(dname.st.st_ex_mode)) { - return NT_STATUS_ACCESS_DENIED; - } - status = check_name(state->conn, &dname); - if (!NT_STATUS_IS_OK(status)) { - /* We know this is an intermediate path. */ - return NT_STATUS_OBJECT_PATH_NOT_FOUND; - } - return NT_STATUS_ACCESS_DENIED; - } else { - /* - * This is the dropbox - * behaviour. A dropbox is a - * directory with only -wx - * permissions, so - * get_real_filename fails - * with EACCESS, it needs to - * list the directory. We - * nevertheless want to allow - * users creating a file. - */ - status = NT_STATUS_OK; - } - } - - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - /* - * ENOTDIR and ELOOP both map to - * NT_STATUS_OBJECT_PATH_NOT_FOUND - * in the filename walk. - */ - if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY) || - NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { - status = NT_STATUS_OBJECT_PATH_NOT_FOUND; - } - return status; - } - - /* - * POSIX pathnames must never call into mangling. - */ - if (state->posix_pathnames) { - goto done; - } - - /* - * Just the last part of the name doesn't exist. - * We need to strupper() or strlower() it as - * this conversion may be used for file creation - * purposes. Fix inspired by - * Thomas Neumann <t.neum...@iku-ag.de>. - */ - if (!state->case_preserve || - (mangle_is_8_3(state->name, false, - state->conn->params) && - !state->short_case_preserve)) { - if (!strnorm(state->name, - lp_default_case(SNUM(state->conn)))) { - DBG_DEBUG("strnorm %s failed\n", - state->name); - return NT_STATUS_INVALID_PARAMETER; - } - } - - /* - * check on the mangled stack to see if we can -- Samba Shared Repository