Simple Bash Script to Fix Account Permissions

4.8/5 - (23 votes)

This is a simple bash script I wrote to fix the permissions and ownership of files within a cpanel account. To use, simply copy the script your server, chmod 755, and pass the usernames as arguments:

./fixperms user1 user2 user3

You can also run a server-wide loop like this:

for i in `ls -A /var/cpanel/users` ; do ./fixperms $i ; done

Below is the script, but I recommend downloading it from here to ensure that the formatting is correct.

#!/bin/bash
# Script to fix permissions of accounts
# Written by: Vanessa Vasile 5/13/10
# http://thecpaneladmin.com

if [ "$#" -lt "1" ];then
  echo "Must specify user"
  exit;
fi

USER=$@

for user in $USER
do

  HOMEDIR=$(egrep "^${user}:" /etc/passwd | cut -d: -f6)

  if [ ! -f /var/cpanel/users/$user ]; then
    echo "$user user file missing, likely an invalid user"
  elif [ "$HOMEDIR" == "" ];then
    echo "Couldn't determine home directory for $user"
  else
    echo "Setting ownership for user $user"
    chown -R $user:$user $HOMEDIR
    chmod 711 $HOMEDIR
    chown $user:nobody $HOMEDIR/public_html $HOMEDIR/.htpasswds
    chown $user:mail $HOMEDIR/etc $HOMEDIR/etc/*/shadow $HOMEDIR/etc/*/passwd

    echo "Setting permissions for user $USER"

    find $HOMEDIR -type f -exec chmod 644 {} ; -print
    find $HOMEDIR -type d -exec chmod 755 {} ; -print
    find $HOMEDIR -type d -name cgi-bin -exec chmod 755 {} ; -print
    find $HOMEDIR -type f ( -name "*.pl" -o -name "*.perl" ) -exec chmod 755 {} ; -print
  fi

done

chmod 750 $HOMEDIR/public_html

if [ -d "$HOMEDIR/.cagefs" ]; then
  chmod 775 $HOMEDIR/.cagefs
  chmod 700 $HOMEDIR/.cagefs/tmp
  chmod 700 $HOMEDIR/.cagefs/var
  chmod 777 $HOMEDIR/.cagefs/cache
  chmod 777 $HOMEDIR/.cagefs/run
fi

