In short code executed by PHP as user apache, doesn't seem to have write access to groups which apache is a member of, that apache can write to on a shell.
So I have a user apache on a production server. If I run id apache
I see apache as a member of several groups, including groupa
. If I grep apache /etc/groups
I can see that those groups memberships are not defined locally, and are coming from LDAP.
I have a folder /u/dir
which is owned by root:groupa
with permissions g+rws
If I run sudo su -s /bin/bash -c "mkdir /u/dir/subdir" apache
it works fine, apache does have permission to create files/folders in /u/dir
However if I create and run the following script in PHP it fails with permission denied: `
If I run id apache
from shell, it shows: uid=48(apache) gid=123(groupa) groups=123(groupa)
However if I run the following from PHP I get a different result:-
<?php echo shell_exec("id");?>
uid=48(apache) gid=48(apache) groups=48(apache)
Any ideas why PHP (and presumably the Apache/httpd process) don't have all the group memberships that they should, and how I can fix it?
I did do a test, before anyone suggests it; If I add apache to a group in /etc/groups and restart apache, then the above call, shows the new group, but it's not picking up groups that apache is a member of via LDAP (and this server is one of a pool, accessing the remotely mapped /u so I don't want to have to manually duplicate each group locally on each server)
I'll also add that I suspect our servers are getting id
info from LDAP via sssd
Seeing: https://unix.stackexchange.com/questions/409843/how-to-get-the-supplementary-groups-ids-of-a-process
If I add <?php echo shell_exec("cat /proc/$$/status"); ?>
I can see that the httpd process hasn't picked up any of the sssd
groups, just the local ones.
Edit for Clarity:
For clarity I should add I tested adding apache
to local group (300)testgroup
, then ran <?php echo shell_exec("id");?>
again:-
uid=48(apache) gid=48(apache) groups=48(apache),300(testgroup)
So whilst it's clear it's the core process permissions which matter, for some reason when I startup httpd
(as apache:apache
), it is pickup up the local groups which apache
is a member of and adding those to the subgroup ('Groups' in /proc/$$/status
), it isn't picking up the groups that apache
is a member of via sssd. That's the puzzle.
Turns out I didn't have a problem at all. Someone had change the primary group of the apache user to my remote group (groupa in my example), so when apache ran as apache:apache according to the httpd.conf file, it was overwriting that primary group. As apache wasn't actually a member of groupa other than that, it was appearing to drop the group.