We have the following setup for a webserver: Windows Server 2008 R2 Standard, IIS 7.5.7600.16385, PHP 5.3.28, the HMVC framework we use is Kohana.
Kohana needs a cache directory to be writable in D:\inetpub\www\application\cache
(D:\inetpub\www\
is our webroot). We removed the cache dir at this location and created a symbolic link to a directory outside of the webroot: D:\cache
, which is writable.
It looks like the first user that is visiting the website gets the error "cache directory is not writeable", which is an error Kohana triggers, surprisingly, when it does not have permission to write in the directory. The second, third and so forth users do not get this error. The strange thing is that only this first user is keep getting this error, while the others never see it.
The solution for us was to use a directory junction.
I read a lot of documentation about the differences between a symbolic link and a directory junction, but I can't relate any to it to the error we got. The only thing I can think of is the fact that a symbolic link is processed on the client side, while a junction is processed on the server side.
The comment of Harry Johnston in this post points to two new links, but there we couldn't find a good explanation for our problem.
@Daan the fact that symbolic links cross SMB is documented in What's new in SMB?. I don't know of any documentation that explicitly states that junction points don't, but it is inherent in the way they are implemented and I did find Create the SYSVOL Root and Staging Areas Junction Point which otherwise wouldn't work. (Mostly though, it's just experience.)
Update:
I monitored the directories in process monitor and got the following result:
User: Test2, first user (here I got the error)
10:21:52.7311891 AM php-cgi.exe QueryOpen D:\inetpub\www\application\cache SUCCESS CreationTime: 8/28/2015 5:12:56 PM, LastAccessTime: 8/28/2015 5:12:56 PM, LastWriteTime: 8/28/2015 5:12:56 PM, ChangeTime: 8/28/2015 5:12:56 PM, AllocationSize: 0, EndOfFile: 0, FileAttributes: DRP
10:21:52.7313164 AM php-cgi.exe CreateFile D:\inetpub\www\application\cache SUCCESS Desired Access: Read Control, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, Impersonating: NL-COMPUTER1\Test2, OpenResult: Opened
10:21:52.7313552 AM php-cgi.exe QuerySecurityFile D:\inetpub\www\application\cache BUFFER OVERFLOW Information: Owner, Group, DACL
10:21:52.7313725 AM php-cgi.exe CloseFile D:\inetpub\www\application\cache SUCCESS
10:21:52.7314490 AM php-cgi.exe CreateFile D:\inetpub\www\application\cache SUCCESS Desired Access: Read Control, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, Impersonating: NL-COMPUTER1\Test2, OpenResult: Opened
10:21:52.7314729 AM php-cgi.exe QuerySecurityFile D:\inetpub\www\application\cache SUCCESS Information: Owner, Group, DACL
10:21:52.7314867 AM php-cgi.exe CloseFile D:\inetpub\www\application\cache SUCCESS
User: Test3, second user (here i don't got the error)
10:28:01.7973266 AM php-cgi.exe 5220 QueryOpen D:\inetpub\www\application\cache SUCCESS CreationTime: 8/28/2015 5:12:56 PM, LastAccessTime: 8/28/2015 5:12:56 PM, LastWriteTime: 8/28/2015 5:12:56 PM, ChangeTime: 8/28/2015 5:12:56 PM, AllocationSize: 0, EndOfFile: 0, FileAttributes: DRP
10:28:01.7974467 AM php-cgi.exe 5220 CreateFile D:\inetpub\www\application SUCCESS Desired Access: Read Data/List Directory, Synchronize, Disposition: Open, Options: Directory, Synchronous IO Non-Alert, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, Impersonating: NL-COMPUTER1\Test3, OpenResult: Opened
10:28:01.7974702 AM php-cgi.exe 5220 QueryDirectory D:\inetpub\www\application\cache SUCCESS Filter: cache, 1: cache
10:28:01.7974943 AM php-cgi.exe 5220 CloseFile D:\inetpub\www\application SUCCESS
10:28:01.7975657 AM php-cgi.exe 5220 CreateFile D:\inetpub\www\application\cache SUCCESS Desired Access: Generic Read, Disposition: Open, Options: Synchronous IO Non-Alert, Open Reparse Point, Attributes: n/a, ShareMode: None, AllocationSize: n/a, Impersonating: NL-COMPUTER1\Test3, OpenResult: Opened
10:28:01.7976098 AM php-cgi.exe 5220 FileSystemControl D:\inetpub\www\application\cache SUCCESS Control: FSCTL_GET_REPARSE_POINT
10:28:01.7976285 AM php-cgi.exe 5220 CloseFile D:\inetpub\www\application\cache SUCCESS
10:28:01.7977090 AM php-cgi.exe 5220 CreateFile D:\cache SUCCESS Desired Access: Read Control, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, Impersonating: NL-COMPUTER1\Test3, OpenResult: Opened
10:28:01.7977524 AM php-cgi.exe 5220 QuerySecurityFile D:\cache BUFFER OVERFLOW Information: Owner, Group, DACL
10:28:01.7977657 AM php-cgi.exe 5220 CloseFile D:\cache SUCCESS
10:28:01.7978337 AM php-cgi.exe 5220 CreateFile D:\cache SUCCESS Desired Access: Read Control, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, Impersonating: NL-COMPUTER1\Test3, OpenResult: Opened
10:28:01.7978573 AM php-cgi.exe 5220 QuerySecurityFile D:\cache SUCCESS Information: Owner, Group, DACL
10:28:01.7978703 AM php-cgi.exe 5220 CloseFile D:\cache SUCCESS
Does anyone know why the first user can't write in the directory when we use a symbolic link instead of a directory junction?