I'm having a problem with a PHP website running on IIS 7 on Windows Server 2008.
There is one line of code calling mkdir which is erroring and the error log reads:
"... permission denied ..."
I have ruled out anything to do with folder permissions (I have tried multiple groups: Everyone, Users, IUSR, Network Service etc. with no luck).
I need to know how mkdir works, does it check the read-only attribute of the parent folder?
If so, then this could be the root of the problem as all folders in Windows Server 2008 are marked as "Read Only" and the checkbox is greyed-out - Microsoft say it is "by design" but I think it is really "bad design".
Please help.
P.S. The line of code which errors can be found here https://github.com/LimeSurvey/LimeSurvey/blob/070d255ba381d7abcd231d7c9e0c7d11f5578c97/admin/templates.php#L1182 it is line 1182.
SOLUTION:
- It was a permissions issue after all!
- We were applying permissions to the wrong folder (smacks hand to forehead)
- There are two "Templates" folders: /Templates and /Uploads/Templates
- /Template is for default templates whereas /Uploads/Templates is for user-created ones
- We gave the "Users" group r/w/execute/modify permissions to /Uploads/Templates folder
- Whereas previously we were applying permissions to /Templates
- To debug this I used
echo
to output the $target
value
LESSONS LEARNT:
- Always read the error message - it said "permission denied" and I didn't believe it
- Don't assume the obvious to be true - /Templates wasn't the right folder
- If the code is erroring then debug the code and don't try to guess the problem
- Debug the code using simple techniques such as outputting variable values - e.g. echo
- Listen to the majority - most people here were right in saying IT IS A PERMISSIONS ISSUE!
- Most errors have a simple fix - don't go looking for something complex
Bounty awarded to @BOMEz because of the useful quote from mkdir()
documentation which indicated that I should double-think the permissions. @BOMEz also provided a tailored answer and interacted with me via comments which helped.
to:
if(mkdir($target))
Windows ignores the mode option. Might be some weird bug causing it to fail.
Additionally for your $target variable could you try forcing it to link to the full Windows path? Such as C:\Program Files\ IIS\...
I've ran into situations with windows before where access was denied attempting to use a relative path, but the full path works just fine.
EDIT:
Looking at the comments on the documentation for mkdir() one commenter mentions that you might also need to add execute permissions to the user:
If you're getting a Permission Denied error, but are certain the
permissions and ownership where you are trying to create the directory
are correct, check again:
The location where you are trying to create the directory in must have
the Execute permission for the owner trying to create it, regardless
of if the folder is Readable, or Writable.
This may be obvious to some, but was not to me at first. Hopefully
this will save you the trouble I went through.
Since you didn't mention a control panel of any sort I'm going to assume you have access to the server either physical or remote desktop. I'm also going to assume you checked your php.ini settings.
That being said, there is a work around for some of these permission problems.
You will need to create an administrator account (and add it to the administrators group) for this site to use or simply use your administrator credentials.
- Open the IIS manager
- Expand Sites
- Highlight the site in question
- On the right side of the screen click 'Basic Settings', a dialog box should pop up.
- Click the button at the bottom that says 'Connect as...'
- Select 'Specific user' and then click the 'Set...' button
- Type the user name and password of either your account or the account you created.
- Hit 'Ok' button 3 times.
This is a bit of a sledge hammer fix since it will grant full unrestricted access to the file system from your scripts.
If you created a new user and you want to maintain some level of script security then you can try pulling the user out of the administrators group and then giving it full permissions on only that site with the following:
- Highlight site
- Right-Click, Edit Permissions
- Security Tab
- Click 'Edit' button
- Click 'Add' button
- Click 'Advanced' then 'Find Now'
- Double click on the user you created
- Click 'Ok'
- Highlight your user, tick the box under allow that is next to full control
- click 'Ok' twice
If asked, select that you want to apply to all directories and files.
~
If your still having issues then there is a good chance your php setup is configured incorrectly or corrupt. (Safe mode turned on maybe?)
Following is the explanation of permissions.
Read
- On a File: this means reading content of the files
- On a Directory: it means viewing the contents of the directory, namely, being able to use
ls
or dir
Write
- On a File: this means being able to edit content of the files
- On a Directory: it means being able to create/modify content of the directory, namely making new files or folders in that directory.
Execute
- On a File: this means executing the code from the file (for scripts/executables)
- On a Directory: it means, entering the directory. You can not
cd
into that directory without this permission.
--
So, now that makes it clear the answer to your problem (as you guessed correctly), for making new directory or writing new files into the directory you need write permission on that directory. So for making folders into say C:/your_folder/
you need, write
and execute
permissions on that folder. (Yes you need execute too, as apparently for mkdir
you need to go inside the folder first.)
One of the issues that we run into quite often is that files have been moved from any location to the websites location, maintaining the original permissions instead of inheriting the permission needed by the application pool user of the pool that's beeing used by the website.
So one good thing to try would be to right click your document root folder, go to properties and then the security tab. Press the advanced button, check the checkbox a "Replace permission entries on all child objects with entries shown here that apply to child objects". That way you can atleast be sure all your permissions are set on all subfolders and files.
We nerver had any problems with the read only attribute, even though this is checked for all our folders. (grayed out/checked). So i doubt that is your problemen.