Jump to content

File permission issues


Recommended Posts

Maybe never mind.  Just noticed ssphpd doesn't have a group...

ps.  do I have the umask part right?

Edit 2.  No, it didn't help...

I have two users (ssphpd and apache) which will need to write files to a given directory and its subdirectories.  My intent was to set them up with ssphd's group and use the setgid to make all future files and directories inherit that group.   Not sure, but I don't think I have this right yet as I indicate at the end of this post.

[michael@bb5 ~]$ sudo useradd -r ssphpd
[michael@bb5 ~]$ sudo usermod -aG wheel ssphpd
[michael@bb5 ~]$ sudo usermod -aG wireshark ssphpd
[michael@bb5 ~]$ sudo usermod -aG ssphpd apache
[michael@bb5 ~]$ groups apache
apache : apache ssphpd
[michael@bb5 ~]$ groups ssphpd
ssphpd : ssphpd wheel wireshark
[michael@bb5 ~]$
[michael@bb5 ~]$ sudo chmod g+rwx -R /var/www/~/storage
[michael@bb5 ~]$ sudo chown michael.ssphpd -R /var/www/~/storage
[michael@bb5 ~]$ sudo chmod g+s /var/www/~/storage

My script to write this files is below:

    public function setFile(array $file, string $nameAlias):void {
        $path=$this->getPath($nameAlias, true);
        $this->moveTo($file['tmp_name'], $path);
    }

    private function getPath(string $name, bool $create):string {
        //$name is 20 characters
        $p1=$this->uploadDirectory.'/'.substr($name,0,2);
        $p2=$p1.'/'.substr($name,2,3);
        $p3=$p2.'/'.substr($name,5,4);
        $old_umask = umask(0);
        if($create) {
            if(!file_exists($p1)){mkdir($p1, 0775);}
            if(!file_exists($p2)){mkdir($p2, 0775);}
            if(!file_exists($p3)){mkdir($p3, 0775);}
        }
        umask($old_umask);
        return $p3.'/'.substr($name,9);
    }

    private function moveTo(string $tmpname, string $path):void {
        syslog(LOG_ERR, "attempting to move $tmpname to $path");
        $uid = posix_getuid();
        syslog(LOG_ERR, "user PHP is running as: $uid - ".posix_getpwuid($uid)['name']);
        $gid = posix_getgid();
        syslog(LOG_ERR, "group PHP is running as: $gid - ".posix_getpwuid($gid)['name']);
        $this->test($tmpname);
        $this->test(substr($path,0,-12));
        syslog(LOG_ERR, move_uploaded_file($tmpname, $path)?'success':'failure');
    }

    private function test(string $file):void {
        syslog(LOG_ERR, "$file is writable: ".(is_writable($file)?'yes':'no'));
        $uid=fileowner($file);
        syslog(LOG_ERR, "$file owner: $uid - ".posix_getpwuid($uid)['name']);
        $gid=filegroup($file);
        syslog(LOG_ERR, "$file group: $gid - ".posix_getpwuid($gid)['name']);
        $perms=fileperms($file);
        syslog(LOG_ERR, "$file permissions: $perms - ".$this->formatPerms($perms));
    }

However, as seen, not only can only apache write files, the newly created directories are displaying apache's group instead of ssphp's group.

Any ideas?

Jun 06 19:40:29 bb5.net Server[8485]: attempting to move /tmp/DL_TS_6n0kmr to /var/www/dev/storage/uploads/45/699/ed6c/d15fd6959b6
Jun 06 19:40:29 bb5.net Server[8485]: user PHP is running as: 989 - ssphpd
Jun 06 19:40:29 bb5.net Server[8485]: group PHP is running as: 986 -
Jun 06 19:40:29 bb5.net Server[8485]: /tmp/DL_TS_6n0kmr is writable: yes
Jun 06 19:40:29 bb5.net Server[8485]: /tmp/DL_TS_6n0kmr owner: 989 - ssphpd
Jun 06 19:40:29 bb5.net Server[8485]: /tmp/DL_TS_6n0kmr group: 986 -
Jun 06 19:40:29 bb5.net Server[8485]: /tmp/DL_TS_6n0kmr permissions: 33152 - rrw-------
Jun 06 19:40:29 bb5.net Server[8485]: /var/www/dev/storage/uploads/45/699/ed6c is writable: yes
Jun 06 19:40:29 bb5.net Server[8485]: /var/www/dev/storage/uploads/45/699/ed6c owner: 989 - ssphpd
Jun 06 19:40:29 bb5.net Server[8485]: /var/www/dev/storage/uploads/45/699/ed6c group: 986 -
Jun 06 19:40:29 bb5.net Server[8485]: /var/www/dev/storage/uploads/45/699/ed6c permissions: 16893 - drwxrwxr-x
Jun 06 19:40:29 bb5.net Server[8485]: failure

