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,
{
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)) {
if (!NT_STATUS_IS_OK(status)) {
return status;
}
+ fsp = *result;
if (config->copyfile_enabled) {
/*
* 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;
}
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;