From: Jeremy Allison Date: Wed, 27 Jul 2022 22:28:13 +0000 (-0700) Subject: s3: smbd: Fix the error processing in filename_convert_dirfsp_nosymlink() to match... X-Git-Tag: samba-4.17.0rc1~181 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=758ffebb8a8ce6b92598137f927a67961690bb69;p=thirdparty%2Fsamba.git s3: smbd: Fix the error processing in filename_convert_dirfsp_nosymlink() to match unix_convert() 100% We need this in order to pass: samba3.raw.samba3badpath raw.chkpath samba3.base.chkpath Now we can convert all the SMB1 reply_openXXX functions, and reply_checkpath(). Signed-off-by: Jeremy Allison Reviewed-by: Volker Lendecke --- diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 5f90f378482..3f0c395fd8f 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -2749,6 +2749,19 @@ static NTSTATUS filename_convert_dirfsp_nosymlink( return NT_STATUS_OK; } + /* + * Catch an invalid path of "." before we + * call filename_split_lcomp(). We need to + * do this as filename_split_lcomp() will + * use "." for the missing relative component + * when an empty name_in path is sent by + * the client. + */ + if (ISDOT(name_in)) { + status = NT_STATUS_OBJECT_NAME_INVALID; + goto fail; + } + ok = filename_split_lcomp( talloc_tos(), name_in, @@ -2761,11 +2774,6 @@ static NTSTATUS filename_convert_dirfsp_nosymlink( goto fail; } - if (fname_rel[0] == '\0') { - status = NT_STATUS_OBJECT_NAME_INVALID; - goto fail; - } - if (!posix) { bool name_has_wild = ms_has_wild(dirname); name_has_wild |= ms_has_wild(fname_rel); @@ -2828,13 +2836,39 @@ static NTSTATUS filename_convert_dirfsp_nosymlink( goto fail; } - TALLOC_FREE(dirname); if (!VALID_STAT_OF_DIR(smb_dirname->st)) { status = NT_STATUS_OBJECT_PATH_NOT_FOUND; goto fail; } + /* + * Only look at bad last component values + * once we know we have a valid directory. That + * way we won't confuse error messages from + * opening the directory path with error + * messages from a bad last component. + */ + + /* Relative filename can't be empty */ + if (fname_rel[0] == '\0') { + status = NT_STATUS_OBJECT_NAME_INVALID; + goto fail; + } + + /* Relative filename can't be ".." */ + if (ISDOTDOT(fname_rel)) { + status = NT_STATUS_OBJECT_NAME_INVALID; + goto fail; + } + /* Relative name can only be dot if directory is empty. */ + if (ISDOT(fname_rel) && dirname[0] != '\0') { + status = NT_STATUS_OBJECT_NAME_INVALID; + goto fail; + } + + TALLOC_FREE(dirname); + smb_fname_rel = synthetic_smb_fname( mem_ctx, fname_rel, @@ -2999,6 +3033,7 @@ done: return NT_STATUS_OK; fail: + TALLOC_FREE(dirname); TALLOC_FREE(smb_dirname); TALLOC_FREE(smb_fname_rel); return status;