mirror of
https://github.com/samba-team/samba.git
synced 2025-02-28 01:58:17 +03:00
smbd: deal with real dirfsps in non_widelink_open()
If we get a real dirfsp, skip the parent-directory logic. Just pass the dirfsp to SMB_VFS_OPENAT() which by now supports real dirfsps. Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
65c4f61587
commit
12d75a83ea
@ -663,55 +663,64 @@ static int non_widelink_open(const struct files_struct *dirfsp,
|
||||
have_opath = true;
|
||||
#endif
|
||||
|
||||
if (fsp->fsp_flags.is_directory) {
|
||||
parent_dir_fname = cp_smb_filename(talloc_tos(), smb_fname);
|
||||
if (parent_dir_fname == NULL) {
|
||||
saved_errno = errno;
|
||||
if (dirfsp == conn->cwd_fsp) {
|
||||
if (fsp->fsp_flags.is_directory) {
|
||||
parent_dir_fname = cp_smb_filename(talloc_tos(), smb_fname);
|
||||
if (parent_dir_fname == NULL) {
|
||||
saved_errno = errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
smb_fname_rel = synthetic_smb_fname(parent_dir_fname,
|
||||
".",
|
||||
smb_fname->stream_name,
|
||||
&smb_fname->st,
|
||||
smb_fname->twrp,
|
||||
smb_fname->flags);
|
||||
if (smb_fname_rel == NULL) {
|
||||
saved_errno = errno;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
ok = parent_smb_fname(talloc_tos(),
|
||||
smb_fname,
|
||||
&parent_dir_fname,
|
||||
&smb_fname_rel);
|
||||
if (!ok) {
|
||||
saved_errno = errno;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
oldwd_fname = vfs_GetWd(talloc_tos(), conn);
|
||||
if (oldwd_fname == NULL) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
smb_fname_rel = synthetic_smb_fname(parent_dir_fname,
|
||||
".",
|
||||
smb_fname->stream_name,
|
||||
&smb_fname->st,
|
||||
smb_fname->twrp,
|
||||
smb_fname->flags);
|
||||
if (smb_fname_rel == NULL) {
|
||||
saved_errno = errno;
|
||||
/* Pin parent directory in place. */
|
||||
if (vfs_ChDir(conn, parent_dir_fname) == -1) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Ensure the relative path is below the share. */
|
||||
status = check_reduced_name(conn, parent_dir_fname, smb_fname_rel);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
saved_errno = map_errno_from_nt_status(status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Setup fsp->fsp_name to be relative to cwd */
|
||||
fsp->fsp_name = smb_fname_rel;
|
||||
} else {
|
||||
ok = parent_smb_fname(talloc_tos(),
|
||||
smb_fname,
|
||||
&parent_dir_fname,
|
||||
&smb_fname_rel);
|
||||
if (!ok) {
|
||||
saved_errno = errno;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
oldwd_fname = vfs_GetWd(talloc_tos(), conn);
|
||||
if (oldwd_fname == NULL) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Pin parent directory in place. */
|
||||
if (vfs_ChDir(conn, parent_dir_fname) == -1) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Ensure the relative path is below the share. */
|
||||
status = check_reduced_name(conn, parent_dir_fname, smb_fname_rel);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
saved_errno = map_errno_from_nt_status(status);
|
||||
goto out;
|
||||
/*
|
||||
* fsp->fsp_name is unchanged as it is already correctly
|
||||
* relative to conn->cwd.
|
||||
*/
|
||||
smb_fname_rel = smb_fname;
|
||||
}
|
||||
|
||||
flags |= O_NOFOLLOW;
|
||||
|
||||
fsp->fsp_name = smb_fname_rel;
|
||||
|
||||
fd = SMB_VFS_OPENAT(conn,
|
||||
dirfsp,
|
||||
smb_fname_rel,
|
||||
@ -741,6 +750,7 @@ static int non_widelink_open(const struct files_struct *dirfsp,
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
fsp->fsp_name->st = orig_fsp_name->st;
|
||||
|
||||
if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
|
||||
ret = SMB_VFS_CLOSE(fsp);
|
||||
|
Loading…
x
Reference in New Issue
Block a user