From: Ralph Boehme Date: Thu, 23 Aug 2018 10:07:20 +0000 (+0200) Subject: vfs_streams_xattr: fix open implementation X-Git-Tag: tdb-1.3.17~1088 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9f58997d7a1ab0358963a45cb8bf291e7afa8068;p=thirdparty%2Fsamba.git vfs_streams_xattr: fix open implementation Since a long time the modules's open function happily returned success when opening a non existent stream without O_CREAT. This change fixes it to return -1 and errno=ENOATTR if o get_ea_value() returns NT_STATUS_NOT_FOUND (eg mapped from getxattr() = -1, errno=ENOATTR) and o flags doesn't contain O_CREAT Bug: https://bugzilla.samba.org/show_bug.cgi?id=13646 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison --- diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index 30459fec4bf..9f4bc13b034 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -412,6 +412,7 @@ static int streams_xattr_open(vfs_handle_struct *handle, char *xattr_name = NULL; int pipe_fds[2]; int fakefd = -1; + bool set_empty_xattr = false; int ret; SMB_VFS_HANDLE_GET_DATA(handle, config, struct streams_xattr_config, @@ -445,39 +446,37 @@ static int streams_xattr_open(vfs_handle_struct *handle, goto fail; } - /* - * Return a valid fd, but ensure any attempt to use it returns an error - * (EPIPE). - */ - ret = pipe(pipe_fds); - if (ret != 0) { - goto fail; - } - - close(pipe_fds[1]); - pipe_fds[1] = -1; - fakefd = pipe_fds[0]; - status = get_ea_value(talloc_tos(), handle->conn, NULL, smb_fname, xattr_name, &ea); DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status))); - if (!NT_STATUS_IS_OK(status) - && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { - /* - * The base file is not there. This is an error even if we got - * O_CREAT, the higher levels should have created the base - * file for us. - */ - DEBUG(10, ("streams_xattr_open: base file %s not around, " - "returning ENOENT\n", smb_fname->base_name)); - errno = ENOENT; - goto fail; + if (!NT_STATUS_IS_OK(status)) { + if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { + /* + * The base file is not there. This is an error even if + * we got O_CREAT, the higher levels should have created + * the base file for us. + */ + DBG_DEBUG("streams_xattr_open: base file %s not around, " + "returning ENOENT\n", smb_fname->base_name); + errno = ENOENT; + goto fail; + } + + if (!(flags & O_CREAT)) { + errno = ENOATTR; + goto fail; + } + + set_empty_xattr = true; } - if ((!NT_STATUS_IS_OK(status) && (flags & O_CREAT)) || - (flags & O_TRUNC)) { + if (flags & O_TRUNC) { + set_empty_xattr = true; + } + + if (set_empty_xattr) { /* * The attribute does not exist or needs to be truncated */ @@ -500,6 +499,19 @@ static int streams_xattr_open(vfs_handle_struct *handle, } } + /* + * Return a valid fd, but ensure any attempt to use it returns an error + * (EPIPE). + */ + ret = pipe(pipe_fds); + if (ret != 0) { + goto fail; + } + + close(pipe_fds[1]); + pipe_fds[1] = -1; + fakefd = pipe_fds[0]; + sio = VFS_ADD_FSP_EXTENSION(handle, fsp, struct stream_io, NULL); if (sio == NULL) { errno = ENOMEM;