Resetting File or Folder Permissions Using Yum

While setting the group file or folder permissions and ownership to /var/www, sometimes we may accidentally update the wrong folder, like to the parent folder of /var instead of /var/www.

In order to restore the default file or folders permissions in RPM-based system, there is a built-in option to revert the changes quickly compare to DEB-based system. Yup, this is probably one of the missing feature if we compare both packaging system.

First, let's find the RPM package name that contains the /var/www/html folder.

Using the rpm command.
$ time rpm -qf /var/www/html
$ time rpm -qf /var/www/html
httpd-2.4.10-1.fc20.x86_64
real    0m0.025s
user    0m0.018s
sys     0m0.006s

Using the yum command which gave us four packages and took around 1-plus BLOODY minutes.
$ time yum whatprovides '/var/www/html'
real    1m23.865s
user    0m19.660s
sys     0m0.901s

Now that is something we can improve by using cached result through -C option. Let's try again. But then again, the results are still not entirely accurate.
$ time yum -C whatprovides '/var/www/html'
......
real    0m0.350s
user    0m0.257s
sys     0m0.050s

$ ls -ld /var/www/html/
drwxr-sr-x 1 root apache 40 Oct  4 15:05 /var/www/html/

Unfortunately, yum does not include support for reverting ownership and permissions of any installed files or folders.

Reset the ownership,
$ sudo rpm --setugids httpd
$ ls -ld /var/www/html
drwxr-sr-x 1 root root 40 Oct  4 15:05 /var/www/html/

However, resetting the permissions does not seems to remove back the setguid flag. Weird. Unfortunately, I can't google for any good explanation of such problem.
$ sudo rpm --setugids httpd
$ ls -ld /var/www/html
drwxr-sr-x 1 root root 40 Oct  4 15:05 /var/www/html/

Setting Apache Document Root With setgid

When you don't understand or remember the fundamental of GNU/Linux file system permissions, you'll tend to do things in an unproductive way. For example, repeatedly and explicitly update the /var/www/ folder file permissions to the Apache's group (www-data or apache).

The proper, alternative, and convenient way of setting web root, /var/www permissions are as follows:

Settings the folder permission to Apache's user group.
$ sudo chgrp apache /var/www -R
$ sudo chmod 775 /var/www -R
$ sudo chmod g+s /var/www

Allow the $USER to fully control of the web root.
$ sudo useradd -G apache $USER
$ sudo chown $USER /var/www/

Now, long grandma story. By default, the file permissions of Apache's web root directory in CentOS or Fedora are only accessible by all but writable by root user.
$ ls -l /var/www/
total 0
drwxr-xr-x 1 root root 0 Jul 23 06:31 cgi-bin/
drwxr-xr-x 1 root root 6 Oct 4 14:30 html/

Change to folder group ownership to apache user so we can install and run any web application using that user. Otherwise most web application will complain about write permissions to the folder, especially for file uploading.
$ sudo chgrp apache /var/www -R
$ ls -l /var/www/
total 0
drwxr-xr-x 1 root apache 0 Jul 23 06:31 cgi-bin/
drwxr-xr-x 1 root apache 6 Oct 4 14:30 html/

Even we've set the group ownership to apache user, any new file or folder creation will still default to root user as we're using the sudo command.
$ sudo mkdir /var/www/html/foo.d
$ sudo touch /var/www/html/foo.f
$ ls -l /var/www/html/
total 0
drwxr-xr-x 1 root root 0 Oct 4 15:03 foo.d/
rw-r--r- 1 root root 0 Oct 4 15:03 foo.f

Hence, in order to retain or inherit the group id (apache) of the parent folder in /var/www, we've to use setgid [4].
$ sudo chmod g+s /var/www/html/

Another way of setting the folder permissions using the numerical method is:
$ sudo chmod 2775 /var/www/html -R

Notice the 's' flag on the group permissions.
$ ls -ld /var/www/html
drwxr-sr-x 1 root apache 20 Oct 4 15:04 /var/www/html/

