diff options
author | Ralph Boehme <slow@samba.org> | 2015-08-08 20:21:39 +0200 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2015-09-04 12:41:17 +0200 |
commit | 6c109257df8aa95f503fc6ee4166753c3ac250b4 (patch) | |
tree | aafaae1dbf23e703dbdaf00b4e53941b8e65a58f | |
parent | 0befbeb33bf3ebb189639598281e989178efbc4a (diff) | |
download | samba-6c109257df8aa95f503fc6ee4166753c3ac250b4.tar.gz |
vfs_fruit: handling of empty resource fork
Opening the resource fork stream with O_CREAT mustn't create a visible
node in the filesystem, only create a file handle. As long as the
creator didn't write into the stream, other openers withour O_CREAT
MUST get an ENOENT error. This is way OS X SMB server implements it.
Bug: https://bugzilla.samba.org/show_bug.cgi?id=11467
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
-rw-r--r-- | source3/modules/vfs_fruit.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c index 8ac4ba1f5b6..def760f23cf 100644 --- a/source3/modules/vfs_fruit.c +++ b/source3/modules/vfs_fruit.c @@ -3085,7 +3085,7 @@ static NTSTATUS fruit_streaminfo(vfs_handle_struct *handle, if (config->rsrc != FRUIT_RSRC_STREAM) { ad = ad_get(talloc_tos(), handle, smb_fname->base_name, ADOUBLE_RSRC); - if (ad) { + if (ad && (ad_getentrylen(ad, ADEID_RFORK) > 0)) { if (!add_fruit_stream( mem_ctx, pnum_streams, pstreams, AFPRESOURCE_STREAM_NAME, @@ -3246,6 +3246,7 @@ static NTSTATUS fruit_create_file(vfs_handle_struct *handle, { NTSTATUS status; struct fruit_config_data *config = NULL; + files_struct *fsp = NULL; status = check_aapl(handle, req, in_context_blobs, out_context_blobs); if (!NT_STATUS_IS_OK(status)) { @@ -3267,6 +3268,7 @@ static NTSTATUS fruit_create_file(vfs_handle_struct *handle, if (!NT_STATUS_IS_OK(status)) { return status; } + fsp = *result; if (config->copyfile_enabled) { /* @@ -3275,11 +3277,27 @@ static NTSTATUS fruit_create_file(vfs_handle_struct *handle, * for copychunk should be allowed in a copychunk * request with a count of 0. */ - (*result)->aapl_copyfile_supported = true; + fsp->aapl_copyfile_supported = true; } + + /* + * If this is a plain open for existing files, opening an 0 + * byte size resource fork MUST fail with + * NT_STATUS_OBJECT_NAME_NOT_FOUND. + * + * Cf the vfs_fruit torture tests in test_rfork_create(). + */ + if (is_afpresource_stream(fsp->fsp_name) && + create_disposition == FILE_OPEN) + { + if (fsp->fsp_name->st.st_ex_size == 0) { + status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + goto fail; + } + } + if (is_ntfs_stream_smb_fname(smb_fname) - || (*result == NULL) - || ((*result)->is_directory)) { + || fsp->is_directory) { return status; } @@ -3296,11 +3314,11 @@ static NTSTATUS fruit_create_file(vfs_handle_struct *handle, return status; fail: - DEBUG(1, ("fruit_create_file: %s\n", nt_errstr(status))); + DEBUG(10, ("fruit_create_file: %s\n", nt_errstr(status))); - if (*result) { - close_file(req, *result, ERROR_CLOSE); - *result = NULL; + if (fsp) { + close_file(req, fsp, ERROR_CLOSE); + *result = fsp = NULL; } return status; |