mirror of
https://github.com/samba-team/samba.git
synced 2025-02-19 21:57:57 +03:00
s3/smbd: let non_widelink_open() chdir() to directories directly
If the caller passes O_DIRECTORY we just try to chdir() to smb_fname directly, not to the parent directory. The security check in check_reduced_name() will continue to work, but this fixes the case of an open() for a previous version of a subdirectory that contains snapshopt. Eg: [share] path = /shares/test vfs objects = shadow_copy2 shadow:snapdir = .snapshots shadow:snapdirseverywhere = yes Directory tree with fake snapshots: $ tree -a /shares/test/ /shares/test/ ├── dir │ ├── file │ └── .snapshots │ └── @GMT-2017.07.04-04.30.12 │ └── file ├── dir2 │ └── file ├── file ├── .snapshots │ └── @GMT-2001.01.01-00.00.00 │ ├── dir2 │ │ └── file │ └── file └── testfsctl.dat ./bin/smbclient -U slow%x //localhost/share -c 'ls @GMT-2017.07.04-04.30.12/dir/*' NT_STATUS_OBJECT_NAME_NOT_FOUND listing \@GMT-2017.07.04-04.30.12\dir\* Bug: https://bugzilla.samba.org/show_bug.cgi?id=12885 Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> (cherry picked from commit b886a9443d49f6e27fa3863d87c9e24d12e62874)
This commit is contained in:
parent
80aeac8bd0
commit
7916e1a9ef
@ -537,12 +537,32 @@ static int non_widelink_open(struct connection_struct *conn,
|
||||
char *oldwd = NULL;
|
||||
char *parent_dir = NULL;
|
||||
const char *final_component = NULL;
|
||||
bool is_directory = false;
|
||||
bool ok;
|
||||
|
||||
if (!parent_dirname(talloc_tos(),
|
||||
smb_fname->base_name,
|
||||
&parent_dir,
|
||||
&final_component)) {
|
||||
goto out;
|
||||
#ifdef O_DIRECTORY
|
||||
if (flags & O_DIRECTORY) {
|
||||
is_directory = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (is_directory) {
|
||||
parent_dir = talloc_strdup(talloc_tos(), smb_fname->base_name);
|
||||
if (parent_dir == NULL) {
|
||||
saved_errno = errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
final_component = ".";
|
||||
} else {
|
||||
ok = parent_dirname(talloc_tos(),
|
||||
smb_fname->base_name,
|
||||
&parent_dir,
|
||||
&final_component);
|
||||
if (!ok) {
|
||||
saved_errno = errno;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
oldwd = vfs_GetWd(talloc_tos(), conn);
|
||||
|
Loading…
x
Reference in New Issue
Block a user