mirror of
https://github.com/samba-team/samba.git
synced 2025-08-24 21:49:29 +03:00
Second part of the fix for bug #5903 - vfs_streams_xattr breaks contents of the file
Jeremy.
This commit is contained in:
@ -404,7 +404,7 @@ dnl These have to be built static:
|
||||
default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl2 rpc_ntsvcs2 rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss rpc_eventlog2 auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin vfs_default nss_info_template"
|
||||
|
||||
dnl These are preferably build shared, and static if dlopen() is not available
|
||||
default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_smb_traffic_analyzer"
|
||||
default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_smb_traffic_analyzer"
|
||||
|
||||
if test "x$developer" = xyes; then
|
||||
default_static_modules="$default_static_modules rpc_rpcecho"
|
||||
|
@ -624,7 +624,7 @@ static ssize_t streams_xattr_pread(vfs_handle_struct *handle,
|
||||
(struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
|
||||
struct ea_struct ea;
|
||||
NTSTATUS status;
|
||||
size_t length, overlap;
|
||||
size_t length, overlap;
|
||||
|
||||
if (sio == NULL) {
|
||||
return SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
|
||||
@ -651,6 +651,63 @@ static ssize_t streams_xattr_pread(vfs_handle_struct *handle,
|
||||
return overlap;
|
||||
}
|
||||
|
||||
static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
|
||||
struct files_struct *fsp,
|
||||
SMB_OFF_T offset)
|
||||
{
|
||||
int ret;
|
||||
uint8 *tmp;
|
||||
struct ea_struct ea;
|
||||
NTSTATUS status;
|
||||
struct stream_io *sio =
|
||||
(struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
|
||||
|
||||
DEBUG(10, ("streams_xattr_ftruncate called for file %s offset %.0f\n",
|
||||
fsp->fsp_name,
|
||||
(double)offset ));
|
||||
|
||||
if (sio == NULL) {
|
||||
return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
|
||||
}
|
||||
|
||||
status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp,
|
||||
sio->base, sio->xattr_name, &ea);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmp = TALLOC_REALLOC_ARRAY(talloc_tos(), ea.value.data, uint8,
|
||||
offset + 1);
|
||||
|
||||
if (tmp == NULL) {
|
||||
TALLOC_FREE(ea.value.data);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Did we expand ? */
|
||||
if (ea.value.length < offset + 1) {
|
||||
memset(&tmp[ea.value.length], '\0',
|
||||
offset + 1 - ea.value.length);
|
||||
}
|
||||
|
||||
ea.value.data = tmp;
|
||||
ea.value.length = offset + 1;
|
||||
ea.value.data[offset] = 0;
|
||||
|
||||
ret = SMB_VFS_SETXATTR(fsp->conn, fsp->base_fsp->fsp_name,
|
||||
sio->xattr_name,
|
||||
ea.value.data, ea.value.length, 0);
|
||||
|
||||
TALLOC_FREE(ea.value.data);
|
||||
|
||||
if (ret == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* VFS operations structure */
|
||||
|
||||
static vfs_op_tuple streams_xattr_ops[] = {
|
||||
@ -672,6 +729,8 @@ static vfs_op_tuple streams_xattr_ops[] = {
|
||||
SMB_VFS_LAYER_TRANSPARENT},
|
||||
{SMB_VFS_OP(streams_xattr_unlink), SMB_VFS_OP_UNLINK,
|
||||
SMB_VFS_LAYER_TRANSPARENT},
|
||||
{SMB_VFS_OP(streams_xattr_ftruncate), SMB_VFS_OP_FTRUNCATE,
|
||||
SMB_VFS_LAYER_TRANSPARENT},
|
||||
{SMB_VFS_OP(streams_xattr_streaminfo), SMB_VFS_OP_STREAMINFO,
|
||||
SMB_VFS_LAYER_OPAQUE},
|
||||
{SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
|
||||
|
@ -2774,10 +2774,42 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
|
||||
* Ordinary file case.
|
||||
*/
|
||||
|
||||
status = open_file_ntcreate(
|
||||
conn, req, fname, &sbuf, access_mask, share_access,
|
||||
create_disposition, create_options, file_attributes,
|
||||
oplock_request, &info, &fsp);
|
||||
if (base_fsp) {
|
||||
/*
|
||||
* We're opening the stream element of a base_fsp
|
||||
* we already opened. We need to initialize
|
||||
* the fsp first, and set up the base_fsp pointer.
|
||||
*/
|
||||
status = file_new(conn, &fsp);
|
||||
if(!NT_STATUS_IS_OK(status)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fsp->base_fsp = base_fsp;
|
||||
|
||||
status = open_file_ntcreate_internal(conn,
|
||||
req,
|
||||
fname,
|
||||
&sbuf,
|
||||
access_mask,
|
||||
share_access,
|
||||
create_disposition,
|
||||
create_options,
|
||||
file_attributes,
|
||||
oplock_request,
|
||||
&info,
|
||||
fsp);
|
||||
|
||||
if(!NT_STATUS_IS_OK(status)) {
|
||||
file_free(fsp);
|
||||
fsp = NULL;
|
||||
}
|
||||
} else {
|
||||
status = open_file_ntcreate(
|
||||
conn, req, fname, &sbuf, access_mask, share_access,
|
||||
create_disposition, create_options, file_attributes,
|
||||
oplock_request, &info, &fsp);
|
||||
}
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
|
||||
|
||||
@ -2804,6 +2836,8 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fsp->base_fsp = base_fsp;
|
||||
|
||||
/*
|
||||
* According to the MS documentation, the only time the security
|
||||
* descriptor is applied to the opened file is iff we *created* the
|
||||
@ -2881,16 +2915,6 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
|
||||
|
||||
DEBUG(10, ("create_file_unixpath: info=%d\n", info));
|
||||
|
||||
/*
|
||||
* Set fsp->base_fsp late enough that we can't "goto fail" anymore. In
|
||||
* the fail: branch we call close_file(fsp, ERROR_CLOSE) which would
|
||||
* also close fsp->base_fsp which we have to also do explicitly in
|
||||
* this routine here, as not in all "goto fail:" we have the fsp set
|
||||
* up already to be initialized with the base_fsp.
|
||||
*/
|
||||
|
||||
fsp->base_fsp = base_fsp;
|
||||
|
||||
*result = fsp;
|
||||
if (pinfo != NULL) {
|
||||
*pinfo = info;
|
||||
@ -2909,6 +2933,13 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
|
||||
DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
|
||||
|
||||
if (fsp != NULL) {
|
||||
if (base_fsp && fsp->base_fsp == base_fsp) {
|
||||
/*
|
||||
* The close_file below will close
|
||||
* fsp->base_fsp.
|
||||
*/
|
||||
base_fsp = NULL;
|
||||
}
|
||||
close_file(fsp, ERROR_CLOSE);
|
||||
fsp = NULL;
|
||||
}
|
||||
|
Reference in New Issue
Block a user