Simple Bash Script to Fix Account Permissions
- Written by Vanessa Vasile
- Published in Fixes, Linux, Scripts
- 46 Comments
- Permalink
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
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
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
@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?
works like a charm. many thanks!!!
Damn girl,
Nice script!
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.
Thank you Vanessa, this is great script, it saves me huge time fixing over 300 websites 🙂
All the best
Hadi
Saved my Day, many thanks.
Pingback: Server hacked! | HostGator Coupons Code
your script saved my day. some file’s permission broke after importing cpmove file, and your script fixed it in no time.
Thankyou!
Your script saved me from what could have been hours of work!
Awesome work here 🙂
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
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)
Great article, I just given this onto a co-worker who was doing a little research on that. And he in fact purchased me lunch because I discovered it for him
nice script
i test now working
i am very very thank you for shard
Thank you for this script. Worked like a charm to fix an issue I had. Wonderful.
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.
Nice script… it worked very well !
thanks for the script!
(but your site have a viagra link 😉 )
Thanks for letting me know. It’s been removed 🙂
Wow…. I’d almost marry you – Great Scripting ! Saved my arse big time !!!
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.
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
Hi there – thanks for pointing this out. I’ve adjusted the code in the script, which can also probably stand to be updated (it was written in 2010).
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
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?
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.
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?
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.
How can i use this script?
You SSH into the server and run it. If you don’t understand what that means, you probably shouldn’t be doing this.
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 🙂
The /home path is not hard-coded anywhere in the script. It pulls the homedir from what /etc/passwd says it is.
Based on that, is it needed to execute script from /home or it can be anywhere?
You can execute it from anywhere.
Issue if “nobody” exist in /var/cpanel/users !!!
Setting ownership for user nobody (/) —> Really BAD !
Setting permissions for user nobody
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.
Thank you so much ! you saved me !
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!
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.
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
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
yes, i have seen it 🙂
Thank you for the modification.
Pingback: Fix CPanel account permission and ownership | TECHSHERIFF
Stumbled across this from a forum post, fixed my issue in a heartbeat. Thanks very much! 🙂
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.