Jun 06 19:40:32 bb5.net Api[6981]: attempting to move /tmp/phpy1CRQR to /var/www/dev/storage/uploads/ec/911/7ab7/c73065bff0b
Jun 06 19:40:32 bb5.net Api[6981]: user PHP is running as: 48 - apache
Jun 06 19:40:32 bb5.net Api[6981]: group PHP is running as: 48 - apache
Jun 06 19:40:32 bb5.net Api[6981]: /tmp/phpy1CRQR is writable: yes
Jun 06 19:40:32 bb5.net Api[6981]: /tmp/phpy1CRQR owner: 48 - apache
Jun 06 19:40:32 bb5.net Api[6981]: /tmp/phpy1CRQR group: 48 - apache
Jun 06 19:40:32 bb5.net Api[6981]: /tmp/phpy1CRQR permissions: 33152 - rrw-------
Jun 06 19:40:32 bb5.net Api[6981]: /var/www/dev/storage/uploads/ec/911/7ab7 is writable: yes
Jun 06 19:40:32 bb5.net Api[6981]: /var/www/dev/storage/uploads/ec/911/7ab7 owner: 48 - apache
Jun 06 19:40:32 bb5.net Api[6981]: /var/www/dev/storage/uploads/ec/911/7ab7 group: 48 - apache
Jun 06 19:40:32 bb5.net Api[6981]: /var/www/dev/storage/uploads/ec/911/7ab7 permissions: 16893 - drwxrwxr-x
Jun 06 19:40:32 bb5.net Api[6981]: success

 

Edited by NotionCommotion
Link to comment
Share on other sites

Are you sure both users need to be able to write to that directory? Normally it's just one: the PHP user (assuming you're running with php-fpm). The web server should be content with the default 0644 permissions that would let it read.

Link to comment
Share on other sites

39 minutes ago, requinix said:

Are you sure both users need to be able to write to that directory? Normally it's just one: the PHP user (assuming you're running with php-fpm). The web server should be content with the default 0644 permissions that would let it read.

Yes, I am pretty sure that both users need to be able to write to that directory.  One of the users is to allow files to be uploaded via the web server.  PHP is currently configured with mod_php  (probably should change one of these days) so the apache user needs permission, but even if I change to php-fpm, then the php-fpm user would need permission.  I then have a totally different socket server application which needs permission, and while I could run it using the apache or php-fpm user, ideally it would run as a different user. 

Regardless of whether I should use one or multiple users, can you see any reason why using more than one user would be an issue?

Link to comment
Share on other sites

Maybe I just don't understand it well enough, but I've always felt like the traditional linux file permissions system became inadequate quickly.   I have all my servers setup now with PHP-FPM and a separate pool for each user.  Each site is configured to use the pool for which ever user owns that site so permissions mostly become a non-issue.   The user PHP is using is the same as the user for SSH, SFTP, etc.  Possibly not the most secure solution, but it's much simpler to setup and deal with.

Regarding your issue, there are a couple things to note regarding the set-guid bit on directories.

Quote

2. only affects the group ID of new files and subdirectories created after the setgid bit is set, and is not applied to existing entities.

3. does not affect group ID of the files that are created elsewhere and moved to the directory in question. The file will continue to carry the group ID that was effected when and where it was created.

You only show applying g+s to the /var/www/~/storage/ directory, but it appears you have an uploads directory under that.  Was that directory already there?  If so, you need to apply the bit to it as well.  Likewise with any other pre-existing directories that you want to have the bit set.  You can't just apply it to a point in the path and have it automatically affect everything under that point.

The uploaded temporary file is going to be owned by apache.  Just moving it over to your storage directory won't change that.  You'll have to copy it instead, which may be undesirable as it could be slow, particularly for large files.

Alternatively, since you made apache part of the ssphpd group you could just chgrp the file after moving it.  Likewise with the directories after making them.

 

Link to comment
Share on other sites

Thanks kicken,

It was my understanding that the set-guid bit would apply to downstream directories, but as you indicate I was mistaken.  I just made a new folder with the bit set, and then as another user added directories and see how the bit is set in those directories.  But my storage directory just has the root directory set, so this will obviously not work.  Any reason recursively adding the bit won't work for an existing directory?

And your point about copied files preserving their original guid makes total sense now that you said it.

I don't like the idea of copying files.  I also would rather not use the chgrp solution.  But I could create the new files in some directory other than /tmp and have the set-guid bit set on this new directory.  Having apache creating uploaded files to this new directory sounds like a bad idea, but it would be simple to have ssphpd create its files there.  This would require me to assign ssphpd the apache group instead of how I was originally going to do it, but doesn't seem like a big deal.

Link to comment
Share on other sites

I'd assume when creating a new file/directory the system only consults the immediate parent when checking if the set-guid bit is set.  As such, having it set at a higher level isn't going to make a difference.

You could recursively set it using the -R flag like you did in the previous commands, but that would set it on files too which you probably don't want.

You can use find to set it on just the directories within a given path.  That'll get it applied to everything currently existing and then new stuff in the future should properly inherit it.

find /var/www/~/storage -type d -exec chmod g+s {} \;

 

Link to comment
Share on other sites

7 hours ago, kicken said:

You could recursively set it using the -R flag like you did in the previous commands, but that would set it on files too which you probably don't want.

I didn't think the seggid would be applicable to files but only directories, but evidently it "kind of" does.  It appears a capital S means the setgid is set but doesn't do anything.  Regardless, will definitely go with find.  Thanks

drwxrwsr-x 3 michael michael 37 Jun  7 10:08 bbb
-rw-rwSr-- 1 michael michael  0 Jun  7 10:08 x


 

Link to comment
Share on other sites

I need to do a better job reading the documentation.

move_uploaded_file ( string $filename , string $destination ) : bool

This function checks to ensure that the file designated by filename is a valid upload file (meaning that it was uploaded via PHP's HTTP POST upload mechanism). If the file is valid, it will be moved to the filename given by destination.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.