46 Comments

  1. XxRa3eDxX Reply

    Why not use this ^_^

    find /home/*/public_html/* -type f -exec chmod 644 {} ;

    find /home/*/public_html/* -type d -exec chmod 755 {} ;

    we can specify user by replace * with usename

    and we can use this to make chown for all websites

    for i in `ls /var/cpanel/users` ; do chown -R $i.$i /home/$i/public_html/* ; done

    Thanks for you
    Al-Ra3eD.CoM

  2. Matt Reply

    I already wrote this very script several years ago ….

    However, my script doesn’t have all the obvious and extremely dangerous exploitable security issues that this script has as well as the bug in your user matching in the code you posted above.

    Contact me and I will help you fix the script

    –Matt

    1. Vanessa Reply

      @Matt Improvements are always welcome – feel free to email me at admin[at]v-nessa.net and we’ll take a look. Do you have a link to the script you wrote, and I’ll post that one as well?

  3. Hosting en Colombia Reply

    Hello Vannesa, after dealing with this issue by hand with no success i have tried your script and it did the job nicely and my hosting user again can create email accounts. Many Thanks from Colombia.

  4. Hadi Naser Reply

    Thank you Vanessa, this is great script, it saves me huge time fixing over 300 websites 🙂

    All the best
    Hadi

  5. Pingback: Server hacked! | HostGator Coupons Code

  6. Guillermo Calvo Reply

    Hi Vanessa

    Great time saver script !!

    I found a little bug today while I was using this script

    If you have several account names like albert, alberto,albert123 and you execute ./fixperms albert the script will change the ownership of all accounts names starting with albert

    The fix is very simple:

    HOMEDIR=$(grep -w $user /etc/passwd | cut -d: -f6)

    I added the “-w” to the grep command

    Thank You

    Guillermo

  7. Mohamd Anouar Reply

    i think is better to do the grep or the directory user with grep -w , is there are two users with diiference of 1 letter in the end , the script handle in error home directory , exemple , we have user1 and user11

    for example ./fixperms user11 , the script work on the directory user1 .

    so is better to change the line to

    HOMEDIR=$(grep -w $user /etc/passwd | cut -d: -f6)

  8. Bozso Reply

    Thanks for the script. Great job.
    I restored 200+ home directories when i realized that everything was owned by root. With a little modification of your script i was able to chown user directories back to users.

  9. Chris Reply

    There is a serious bug in this code:
    HOMEDIR=$(egrep ^${user} /etc/passwd | cut -d: -f6)
    What if the user is named “roo”? You’ll match the root user and chown/chmod /root.
    What if the user is named ‘hal’? You’ll match the ‘halt’ user and chown/chmod /sbin.

  10. Benjamin Purcell Reply

    HOMEDIR=$(egrep ^${user} /etc/passwd | cut -d: -f6)

    What if you have a user named roo? or hal? or tom?

    root@*** [7321 16:01:46 ~]# user=roo
    root@*** [7320 16:01:44 ~]# egrep ^${user} /etc/passwd | cut -d: -f6
    /root
    root@*** [7321 16:01:46 ~]# user=hal
    root@*** [7322 16:01:53 ~]# egrep ^${user} /etc/passwd | cut -d: -f6
    /sbin

    Just saying…

    Use this instead:

    egrep “^${user}:” /etc/passwd | cut -d: -f6

  11. Jeffery Reply

    This would probably be a bit more portable and has a few additional checks.

    #!/bin/bash
    # Script to fix permissions of accounts
    # Written by: Vanessa Vasile 5/13/10
    # Tweaked by jeffery 10/13/14
    # http://thecpaneladmin.com

    if [[ $# -lt 1 ]] || [[ $# -gt 1 ]] || [[ $(echo $1 | egrep “^roo|^bin\>|\|^nobody|^cpanel”) ]] ;then
    echo “No/invalid/multiple user(s) specified”
    exit;
    fi && export U=$@ ; if [[ ! “${U}” == “$(echo “${U}” | grep –file=<(awk -F: '/'$U'/{print $1}' /etc/passwd|awk '/'$U'/{print $1"$"}'))" ]] ; then echo "nice try." ;else echo "User checks out proceeeding" ; fi && export USER=${U} &&for user in $USER
    do

    HOMEDIR=$(awk -F: '/'$user'/{print $6}' /etc/passwd)

    if [ ! -f /var/cpanel/users/$user ]; then
    echo "$user user file missing, likely an invalid user"

    elif [ "$HOMEDIR" == "" ];then
    echo "Couldn't determine home directory for $USER"

    else

    echo "Setting ownership for user $user"

    chown -R $user:$user $HOMEDIR
    chmod 711 $HOMEDIR
    chown $user:nobody $HOMEDIR/public_html $HOMEDIR/.htpasswds
    chown $user:mail $HOMEDIR/etc $HOMEDIR/etc/*/shadow $HOMEDIR/etc/*/passwd

    echo "Setting permissions for user $USER"

    find $HOMEDIR -type f -exec chmod -v 644 "{}" \; -print &&
    find $HOMEDIR -type d -exec chmod -v 755 "{}" \; -print
    find $HOMEDIR -type d -name cgi-bin -exec chmod -v 755 {} \; -print
    find $HOMEDIR -type f -name "*.pl" -o -name "*.perl" -exec chmod 755 {} \; -print
    chown -v ${user}:nobody $HOMEDIR/public_html/ && chmod -v 750 ${HOMEDIR}/public_html
    fi
    done

  12. C Davis Reply

    In many cases, my public_html directory is nested like this:
    /home/{user}/domain.com/public_html

    How could I modify the script to account for that scenario?

    1. Vanessa Vasile Reply

      Is this script not addressing permissions on those, or are you mainly trying to make sure the docroot is 750 user:nobody like the main public_html? Technically, you could just pull the docroot out of /var/cpanel/userdata for each domain the user owns, and make sure those are 750 user:nobody.

  13. Morris Reply

    Hello Vanessa,

    Thanks for a great script!
    I just used your script and it does change permissions on most folders correctly.
    But when using Cloudlinux / CageFS it does change .cagefs/ folder wrong.
    .cagefs folder should be drwxrwx–x and not drwxr-xr-x.
    Folders under that is also changed wrong.
    tmp and var folder should be drwx—— and not drwxr-xr-x.
    Folders under that again should also be under var:
    drwxrwxrwx – cache
    drwxrwxrwx – run

    And in root folder for user it changes public_html folder to drwxr-xr-x. It should be drwxr-x—.
    Is there anyway you can change this in your script?

    1. Vanessa Vasile Reply

      The script is just a basic template and would not accommodate every possible environment – you should be able to edit it easily. However, I’ve updated it to include CloudLinux servers with CageFS enabled.

  14. Dusan Reply

    Great script, we use it when client has obvious permission issues, thanks for sharing!

    Is it universal because from what I saw it has to be in /home?
    If you want I can re-check entire script and make it universal and runable with sh fixperms.sh insted of commands above 🙂

  15. Quentin Reply

    Issue if “nobody” exist in /var/cpanel/users !!!

    Setting ownership for user nobody (/) —> Really BAD !
    Setting permissions for user nobody

    1. Vanessa Vasile Reply

      I’d imagine common sense would prevent someone from running this against a system user that is not associated with a cPanel account, but as with everything, people need to understand the ramifications of what they are doing as root on a server.

  16. Lucian Stiopei Reply

    Hi,
    I use this script for several years. Is very helpful!
    Today running on this account (lsn), also changed other accounts (lsnrn, gerlsn, lsnapo, lsn-ho) to lsn.
    ./fixperms.sh lsn

    Multumesc!

  17. Gabriel P. Reply

    Very nice script, thank you, but I would not recommend using it as root.

    The command ls -A /var/cpanel/users will sometimes list nobody and the home directory of nobody is /. There’s a chance that it chown all your server to nobody:nobody.

    Running the fixperm as the user will probably help.

  18. Andrej Reply

    Though still functional after 7 years, the script does have some issues as written (e.g. the chown will affect the targets of symlinks, possibly changing system files, and chmods will affect the .ssh directory, possibly making ssh keys readable to other users). The most glaring I feel is that the home directory /home/user ends up as 755 instead of 711 because of the find command, granting other users read access to that user’s entire directory.

    As Vanessa rightly warns in the comments, people do need to be careful with what they do as root on a server, and I hope we all know what happens when we download bash scripts on the internet ;-D. This script does need to be run as root, because if permissions for the home directory are wrong, the user can’t change them. I spiffed up a modified version, though I’m not sure if anyone will scroll this far to see it 🙂

    #!/bin/bash
    # Script to fix permissions of accounts
    # Original script by: Vanessa Vasile :: http://thecpaneladmin.com
    # version 1.52

    if [ “$#” -lt “1” ] || [[ $(echo $@ | egrep “\b(root|bin|nobody|cpanel|halt|system)\b”) ]]; then
    echo “Must specify user or invalid user. Usage: $0 [–all | username [username…]]”
    exit
    fi

    USER=$@

    if [ “$USER” = “–all” ]; then
    USER=`\ls -A /var/cpanel/users/ | egrep -v “\b(root|bin|nobody|cpanel|halt|system)\b”`
    fi

    for user in $USER; do
    HOMEDIR=$(egrep ^${user}: /etc/passwd | cut -d: -f6)
    if [ ! -f /var/cpanel/users/$user ]; then
    echo “$user user file missing, likely an invalid user”
    elif [ “$HOMEDIR” == “” ]; then
    echo “Couldn’t determine home directory for $user”
    else
    echo “Setting ownership for user $user”
    chown -hR $user:$user $HOMEDIR
    chgrp -h nobody $HOMEDIR/public_html $HOMEDIR/.htpasswds
    for docroot in $(grep \ $user\=\= /etc/userdatadomains | awk -F”==” ‘{print $5}’ | grep $HOMEDIR); do
    chgrp -h nobody $docroot
    done
    chown -h $user:mail $HOMEDIR/etc $HOMEDIR/etc/*/shadow $HOMEDIR/etc/*/passwd

    echo “Setting permissions for user $user”

    find $HOMEDIR -type f ! -path “*/mail/*” ! -path “*/.ssh/*” ! -perm 000 -exec chmod 644 {} \;
    find $HOMEDIR -type d ! -path “*/mail/*” ! -path “*/.ssh/*” ! -perm 000 -exec chmod 755 {} \;
    find $HOMEDIR -type d -name cgi-bin -exec chmod 755 {} \;
    find $HOMEDIR -type f \( -name “*.pl” -o -name “*.perl” -o -name “*.cgi” \) ! -perm 000 -exec chmod 755 {} \;
    chmod 750 $HOMEDIR/public_html
    chmod 711 $HOMEDIR
    for docroot in $(grep \ $user\=\= /etc/userdatadomains | awk -F”==” ‘{print $5}’ | grep $HOMEDIR); do
    chmod 750 $docroot
    done

    if [ -d “$HOMEDIR/.cagefs” ]; then
    chmod 775 $HOMEDIR/.cagefs
    chmod 700 $HOMEDIR/.cagefs/tmp
    chmod 700 $HOMEDIR/.cagefs/var
    chmod 777 $HOMEDIR/.cagefs/cache
    chmod 777 $HOMEDIR/.cagefs/run
    fi
    fi
    done

    1. Mario Reply

      Andre, thank you for your modified script, its March 2020 and that just saved me a truck load of time.
      Albeit I did the basic mistake of coyp/paste from here to shell and apostrophe’s and double quotes had to be updated before executing the script.

      Thank you

  19. Pingback: Fix CPanel account permission and ownership | TECHSHERIFF

  20. Nabi Reply

    Thanks for the script.
    I think this is also necessary:
    “`chmod 750 $HOMEDIR/.htpasswds“`
    And please update the script on the page of this blog according to the link of the file you have placed, to avoid duplication and confusion.
    It is also good if you put it on the github or gist.

Leave a Reply

Your email address will not be published. Required fields are marked *

Log in