Differentiate each apache user and give permissions
If I understand your question right, your problem begins with the structure of the linux permission/user framework. Thus, the Apache process owning user is the one that is creating dirs and files when it is running your script.
If you need user separation for scripts, e.g.: you have different directories for different (virtual) hosts on your server and you don't want the script of one host is acting on data of a different host on the same (apache) server, then you should use 'mpm_itk_module' instead of the more common 'mpm-prefork' apache.
Using this you can go and define the user/group that apache is using when it executes any scripts and e.g. creates directories just by this command for each virtual host entry in the httpd.conf:
<IfModule mpm_itk_module>
AssignUserId USER GROUP
</IfModule>
If you really want to create different directories from ONE script execution, you need the apache process to be owned by root.root and then the script needs to set the permissions and owners for each directoy the way you want.
But it is never a good idea to run even the best scripts on a webserver as root, as you might fail to think of any risk.
The user/right separation by vhosts seems to be a much saver way in my view.
Another point - PHP only - is suPHP -> http://www.suphp.org
EDIT:
Ok, I had a look at your site and even if I can't speak spanish, it looks like you have just one website, acting for different users coming allways thru this webpage. So where is the need for user separation on linux filesystem permissions? You can restrict everything by your application with no need for filesystem users. Even if you give e.g. additional ftp access - restrict it e.g. with proftpd it has its own chroot mech for different users.
You should have to care about filesystem rights only if you can't control who is executing what. Thats a common problem on a multidomain host which you could solve with the mpm_itk_module I mentioned.
Maybe you should describe your situation a little bit more?
EDIT 2:
As suggest in the coment, if you ONLY use apache to give the users access to the files for uploading/manipulation, then just put the files outside(!) the documentroot tree of apache and create simple database to know which file is owned by which user:
user a | file parentdir/filename
This could be an easy table and your php code gives a list to the user from the database which file he is able to see/manipulate and your code does the work as intended by the user action.
As long as you don't give the user access to the files by other services (ftp, ssh, etc.) there is NO need to work with linux user rights at all. Just take care to place the files outside the documentroot of the server so that only your php code has access to the files by the rights of the apache user of your server.
EDIT 3:
Haha, now finally I got your problem after I read a similar post of you: (How can an Apache user write files when having permissions to do it?) In this case (with REALLY anonymous users on your webpage) you have NO chance to solve this at all. Every visitor is handled as the same one without authentication. And as I assumed in my last EDIT and commented in the similar post: no need to handle with linux file permissions at all.
YOUR SOLUTION ;) : You need to do the file manipulation in one sessions with session-ids while the user is visiting your page. So your code needs to handle the relation between the visitor (the session-id) and the file he uploaded with this session-id. Using a session-id that is valid as long the visitor is online is the best way to do this. And again - no need for filesystem permissions.... ;)
The second way is with authed users as suggested before: Create a db table with users/passwords to login the webpage (not the server) and another table that holds the user/file relations. Than, after he logs into the webpage, work again with sessions to allow the user accessing/manipulate already uploaded files.
I can that you run apache with mod_php. So then it means that your PHP instance work under apache instance and have apache USER and GROUP. You can create folder and can change owner of this folder but owner must be user in you system (not apache or same virtual user).
But you can store in every directory file for example ".permitions" and put inthat file virtual owner. Next you need filter every write (delete,rename, etc...) attempt to this directory and compare your virtual user and user that stored in .permitions file.
Sample Class (not full but it is more than enough to understand idea):
class UserDirs {
private $path='/home/vusers';
public function mkdir($user){
$d = $this->path.'/'.md5($user);
mkdir($d);
file_put_contents($d."/.owner",$user);
}
public function checkOwner($user, $dirname){
$f = $dirname."/.owner";
$virtual_owner = file_get_contents($f);
return $user === $virtual_owner;
}
}
$d = new UserDirs()
$d->mkdir("foo","bar");
echo $d->checkOwner("foo1","bar") === true ? "OK":"FAIL";
echo $d->checkOwner("foo","bar") === true ? "OK":"FAIL";
You can encapsulate all that you need in this class to work with UserDirs and extend class depending your requirement.
Your users do not have system accounts. It probably is not feasible to create those accounts either. Therefore, I'd recommend managing all of this via the Web UI.
Continue to create your directories as you are. The permissions are fine. Your user interface needs to change though, to only show that user's directory or files. I assume you have a database associated with this page. Associate the usernames and the randomly generated directory name with the user. If someone attempts to go to the direct path and they are NOT the user associated with that directory, kick them back to the login screen.
To illustrate, I created an account named test
and was presumably given a unique directory. If I log out, I should not be able to visit that directory because your code would see that
- I'm not logged in and therefore don't have access to that directory
If I were to login as test2
and visit the directory of test
, your code should see that
- I'm not the owner of the directory being visited and should therefore be redirected as appropriate.
You need to add a function that checks the directory the user is visiting and compare it to the directory associated with the user. If they two match, allow them to proceed. If they don't match, redirect the user.