php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #43817 opendir() fails on Windows directories with parent directory unaccessible
Submitted: 2008-01-11 12:23 UTC Modified: 2013-03-05 12:12 UTC
Votes:33
Avg. Score:4.3 ± 0.9
Reproduced:28 of 28 (100.0%)
Same Version:14 (50.0%)
Same OS:18 (64.3%)
From: losd at mail dot dk Assigned: pajoye
Status: Assigned Package: Directory function related
PHP Version: 5.3.0beta1 OS: win32 only - Windows Server 2003
Private report: No CVE-ID:
Have you experienced this issue?
Rate the importance of this bug to you:

 [2008-01-11 12:23 UTC] losd at mail dot dk
Description:
------------
If the parent directory of a Windows network share is not accessible, you are still able to access subdirectories if given explicit permission.

However, PHP has trouble with the first accessible directory below an inaccessible directory. This is not a problem for the accessible dir's  subdirs, though.

Scenario:
C:/Test/NoAccess/  -- Not accessible
   Access/        -- Accesible from here
      yyyyyyy.txt
      Subdir/
         xxxxxxx.txt

The problem has been found with opendir(), is_dir() and is_readable(). All directory functions are probably affected.

No workarounds has been found so far (suggestions appreciated).

Reproduce code:
---------------
<?php
if ($handle = opendir("C:/Test/NoAccess/Access/Subdir")) {
	echo "Opened dir C:/Test/NoAccess/Access/Subdir<br/>";
	while (false !== ($file = readdir($handle)))
		echo"File: $file<br/>";
	closedir($handle);
} else {
	echo "Hmmmm, can't open directory, is it accessible?<br/>";
}
echo "<br/>";
if ($handle = opendir("C:/Test/NoAccess/Access")) {
	echo "Opened directory C:/Test/NoAccess/Access<br/>";
	while (false !== ($file = readdir($handle)))
		echo"File: $file<br/>";
	closedir($handle);
} else {
	echo "Hmmmm, can't open directory, is it accessible?<br/>";
}
?>

Expected result:
----------------
Opened dir C:/Test/NoAccess/Access/Subdir
File: .
File: ..
File: xxxxxxx.txt

Opened dir C:/Test/NoAccess/Access
File: .
File: ..
File: yyyyyyy.txt
File: Subdir




Actual result:
--------------
Opened dir C:/Test/NoAccess/Access/Subdir
File: .
File: ..
File: xxxxxxx.txt


Warning: opendir(C:/Test/NoAccess/Access) [function.opendir]: failed to open dir: No such file or directory in C:\Inetpub\wwwroot\pm2\opendir.php on line 13
Hmmmm, can't open directory, is it accessible?

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-01-11 13:36 UTC] losd at mail dot dk
Temporary workaround found, but only if there is a known subdirectory inside the top accessible directory:

opendir("C:/Test/NoAccess/Access/Subdir/..");
 [2008-03-01 01:10 UTC] danielc@php.net
I am experiencing this issue as well, but on local directories, not network shares.  My OS is Windows XP Pro.  The opendir() functionality works correctly in release 5.2.1.  The functionality is broken in releases 5.2.2 through 5.2.5, plus the 526-php5.2-win32-200802292130 and php5.3-win32-200802201330 snapshots.
 [2008-03-01 09:02 UTC] losd at mail dot dk
Description:
------------
If the parent directory of a Windows directory is not accessible,
you are still able to access subdirectories if given explicit
permission.

However, PHP has trouble with the first accessible directory below an
inaccessible directory. This is not a problem for the accessible dir's 
subdirs, though.

Scenario:
C:/Test/NoAccess/  -- Not accessible
   Access/        -- Accesible from here
      yyyyyyy.txt
      Subdir/
         xxxxxxx.txt

The problem has been found with opendir(), is_dir() and is_readable().
All directory functions are probably affected.

No workarounds has been found so far (suggestions appreciated).

