In settings.php, the private file path is documented with "This directory must be absolute, ...". However, an absolute path does not work when drupal runs on a shared host and access to the parent directories is not possible.

Example:
• a shared host with drupal root /var/www/ud17_276/html/drupal
• web server root is /var/www/ud17_276/html
• shared host root is /var/www/ud17_276, i.e., this part is not visible for the space admin, and thus neither for drupal
• in settings.php:
$settings['file_private_path'] = '/var/www/ud17_276/files/drupal-private';

If a drupal user tries to upload a file, by creating a node of a content type having a file field with private storage configured, drupal tries to create the full parent path, /var/www/ud17_276, which obviously will fail. The error message in the log is:

"The upload directory private://2016-09 for the file field field_privimage could not be created or is not accessible. A newly uploaded file could not be saved in this directory as a consequence, and the upload was canceled."

Configuring the shared host's users relative root, like
$settings['file_private_path'] = '/files/drupal-private';
does also not work. The only way this seems to work currently is a relative path:

$settings['file_private_path'] = '../../files/drupal-private';

Hence, either the code documentation in settings.php should be updated to include this case, or the coding has to be changed to be able to deal with shared hosting. (Unfortunately, due to lack of php knowledge, I cannot judge these options.)

Best, Tobias

CommentFileSizeAuthor
#54 interdiff_52-54.txt568 bytesaleix
#54 2799635-54.patch4.32 KBaleix
#52 interdiff_46-52.patch8.64 KBaleix
#52 2799635-52.patch5.08 KBaleix
#48 interdiff_41-48.txt3.8 KBBen Buske
#48 2799635-48.patch4.38 KBBen Buske
#46 2799635-45.patch4.34 KBdaften
#41 interdiff_38-41.txt464 bytesneelam_wadhwani
#41 2799635-41.patch4.23 KBneelam_wadhwani
#38 interdiff_35-38.txt464 bytesNeslee Canil Pinto
#38 2799635-38.patch4.23 KBNeslee Canil Pinto
#35 2799635-35.patch4.23 KBjungle
#35 interdiff-32-35.txt569 bytesjungle
#32 2799635-mkdir_relative_parent-32.patch4.29 KBrobotjox
#31 2799635-mkdir_relative_parent-31.patch4.29 KBrobotjox
#15 2799635-fix_mkdir-15.patch4.28 KBLpSolit
#12 patch_mkdir.diff3.47 KBLpSolit
#7 interdiff-2799635-3-6.txt689 bytestobias-hd
#7 drupal-mkdir_relative_parent-2799635-6.patch1.41 KBtobias-hd
#3 drupal-mkdir_relative_parent-2799635-3.patch758 bytesBoobaa
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tobias-hd created an issue. See original summary.

Boobaa’s picture

Version: 8.1.8 » 8.2.4
Assigned: Unassigned » Boobaa

Ran into the same problem, and was able to track it down to \Drupal\Core\File\FileSystem::mkdir(). This method iterates through all the components of the file_private_path and checks if the component exists. Since in our case the first component is .., file_exists() will return FALSE, thus this method tries to create it, which will obviously fail.

By the way, the same bug can be triggered by trying to download an image derivative whose directory does not exist yet. In this case, the error message is different: "Failed to create style directory: %directory" (from \Drupal\image\Entity\ImageStyle::createDerivative()).

A patch is coming, but I don't know how to write a test case for this, as the existence of this bug highly depends on hard-to-change PHP settings.

Boobaa’s picture

Assigned: Boobaa » Unassigned
Status: Active » Needs review
FileSize
758 bytes
Boobaa’s picture

Version: 8.2.4 » 8.2.5

The bug is still present on 8.2.5.

cilefen’s picture

Version: 8.2.5 » 8.2.x-dev
tobias-hd’s picture

Thanks @Boobaa for the patch #3!

I tested it with Drupal 8.2.5 on my webhoster, and I can confirm that the patch supresses a php error message "User error: Invalid placeholder (!name) in string: The directory %directory ... could not be created..."

Strangely, the upload itself did work (as far as I can judge) with and without patch - hence to me it's not clear, what the affected functionality behind that is. (I did clear the cache between testing with and without patch...)

With the image derivatives I still have the problem reported in #2799639: Image derivative generation not working for private files on shared host - the patch seems to not change anything in that respect.

I'd propose to supplement the patch with an adjustment of the corresponding comment in /sites/default/default.settings.php - I'll try to upload a patch.

tobias-hd’s picture

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

eithel’s picture

Maybe relate to thus issue: https://www.drupal.org/node/2878778

LpSolit’s picture

IMO, the right fix is to call createDirectory() being in core/lib/Drupal/Component/PhpStorage/FileStorage.php or to duplicate its behavior, as it already handles open_basedir correctly.

Boobaa’s picture

@LpSolit: could you submit this idea as a patch?

LpSolit’s picture

Here is what I had in mind.

Status: Needs review » Needs work

The last submitted patch, 12: patch_mkdir.diff, failed testing. View results

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

LpSolit’s picture

Status: Needs work » Needs review
FileSize
4.28 KB

Fix the error message in core/modules/migrate/tests/src/Kernel/process/FileCopyTest.php.

LpSolit’s picture

Title: 'file_private_path' needs to be a relative path on shared host » FileSystem::mkdir should handle open_basedir correctly

Updating the bug summary to better reflect what the problem is. With my patch, there is no need to use relative paths. Absolute paths just work fine.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

trungonly’s picture

Facing problem. Buzz for the fix.
For the #7, for the directory create, you should add DIRECTORY_SEPARATOR like this:

if ($component == '..') {
          $recursive_path .= DIRECTORY_SEPARATOR;
          continue;
        }
Anybody’s picture

I just ran into the same problem and can confirm this issue.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

capmex’s picture

I experienced this issue on a Plesk server where paths are like:

/var/www/vhosts/domain.com/httpdocs (DocRoot)
/var/www/vhosts/domain.com/private (the private folder I created not accessible over the web, ownership domain-user:psacln, permissions 775)

With the absolute path Drupal was able to create the .htaccess correctly, but any uploads failed because it was not able to create subdirectories.

$settings['file_private_path'] = '/var/www/vhosts/domain.com/private';

Using #7 (thanks @Boobaa and @tobias-hd) and adjusting it with #17 (thanks @trungonly) allowed the private directory to work correctly using:

$settings['file_private_path'] = '../private';

For anyone on a shared host or with setups like the above this is a good solution that can be easily implemented. I spent several hours trying to figure out why private files did not work at the server level.

Yazzbe’s picture

Many thanks for the suggestion. Struggled with this for hours ...
A relative path is the answer!

Geolim4’s picture

Thanks #21 for saving me hours of debug... Much appreciated !

rjw’s picture

Thanks. I came up against this issue when I added a file upload field to a webform. A relative path for the private file directory made it work. I didn't apply any patches.

broon’s picture

Thanks all, I was wrapping my head about this issue as well on a Plesk-based Drupal installation. Providing the private filesystem folder with a relative path solved the issue for now without any patches applied.

Dries Arnolds’s picture

This worked for me too. I had to apply the patch AND set a relative path.

I was using ISPConfig on a Debian server here.

robotjox’s picture

Also on ispconfig - came across this patch after banging my head against the wall for hours. Thanks!

milopca’s picture

Thanks to all!!
After a lot of time debugging the issue on a Plesk-based Drupal installation, setting the private dir to relative solved the issue (without any patches applied).

jfoctober’s picture

might this patch be making its way into core soon?

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

robotjox’s picture

I for one still need this patch.

robotjox’s picture

Let's try that again.

Neslee Canil Pinto’s picture

Status: Needs review » Reviewed & tested by the community

#32 applied cleanly and tests passed. Moving to RTBC.

jungle’s picture

Version: 8.8.x-dev » 8.9.x-dev
Assigned: Unassigned » jungle
Status: Reviewed & tested by the community » Needs work
+++ b/core/lib/Drupal/Core/File/FileSystem.php
@@ -187,7 +187,14 @@ public function mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) {
+    ¶

Unexpected leading spaces and should file against 8.9.x or other branches, not 8.8.x.

jungle’s picture

Status: Needs review » Needs work

The last submitted patch, 35: 2799635-35.patch, failed testing. View results

jungle’s picture

Status: Needs work » Reviewed & tested by the community

Failures seem unrelated and the re-testing passed, and #36 is just a tiny trivial change, so setting back to RTBC as #34.

Neslee Canil Pinto’s picture

Corrected sentence from 'If the directory exists already, there's nothing to do.' to 'If the directory already exists, there's nothing to do.'

jungle’s picture

Thanks, @Neslee Canil Pinto!

Re #38 It can be either in the mid position or the end position actually. But already in the mid position seems more formal than in the end position.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 38: 2799635-38.patch, failed testing. View results

neelam_wadhwani’s picture

Hello @jungle.
Your point was right, in mid position seems formal.

I have reroll patch #38
Kindly review it.

neelam_wadhwani’s picture

Status: Needs work » Needs review

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

daften’s picture

Rerolled patch for 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Ben Buske’s picture

Changed path of #46 for it to apply and added interdiff.

Status: Needs review » Needs work

The last submitted patch, 48: 2799635-48.patch, failed testing. View results

vijaycs85’s picture

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

aleix’s picture

The only way that test is passing is increasing the sleep time...

aleix’s picture

aleix’s picture

Attempt to make it pass the testNonWritableDestination

aleix’s picture

Status: Needs work » Needs review

As it is passing right now, please consider review the patch.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

LpSolit’s picture

I'm using this patch for years without any problem. I needed it to make the filebrowser module work with open_basedir. Not sure if this is enough to RTBC this patch.

LpSolit’s picture

aleix's patch #54 works fine with the filebrowser module and is 99% similar to what I wrote in comment #15, which I use for 5 years now. Not sure if I'm allowed to RTBC this patch.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative, +Needs issue summary update, +Needs tests

This issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.

The issue summary should be updated to clearly show what the proposed solution is, remaining tasks, etc

-        usleep((int) (($time_to_start - microtime(TRUE)) * 1000000));
+        usleep((int) (($time_to_start - microtime(TRUE)) * 5000000));

Not sure if this is in scope?

But as a bug this will need a test case showing the issue.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

bohemier’s picture

Thanks for the patch, without it, it is impossible to handle securing private files outside of the webroot with the open_basedir directive. After applying it, wet can set private and tmp using relative directories, such as:

$settings['file_private_path'] = '../../private';
$settings['file_temp_path'] = '../../tmp';
egfrith’s picture

After some time getting to the bottom of #3411785: Create subtheme doesn't work with open_basedir restriction, I would hope that we could get this sorted out. @smustgrave: is it possible to set up open_basedir in the testing environment? If not, I'm not clear how a test could be created for this issue.

apaderno’s picture

Assigned: neelam_wadhwani » Unassigned

I use shared hosting for a site, but I am able to use absolute paths, even when I set the file private path. Maybe the issue summary should explain when there are issues with using absolute paths.