I’ve been continuing work on Netsoc’s public user-facing server Leela. Previously, we’d relied heavily on using /etc/skel to properly layout user directories and their subfolders. However, we allow users to host public sites from the public_html folder on {user}.netsoc.co which meant that periodically, we had to run a script to alter permissions on user folders to allow Apache to access their public_html while not allowing other users access to their home directory.

To achieve this, all user home directories have to be owned by www-data and have at least 710 permissions (rwx –x —). Recently, I’ve been investigating PAM as we use it to authenticate users off LDAP and it’s the perfect entry-point for automating our home dir needs. Lo and behold, there’s a method to do exactly what we need!

First, we need to write a script to perform our fixes and checks. However, this is going to be run every time a user logs in and not just when the user logs in for the first time. As such, every action is wrapped in a check to make sure it’s necessary. Below is our /usr/local/bin/check_homedir_perms.sh:


#!/bin/bash

home_dir="/home/users/$PAM_USER"
pub_html="$home_dir/public_html"

# Give www-data group access to the user's home
# directory
user_dir_group=`stat -c "%G" $home_dir`
if [[ "$user_dir_group" != "www-data" ]]; then
    chgrp www-data $home_dir
fi

# Ensure user directory is only accessible to user
# and www-data
user_dir_perms=`stat -c "%a" $home_dir`
if [[ "$user_dir_perms" != "710" ]]; then
    chmod 710 $home_dir
fi

# If public_html doesn't exist, create it
if [ ! -d $pub_html ]; then
    mkdir $pub_html
    chown $PAM_USER:www-data $pub_html
fi

# public_html has to be owned by www-data for
# web access
pub_html_group=`stat -c "%G" $pub_html`
if [[ "$pub_html_group" != "www-data" ]]; then
    chgrp www-data $pub_html
fi

Next, we have to plug this into PAM. As part of this, it’s always good to have lots and lots of logging. I’ve left the logging lines out of the script above but I’d advise an echo accompanied by a timestamp and a message. Simply add the following to the end of /etc/pam.d/common-session:


session optional    pam_exec.so debug log=/netsoc/logs/pam_exec.log /usr/local/bin/create_homedir_perms.sh $PAM_USER

Leave a Reply