1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-12 09:18:10 +03:00

vfs_fruit: fix fruit_check_access()

Applying fcntl read locks requires an fd opened for reading. This means
we have to check the open flags of an fd and if the fd is not opened for
reading, we can't use it to set shared fctnl locks.

Iow we won't be applying interop locks with Netatalk for files openend
write-only.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12427

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Uri Simchoni <uri@samba.org>
This commit is contained in:
Ralph Boehme 2016-12-08 11:08:53 +01:00 committed by Uri Simchoni
parent b1223520e3
commit 41a2b2f5cd

View File

@ -1805,6 +1805,8 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle,
struct byte_range_lock *br_lck = NULL;
bool open_for_reading, open_for_writing, deny_read, deny_write;
off_t off;
bool have_read = false;
int flags;
/* FIXME: hardcoded data fork, add resource fork */
enum apple_fork fork_type = APPLE_FORK_DATA;
@ -1816,6 +1818,26 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle,
deny_mode & DENY_READ ? "DENY_READ" : "-",
deny_mode & DENY_WRITE ? "DENY_WRITE" : "-"));
if (fsp->fh->fd == -1) {
return NT_STATUS_OK;
}
flags = fcntl(fsp->fh->fd, F_GETFL);
if (flags == -1) {
DBG_ERR("fcntl get flags [%s] fd [%d] failed [%s]\n",
fsp_str_dbg(fsp), fsp->fh->fd, strerror(errno));
return map_nt_error_from_unix(errno);
}
if (flags & (O_RDONLY|O_RDWR)) {
/*
* Applying fcntl read locks requires an fd opened for
* reading. This means we won't be applying locks for
* files openend write-only, but what can we do...
*/
have_read = true;
}
/*
* Check read access and deny read mode
*/
@ -1837,7 +1859,7 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle,
}
/* Set locks */
if (access_mask & FILE_READ_DATA) {
if ((access_mask & FILE_READ_DATA) && have_read) {
off = access_to_netatalk_brl(fork_type, FILE_READ_DATA);
br_lck = do_lock(
handle->conn->sconn->msg_ctx, fsp,
@ -1851,7 +1873,7 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle,
TALLOC_FREE(br_lck);
}
if (deny_mode & DENY_READ) {
if ((deny_mode & DENY_READ) && have_read) {
off = denymode_to_netatalk_brl(fork_type, DENY_READ);
br_lck = do_lock(
handle->conn->sconn->msg_ctx, fsp,
@ -1887,7 +1909,7 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle,
}
/* Set locks */
if (access_mask & FILE_WRITE_DATA) {
if ((access_mask & FILE_WRITE_DATA) && have_read) {
off = access_to_netatalk_brl(fork_type, FILE_WRITE_DATA);
br_lck = do_lock(
handle->conn->sconn->msg_ctx, fsp,
@ -1901,7 +1923,7 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle,
TALLOC_FREE(br_lck);
}
if (deny_mode & DENY_WRITE) {
if ((deny_mode & DENY_WRITE) && have_read) {
off = denymode_to_netatalk_brl(fork_type, DENY_WRITE);
br_lck = do_lock(
handle->conn->sconn->msg_ctx, fsp,