Reproduce code:
---------------
<?php
if ($handle = opendir("C:/Test/NoAccess/Access/Subdir")) {
	echo "Opened dir C:/Test/NoAccess/Access/Subdir<br/>";
	while (false !== ($file = readdir($handle)))
		echo"File: $file<br/>";
	closedir($handle);
} else {
	echo "Hmmmm, can't open directory, is it accessible?<br/>";
}
echo "<br/>";
if ($handle = opendir("C:/Test/NoAccess/Access")) {
	echo "Opened directory C:/Test/NoAccess/Access<br/>";
	while (false !== ($file = readdir($handle)))
		echo"File: $file<br/>";
	closedir($handle);
} else {
	echo "Hmmmm, can't open directory, is it accessible?<br/>";
}
?>

Expected result:
----------------
Opened dir C:/Test/NoAccess/Access/Subdir
File: .
File: ..
File: xxxxxxx.txt

Opened dir C:/Test/NoAccess/Access
File: .
File: ..
File: yyyyyyy.txt
File: Subdir

Actual result:
--------------
Opened dir C:/Test/NoAccess/Access/Subdir
File: .
File: ..
File: xxxxxxx.txt

Warning: opendir(C:/Test/NoAccess/Access) [function.opendir]: failed to open dir: No such file or directory in C:\Inetpub\wwwroot\pm2\opendir.php on line 13
Hmmmm, can't open directory, is it accessible?
 [2008-03-01 09:09 UTC] losd at mail dot dk
Doh, sorry, thought I could edit the original text. Just delete that comment.

But yes, as Daniel correctly points out, it's all Windows permission handling (As my reproduce code also shows), not just related to network shares... I experienced it in one at first, I guess that's why it stuck in my brain.
 [2008-08-12 09:42 UTC] dmitry@php.net
Fixed in CVS HEAD and PHP_5_3.
 [2009-02-03 15:31 UTC] danielc@php.net
