]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
vfs_fruit: handling of empty resource fork
authorRalph Boehme <slow@samba.org>
Sat, 8 Aug 2015 18:21:39 +0000 (20:21 +0200)
committerKarolin Seeger <kseeger@samba.org>
Fri, 4 Sep 2015 11:02:19 +0000 (13:02 +0200)
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>
source3/modules/vfs_fruit.c

index fb9350ba04fd2dc619edf6f21f9b9c37a1c2dc28..c9f27a362ae93ed67ace4191c8182ac619887a5a 100644 (file)
@@ -3092,7 +3092,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,
@@ -3253,6 +3253,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)) {
@@ -3274,6 +3275,7 @@ static NTSTATUS fruit_create_file(vfs_handle_struct *handle,
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
+       fsp = *result;
 
        if (config->copyfile_enabled) {
                /*
@@ -3282,11 +3284,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;
        }
 
@@ -3303,11 +3321,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;