Create another folder and file in /var/www folder again. Notice the group permissions inherit the group id in /var/www.
$ sudo mkdir /var/www/html/bar.d
$ sudo touch /var/www/html/bar.f
$ ls -ltU /var/www/html
total 0
drwxr-xr-x 1 root root 0 Oct 4 15:03 foo.d/
rw-r--r- 1 root root 0 Oct 4 15:03 foo.f
drwxr-sr-x 1 root apache 0 Oct 4 15:05 bar.d/
rw-r--r- 1 root apache 0 Oct 4 15:05 bar.f

Using the namei command to show the permissions for each components in the file path.
$ namei -l /var/www/html/foo.d/
f: /var/www/html/foo.d/
drwxr-xr-x root root /
drwxr-xr-x root root var
drwxr-xr-x root apache www
drwxr-sr-x root apache html
drwxr-xr-x root root foo.d

$ namei -l /var/www/html/bar.d
f: /var/www/html/bar.d
drwxr-xr-x root root /
drwxr-xr-x root root var
drwxr-xr-x root apache www
drwxr-sr-x root apache html
drwxr-sr-x root apache bar.d

Namei: File Permissions Listing Tool

While setting up the Apache web server, occasionally we’ll encounter the file permission issues in the document root folder, especially when symlink involved. This console app, namei, which is part of util-linux, provides a quick view of the file permissions of each component of the resolved full path. Quite a useful tool especially for those who just venture into GNU/Linux and haven’t fully grasp the file permissions in the system.

For example, listing of the file permission of the folders and file of SSH private key.
$ namei -l ~/.ssh/id_rsa 
f: /home/ang/.ssh/id_rsa
drwxr-xr-x root root /
drwxr-xr-x root root home
drwx------ ang ang ang
drwx------ ang ang .ssh
-rw------- ang ang id_rsa

First, let's create a sample symlink.
$ sudo ln -s /tmp /var/www/html/tmp

Tracing to the endpoint of the symlink.
$ namei /var/www/html/tmp
f: /var/www/html/tmp
d /
d var
d www
d html
l tmp -> /tmp
d /
d tmp

Similarly, but showing the permissions of each component of the resolved full path.
$ namei -l /var/www/html/tmp
f: /var/www/html/tmp
drwxr-xr-x root root /
drwxr-xr-x root root var
drwxr-xr-x root root www
drwxr-xr-x root root html
lrwxrwxrwx root root tmp -> /tmp
drwxr-xr-x root root /
drwxrwxrwt root root tmp

Resetting GNU/Linux File or Folder Permissions

While setting the group file or folder permissions and ownership to /var/www, sometimes we may accidentally update the wrong folder, like to the parent folder of /var instead of /var/www.

In order to restore the default file or folders permissions in RPM-based system, there is a built-in option to revert the changes quickly compare to DEB-based system. Yup, this is probably one of the missing feature if we compare both packaging system.

First, let's find the RPM package name that contains the /var/www/html folder. Using the rpm command.
$ time rpm -qf /var/www/html
$ time rpm -qf /var/www/html
httpd-2.4.10-1.fc20.x86_64
real    0m0.025s
user    0m0.018s
sys     0m0.006s

Using the yum command which gave us four packages and took around 1-plus BLOODY minutes.
$ time yum whatprovides '/var/www/html'
real    1m23.865s
user    0m19.660s
sys     0m0.901s

Now that is something we can improve by using cached result through -C option. Let's try again. But then again, the results are still not entirely accurate.
$ time yum -C whatprovides '/var/www/html'
......
real    0m0.350s
user    0m0.257s
sys     0m0.050s

$ ls -ld /var/www/html/
drwxr-sr-x 1 root apache 40 Oct  4 15:05 /var/www/html/

Unfortunately, yum does not include support for reverting ownership and permissions of any installed files or folders. Reset the ownership.
$ sudo rpm --setugids httpd
$ ls -ld /var/www/html
drwxr-sr-x 1 root root 40 Oct  4 15:05 /var/www/html/

However, resetting the permissions does not seems to remove back the setguid flag. Weird. Unfortunately, I can't google for any good explanation of such problem.
$ sudo rpm --setugids httpd
$ ls -ld /var/www/html
drwxr-sr-x 1 root root 40 Oct  4 15:05 /var/www/html/