This problem still exists in 5.3.0 beta 1 (http://windows.php.net/downloads/qa/php-5.3.0beta1-Win32-VC6-x86.zip)
 [2009-02-03 17:36 UTC] danielc@php.net
Changing version from 5.2.5 to 5.3.0beta1 to facilitate this getting fixed before the next release.
 [2009-03-02 20:01 UTC] pajoye@php.net
I can now reproduce it on XP, but not on 2008/Vista/win7.

I have to investigate deeper :P
 [2009-03-02 20:09 UTC] pajoye@php.net
Also see #42832
 [2009-06-20 11:39 UTC] pajoye@php.net
Can't reproduce it with RC4, please try again with 5.3.0RC4.
 [2009-06-28 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2010-03-29 00:12 UTC] danielc@php.net
-Status: No Feedback +Status: Assigned
 [2010-03-29 00:12 UTC] danielc@php.net
Still exists for me under the official release of PHP 5.3.0 on an XP SP3 machine.
 [2010-03-29 00:27 UTC] pajoye@php.net
-Status: Assigned +Status: Feedback
 [2010-03-29 00:27 UTC] pajoye@php.net
Please try with 5.3.2
 [2010-04-05 01:45 UTC] danielc@php.net
-Status: Feedback +Status: Assigned
 [2010-04-05 01:45 UTC] danielc@php.net
I just installed 5.3.2.  The regression has gotten worse.  Now the "Subdir/.." workaround fails too:

Warning: opendir(C:/Dir/Subdir/..,C:/Dir/Subdir/..) [function.opendir]: Access is denied. (code: 5)...
 [2010-04-05 01:59 UTC] pajoye@php.net
Nothing has changed in 5.2/3.x about that. The problem may come from the tsrm's real path which tries to access all parent directories to cache them.

I have to investigate why it fails on XP (and on on 2003 for your right?) but not on more recent versions.
 [2010-04-08 16:36 UTC] danielc@php.net
That makes sense.  I'm on XP.  Thanks.  If you need quicker feedback, shoot me an email or assign the bug to me.
 [2011-01-29 00:11 UTC] asankel at yahoo dot com
Same problem with PHP 5.3.5 on Windows 2008 with IIS 7.

Workaround is to add "\." to the end of the path and then PHP doesn't attempt to access the parent directories at all. For example, change "d:\files\directory\test" to "d:\files\directory\test\."
 [2011-01-29 00:22 UTC] asankel at yahoo dot com
Never mind on the workaround. Was related to some fastcgi caching. If you are running fastcgi the parent directory check is only done the first time. If it has access the first time it won't check the parent directory for further accesses.
 [2011-02-01 22:42 UTC] asankel at yahoo dot com
UPDATE: This problem does not occur with php-5.2.17-nts-Win32-VC6-x86 so you can use it as a workaround.
 [2012-07-18 06:53 UTC] denis at morozov dot tk
W2008R2x64+PHP5.3.8.: have got the same error+
In my case is_dir() is not affected,
but opendir() fails.
Directory is in the root of system disk, directories inside wwwroot are not affected.
If started from CMD with Admin - no error, error comes only in case of IUSR-IIS calls.
IN:
$dir="E:\\temp\\";
$dh=opendir($dir);
OUT:
PHP Warning:  opendir(E:\temp\,E:\temp\) [<a href='function.opendir'>function.opendir</a>]: Отказано в доступе. (code: 5) in E:\inetpub\dm\iPrinter\dir.php
 [2012-10-18 11:49 UTC] y dot korotia at hotmail dot com
are you going to fix it for Windows or not?

I've wasted about 4 hours because of this bug!

installed ZendServer with 5.3x

To access folder I must give access to its parent. what a f..?
 [2013-01-10 12:34 UTC] pajoye@php.net
Quick notice to help to understand the problem describe here:

The main problem here is that FindFirstFile requires access to all elements of a 
given path, which is not the case here.

To work around this limitation while keeping the realpath cache working nicely is 
not that easy.
 [2013-01-14 11:26 UTC] pajoye@php.net
Ok, the actual issue is about setting the right permissions.

It is possible to block read&write and other operations but the read of the 
attribute of a given path must be allowed. It is used by almost all file 
functions    (Find*, GetLong/ShortPathName, etc.). 

Without the permissions allowing to read attributes, we won't be able to fetch 
the actual name (ie: c:\Foo is given but the actual name is c:\fOo). We used the 
actual to store it in the real cache and avoid to have to lower case all paths 
before each file operation.

Can you try to set the perms correctly and tell me if it works out for you? 
Should work on any windows supported version.
 [2013-01-16 06:42 UTC] d at hp23c dot dk
In Windows, it _does not matter_ if it is C:\fOo or c:\foo. If you do not lowercase (or uppercase, or whatever) to compare, it is a bug.
 [2013-01-16 09:20 UTC] pajoye@php.net
It does matter. The reasons are:

1. Windows support case sensitive filesystems (in any modern versions)
2. the real path stat cache is case sensitive, for portability and performance, 
by design.

However, no matter how the case is, you have to set the attributes permissions. 
If it is not allowed to read the attributes, php won't be able to load that file 
or path. And again, it has absolutely nothing do with case sensitive paths.

Last but not least, if you see the bug status, it is still open as a bug, but it 
is about other issues caused by FindFirstFile, not the case sensitivity.
 [2013-03-05 12:08 UTC] mindless at mindless999 dot net
Issue still exists in 5.3.22

Workaround is to give the user under which the website is running (advanced) "list folder / read data" permissions on the parent folder.
this is the only permission required.
 [2013-03-05 12:12 UTC] pajoye@php.net
@mindless at mindless999 dot net

That's correct, I forgot to add this info to this bug report (present in another 
one). It is required to allow the underlying Windows API to get through the 
directories while it won't allow the user to access it.
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Wed Apr 16 04:02:11 2014 UTC