]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: VFS: fruit: Implement SMB_VFS_FREADDIR_ATTR()
authorSamuel Cabrero <scabrero@samba.org>
Thu, 13 May 2021 11:08:20 +0000 (13:08 +0200)
committerJeremy Allison <jra@samba.org>
Fri, 14 May 2021 20:04:28 +0000 (20:04 +0000)
Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/modules/vfs_fruit.c

index 856a7beb650e108e3276bb31852d39a608ed7296..da9c9f0cd2fb136307f969992823d52907e27570 100644 (file)
@@ -4286,6 +4286,105 @@ fail:
        return status;
 }
 
+static NTSTATUS fruit_freaddir_attr(struct vfs_handle_struct *handle,
+                                   struct files_struct *fsp,
+                                   TALLOC_CTX *mem_ctx,
+                                   struct readdir_attr_data **pattr_data)
+{
+       struct fruit_config_data *config = NULL;
+       struct readdir_attr_data *attr_data;
+       uint32_t conv_flags  = 0;
+       NTSTATUS status;
+       int ret;
+
+       SMB_VFS_HANDLE_GET_DATA(handle, config,
+                               struct fruit_config_data,
+                               return NT_STATUS_UNSUCCESSFUL);
+
+       if (!global_fruit_config.nego_aapl) {
+               return SMB_VFS_NEXT_FREADDIR_ATTR(handle,
+                                                 fsp,
+                                                 mem_ctx,
+                                                 pattr_data);
+       }
+
+       DBG_DEBUG("Path [%s]\n", fsp_str_dbg(fsp));
+
+       if (config->wipe_intentionally_left_blank_rfork) {
+               conv_flags |= AD_CONV_WIPE_BLANK;
+       }
+       if (config->delete_empty_adfiles) {
+               conv_flags |= AD_CONV_DELETE;
+       }
+
+       ret = ad_convert(handle,
+                        fsp->fsp_name,
+                        macos_string_replace_map,
+                        conv_flags);
+       if (ret != 0) {
+               DBG_ERR("ad_convert() failed\n");
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       *pattr_data = talloc_zero(mem_ctx, struct readdir_attr_data);
+       if (*pattr_data == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       attr_data = *pattr_data;
+       attr_data->type = RDATTR_AAPL;
+
+       /*
+        * Mac metadata: compressed FinderInfo, resource fork length
+        * and creation date
+        */
+       status = readdir_attr_macmeta(handle, fsp->fsp_name, attr_data);
+       if (!NT_STATUS_IS_OK(status)) {
+               /*
+                * Error handling is tricky: if we return failure from
+                * this function, the corresponding directory entry
+                * will to be passed to the client, so we really just
+                * want to error out on fatal errors.
+                */
+               if  (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+                       goto fail;
+               }
+       }
+
+       /*
+        * UNIX mode
+        */
+       if (config->unix_info_enabled) {
+               attr_data->attr_data.aapl.unix_mode =
+                       fsp->fsp_name->st.st_ex_mode;
+       }
+
+       /*
+        * max_access
+        */
+       if (!config->readdir_attr_max_access) {
+               attr_data->attr_data.aapl.max_access = FILE_GENERIC_ALL;
+       } else {
+               status = smbd_calculate_access_mask(
+                       handle->conn,
+                       handle->conn->cwd_fsp,
+                       fsp->fsp_name,
+                       false,
+                       SEC_FLAG_MAXIMUM_ALLOWED,
+                       &attr_data->attr_data.aapl.max_access);
+               if (!NT_STATUS_IS_OK(status)) {
+                       goto fail;
+               }
+       }
+
+       return NT_STATUS_OK;
+
+fail:
+       DBG_WARNING("Path [%s], error: %s\n", fsp_str_dbg(fsp),
+                  nt_errstr(status));
+       TALLOC_FREE(*pattr_data);
+       return status;
+}
+
 static NTSTATUS fruit_fget_nt_acl(vfs_handle_struct *handle,
                                  files_struct *fsp,
                                  uint32_t security_info,
@@ -5215,6 +5314,7 @@ static struct vfs_fn_pointers vfs_fruit_fns = {
        .fallocate_fn = fruit_fallocate,
        .create_file_fn = fruit_create_file,
        .readdir_attr_fn = fruit_readdir_attr,
+       .freaddir_attr_fn = fruit_freaddir_attr,
        .offload_read_send_fn = fruit_offload_read_send,
        .offload_read_recv_fn = fruit_offload_read_recv,
        .offload_write_send_fn = fruit_offload_write_send,