Simple Bash Script to Fix Account Permissions

Simple Bash Script to Fix Account Permissions
5 (100%) 19 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.

# Script to fix permissions of accounts
# Written by: Vanessa Vasile 5/13/10

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


for user in $USER

  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"
    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


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
Don't be selfish, share!Tweet about this on TwitterShare on RedditShare on TumblrBuffer this pageDigg thisShare on FacebookFlattr the authorEmail this to someoneShare on Google+Pin on PinterestPrint this pageShare on LinkedInShare on StumbleUpon


  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

  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


    1. Vanessa Reply

      @Matt Improvements are always welcome – feel free to email me at admin[at] 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

  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


  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@*** [7321 16:01:46 ~]# user=hal
    root@*** [7322 16:01:53 ~]# egrep ^${user} /etc/passwd | cut -d: -f6

    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.

    # Script to fix permissions of accounts
    # Written by: Vanessa Vasile 5/13/10
    # Tweaked by jeffery 10/13/14

    if [[ $# -lt 1 ]] || [[ $# -gt 1 ]] || [[ $(echo $1 | egrep “^roo|^bin\>|\|^nobody|^cpanel”) ]] ;then
    echo “No/invalid/multiple user(s) specified”
    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

    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"


    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

  12. C Davis Reply

    In many cases, my public_html directory is nested like this:

    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 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

    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.
    ./ lsn


  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.

Leave a Reply

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

Log in