diff --git a/bin/v-backup-user b/bin/v-backup-user index a5fe223b..8b84a63d 100755 --- a/bin/v-backup-user +++ b/bin/v-backup-user @@ -300,6 +300,7 @@ then msg="$msg\n$(date "+%F %T") $domain" mkdir -p $tmpdir/mail/$domain/conf mkdir -p $tmpdir/mail/$domain/vesta + domain_idn=$(idn -t --quiet -a "$domain") # Creating exim config cd $tmpdir/mail/$domain/ @@ -314,7 +315,7 @@ then fi # Packing mailboxes - cd $HOMEDIR/$user/mail/$domain + cd $HOMEDIR/$user/mail/$domain_idn accounts=$(ls) if [ ! -z "$accounts" ]; then tar -cpf $tmpdir/mail/$domain/accounts.tar $accounts @@ -336,7 +337,7 @@ then fi -# DataBases +# Databases if [ ! -z "$DB_SYSTEM" ] && [ "$DB_SYSTEM" != 'no' ] && [ "$DB" != '*' ]; then echo "-- DB --" msg="$msg\n-- DB --" @@ -553,7 +554,6 @@ ftp_backup() { # Debug info echo -e "$(date "+%F %T") FTP ftp://$HOST$BPATH/$user.$DATE.tar" - msg="$msg\n$(date "+%F %T") FTP ftp://$HOST$BPATH/$user.$DATE.tar" # Checking ftp connection if [ ! -z "$(ftpc)" ]; then diff --git a/bin/v-rebuild-user b/bin/v-rebuild-user index 70cee8a2..5b63460c 100755 --- a/bin/v-rebuild-user +++ b/bin/v-rebuild-user @@ -16,6 +16,10 @@ restart=$2 # Includes source $VESTA/conf/vesta.conf source $VESTA/func/main.sh +source $VESTA/func/rebuild.sh + +# Export sbin +export PATH=$PATH:/usr/sbin #----------------------------------------------------------# @@ -31,131 +35,15 @@ is_object_unsuspended 'user' 'USER' "$user" #----------------------------------------------------------# # Action # #----------------------------------------------------------# -export PATH=$PATH:/usr/sbin - -# Get user variables -source $USER_DATA/user.conf # Rebuild user -shell=$(chsh --list-shells | grep -w "$SHELL" |head -n1) -adduser "$user" -s "$shell" -c "$CONTACT" -m -d "$HOMEDIR/$user" &>/dev/null - -# Update user shell -shell_path=$(/usr/bin/chsh --list-shells | grep -w "$SHELL" |head -n1) -/usr/bin/chsh -s "$shell_path" "$user" &>/dev/null - -# Update password -shadow='/etc/shadow' -shdw=$(grep ^$user: $shadow) -shdw3=$(echo "$shdw" | cut -f3 -d :) -shdw4=$(echo "$shdw" | cut -f4 -d :) -shdw5=$(echo "$shdw" | cut -f5 -d :) -shdw6=$(echo "$shdw" | cut -f6 -d :) -shdw7=$(echo "$shdw" | cut -f7 -d :) -shdw8=$(echo "$shdw" | cut -f8 -d :) -shdw9=$(echo "$shdw" | cut -f9 -d :) -chmod u+w $shadow -sed -i "/^$user:*/d" $shadow -echo "$user:$MD5:$shdw3:$shdw4:$shdw5:$shdw6:$shdw7:$shdw8:$shdw9" >> $shadow -chmod u-w $shadow - -# Building directory tree -mkdir -p $HOMEDIR/$user/conf -chmod a+x $HOMEDIR/$user -chmod a+x $HOMEDIR/$user/conf -chown $user:$user $HOMEDIR/$user -chown root:root $HOMEDIR/$user/conf -chattr +i $HOMEDIR/$user/conf - -if [ ! -z "$WEB_SYSTEM" ] && [ "$WEB_SYSTEM" != 'no' ]; then - mkdir -p $HOMEDIR/$user/conf/web - mkdir -p $HOMEDIR/$user/web - mkdir -p $HOMEDIR/$user/tmp - chmod 751 $HOMEDIR/$user/conf/web - chmod 751 $HOMEDIR/$user/web - chmod 771 $HOMEDIR/$user/tmp - chown $user:$user $HOMEDIR/$user/web - $BIN/v-rebuild-web-domains $user $restart -fi - -if [ ! -z "$DNS_SYSTEM" ] && [ "$DNS_SYSTEM" != 'no' ]; then - mkdir -p $HOMEDIR/$user/conf/dns - chmod 751 $HOMEDIR/$user/conf/dns - $BIN/v-rebuild-dns-domains $user $restart -fi - -if [ ! -z "$MAIL_SYSTEM" ] && [ "$MAIL_SYSTEM" != 'no' ]; then - mkdir -p $HOMEDIR/$user/conf/mail - mkdir -p $HOMEDIR/$user/mail - chmod 751 $HOMEDIR/$user/mail - chmod 751 $HOMEDIR/$user/conf/mail - $BIN/v-rebuild-mail-domains $user -fi - - -if [ ! -z "$DB_SYSTEM" ] && [ "$DB_SYSTEM" != 'no' ]; then - $BIN/v-rebuild-databases $user -fi - -if [ ! -z "$CRON_SYSTEM" ] && [ "$CRON_SYSTEM" != 'no' ]; then - $BIN/v-rebuild-cron-jobs $user $restart -fi +rebuild_user_conf #----------------------------------------------------------# # Vesta # #----------------------------------------------------------# -# Creating configuration files and pipes -chmod 770 $USER_DATA -touch $USER_DATA/backup.conf -chmod 660 $USER_DATA/backup.conf -touch $USER_DATA/history.log -chmod 660 $USER_DATA/history.log -touch $USER_DATA/stats.log -chmod 660 $USER_DATA/stats.log - -sed -i "/ $user$/d" $VESTA/data/queue/disk.pipe -echo "$BIN/v-update-user-disk $user" >> $VESTA/data/queue/disk.pipe - -if [ ! -z "$WEB_SYSTEM" ] && [ "$WEB_SYSTEM" != 'no' ]; then - mkdir -p $USER_DATA/ssl - chmod 770 $USER_DATA/ssl - touch $USER_DATA/web.conf - chmod 660 $USER_DATA/web.conf - if [ "$(grep -w $user $VESTA/data/queue/traffic.pipe)" ]; then - echo "$BIN/v-update-web-domains-traff $user" \ - >> $VESTA/data/queue/traffic.pipe - fi - echo "$BIN/v-update-web-domains-disk $user" >> $VESTA/data/queue/disk.pipe -fi - -if [ ! -z "$DNS_SYSTEM" ] && [ "$DNS_SYSTEM" != 'no' ]; then - mkdir -p $USER_DATA/dns - chmod 770 $USER_DATA/dns - touch $USER_DATA/dns.conf - chmod 660 $USER_DATA/dns.conf -fi - -if [ ! -z "$MAIL_SYSTEM" ] && [ "$MAIL_SYSTEM" != 'no' ]; then - mkdir -p $USER_DATA/mail - chmod 770 $USER_DATA/mail - touch $USER_DATA/mail.conf - chmod 660 $USER_DATA/mail.conf - echo "$BIN/v-update-mail-domains-disk $user" >> $VESTA/data/queue/disk.pipe -fi - -if [ ! -z "$DB_SYSTEM" ] && [ "$DB_SYSTEM" != 'no' ]; then - touch $USER_DATA/db.conf - chmod 660 $USER_DATA/db.conf - echo "$BIN/v-update-databases-disk $user" >> $VESTA/data/queue/disk.pipe -fi - -if [ ! -z "$CRON_SYSTEM" ] && [ "$CRON_SYSTEM" != 'no' ]; then - touch $USER_DATA/cron.conf - chmod 660 $USER_DATA/cron.conf -fi - # Logging log_event "$OK" "$EVENT" diff --git a/bin/v-restore-user b/bin/v-restore-user index 1bdf1302..f344101f 100755 --- a/bin/v-restore-user +++ b/bin/v-restore-user @@ -50,29 +50,43 @@ is_backup_valid() { args='USER BACKUP [WEB] [DNS] [MAIL] [DB] [CRON] [UDIR] [NOTIFY]' check_args '2' "$#" $args validate_format 'user' 'backup' -is_object_valid 'user' 'USER' "$user" -is_object_unsuspended 'user' 'USER' "$user" is_backup_valid +is_backup_available #----------------------------------------------------------# # Action # #----------------------------------------------------------# -# Set notification email and subject -if [ "$notify" != 'no' ]; then - subj="$user → restore failed" - email=$(get_user_value '$CONTACT') -else - subj="$user → restore failed" - email=$(grep CONTACT $VESTA/data/users/admin/user.conf | cut -f 2 -d \') -fi +# Define email wrapper if [ -e "$VESTA/web/inc/mail-wrapper.php" ]; then send_mail="$VESTA/web/inc/mail-wrapper.php" else send_mail=$(which mail) fi + +# Check user +check_user=$(is_object_valid 'user' 'USER' "$user") +if [ -z "$check_user" ]; then + is_object_unsuspended 'user' 'USER' "$user" + + if [ "$notify" != 'no' ]; then + subj="$user → restore failed" + email=$(get_user_value '$CONTACT') + else + subj="$user → restore failed" + email=$(grep CONTACT $VESTA/data/users/admin/user.conf |cut -f2 -d \') + fi +else + # Set flag for user creation + create_user="yes" + + # Set notification email and subject + subj="$user → restore failed" + email=$(grep CONTACT $VESTA/data/users/admin/user.conf | cut -f2 -d \') +fi + # Check disk usage disk_usage=$(df $BACKUP |tail -n1 |tr ' ' '\n' |grep % |cut -f 1 -d %) if [ "$disk_usage" -ge "$BACKUP_DISK_LIMIT" ]; then @@ -92,7 +106,7 @@ while [ "$la" -ge "$BACKUP_LA_LIMIT" ]; do echo sleep 60 if [ "$i" -ge "15" ]; then - echo "LoadAverage $i is above threshold" | $send_mail -s "$subj" $email + echo "LoadAverage $i is above threshold" |$send_mail -s "$subj" $email echo "Error: LA is too high" sed -i "/ $user /d" $VESTA/data/queue/backup.pipe log_event "$E_LA" "$EVENT" @@ -110,12 +124,52 @@ if [ "$?" -ne 0 ]; then exit $E_NOTEXIST fi +# User +if [ "$create_user" = 'yes' ]; then + echo "-- USER --" + msg="$msg\n-- USER --" + + echo -e "$(date "+%F %T") $user" + msg="$msg\n$(date "+%F %T") $user" + + # unpack user container + tar xf $BACKUP/$backup -C $tmpdir ./vesta + if [ "$?" -ne 0 ]; then + echo "Error: can't unpack user contaner" + echo "Can't unpack user contaner" | $send_mail -s "$subj" $email + rm -rf $tmpdir + exit $E_PARSING + fi + + # Restore cron records + mkdir $USER_DATA + cp $tmpdir/vesta/user.conf $USER_DATA/ + + # Rebuild cron + rebuild_user_conf + + echo + msg="$msg\n" +fi # WEB if [ "$web" != 'no' ]; then echo "-- WEB --" msg="$msg\n-- WEB --" + # Unpack pam container + tar xf $BACKUP/$backup -C $tmpdir ./pam + if [ "$?" -ne 0 ]; then + echo "Error: can't unpack PAM contaner" + echo "Can't unpack PAM contaner" | $send_mail -s "$subj" $email + rm -rf $tmpdir + exit $E_PARSING + fi + + # Get user id + old_uid=$(cut -f 3 -d : $tmpdir/pam/passwd) + new_uid=$(grep "^$user:" /etc/passwd | cut -f 3 -d :) + # Create domain list domain_list=$(tar -tf $BACKUP/$backup | grep "^./web" |\ grep domain_data.tar.gz | cut -f 3 -d '/') @@ -238,6 +292,14 @@ if [ "$web" != 'no' ]; then fi fi + # Convert ftp user + FTP_USER=$(echo "$FTP_USER" | cut -f 2,3,4,5,6,7 -d '_') + FTP_USER="${user}_${FTP_USER}" + + # Convert stats user + STATS_USER=$(echo "$STATS_USER" | cut -f 2,3,4,5,6,7 -d '_') + STATS_USER="${user}_${STATS_USER}" + str="DOMAIN='$domain' IP='$IP' IP6='$IP6' ALIAS='$ALIAS'" str="$str TPL='$TPL' SSL='$SSL' SSL_HOME='$SSL_HOME'" str="$str FTP_USER='$FTP_USER' FTP_MD5='$FTP_MD5' NGINX='$NGINX'" @@ -309,7 +371,16 @@ if [ "$web" != 'no' ]; then rm -rf $tmpdir exit $E_PARSING fi + + # ReChown files if uid differs + if [ "$old_uid" -ne "$new_uid" ]; then + find $HOMEDIR/$user/web/$domain/ -user $old_uid \ + -exec chown -h $user:$user {} \; + fi done + + # Restart WEB + $BIN/v-restart-web "$EVENT" echo msg="$msg\n" fi @@ -416,6 +487,9 @@ if [ "$dns" != 'no' ]; then # Rebuild dns config rebuild_dns_domain_conf done + + # Restart DNS + $BIN/v-restart-dns "$EVENT" echo msg="$msg\n" fi @@ -425,6 +499,19 @@ if [ "$mail" != 'no' ]; then echo "-- MAIL --" msg="$msg\n-- MAIL --" + # Unpack pam container + tar xf $BACKUP/$backup -C $tmpdir ./pam + if [ "$?" -ne 0 ]; then + echo "Error: can't unpack PAM contaner" + echo "Can't unpack PAM contaner" | $send_mail -s "$subj" $email + rm -rf $tmpdir + exit $E_PARSING + fi + + # Get user id + old_uid=$(cut -f 3 -d : $tmpdir/pam/passwd) + new_uid=$(grep "^$user:" /etc/passwd | cut -f 3 -d :) + # Create domain list domain_list=$(tar -tf $BACKUP/$backup | grep "^./mail" |\ grep mail.conf | cut -f 3 -d '/') @@ -452,6 +539,8 @@ if [ "$mail" != 'no' ]; then fi # Restore domain config + domain_idn=$(idn -t --quiet -a "$domain") + check_config=$(grep "DOMAIN='$domain'" $USER_DATA/mail.conf) if [ -z "$check_config" ]; then @@ -491,7 +580,7 @@ if [ "$mail" != 'no' ]; then # Restore emails if [ -e "$tmpdir/mail/$domain/accounts.tar.gz" ]; then tar -xzpf $tmpdir/mail/$domain/accounts.tar.gz \ - -C $HOMEDIR/$user/mail/$domain/ + -C $HOMEDIR/$user/mail/$domain_idn/ if [ "$?" -ne 0 ]; then echo "Error: can't unpack $domain mail account tarball" echo "Can't unpack $domain mail account tarball" |\ @@ -499,6 +588,13 @@ if [ "$mail" != 'no' ]; then rm -rf $tmpdir exit $E_PARSING fi + + # ReChown files if uid differs + if [ "$old_uid" -ne "$new_uid" ]; then + find $HOMEDIR/$user/mail/$domain_idn -user $old_uid \ + -exec chown -h $user:mail {} \; + fi + fi done echo @@ -523,8 +619,6 @@ if [ "$db" != 'no' ]; then fi for db in $db_list; do - echo -e "$(date "+%F %T") $db" - msg="$msg\n$(date "+%F %T") $db" # unpack db container tar xf $BACKUP/$backup -C $tmpdir ./db/$db @@ -540,14 +634,24 @@ if [ "$db" != 'no' ]; then check_config=$(grep "DB='$db'" $USER_DATA/db.conf) if [ -z "$check_config" ]; then - # Parse domain config + # Parse database config eval $(cat $tmpdir/db/$db/vesta/db.conf) - str="DB='$db' DBUSER='$DBUSER' MD5='$MD5' HOST='$HOST'" + + # Convert database & database user + DB=$(echo "$DB" | cut -f 2,3,4,5,6,7 -d '_') + DB="${user}_${DB}" + DBUSER=$(echo "$DBUSER" | cut -f 2,3,4,5,6,7 -d '_') + DBUSER="${user}_${DBUSER}" + + str="DB='$DB' DBUSER='$DBUSER' MD5='$MD5' HOST='$HOST'" str="$str TYPE='$TYPE' CHARSET='$CHARSET' U_DISK='$U_DISK'" str="$str SUSPENDED='no' TIME='$(date +%T)' DATE='$(date +%F)'" echo $str >> $USER_DATA/db.conf fi + echo -e "$(date "+%F %T") $DB" + msg="$msg\n$(date "+%F %T") $DB" + # Unzip database dump gzip -d $tmpdir/db/$db/$db.*.sql.gz @@ -571,9 +675,6 @@ if [ "$cron" != 'no' ]; then echo "-- CRON --" msg="$msg\n-- CRON --" - echo -e "$(date "+%F %T") $db" - msg="$msg\n$(date "+%F %T") $db" - # unpack cron container tar xf $BACKUP/$backup -C $tmpdir ./cron if [ "$?" -ne 0 ]; then @@ -583,12 +684,23 @@ if [ "$cron" != 'no' ]; then exit $E_PARSING fi + cron_record=$(wc -l $tmpdir/cron/cron.conf |cut -f 1 -d' ') + if [ "$cron_record" -eq 1 ]; then + echo -e "$(date "+%F %T") $cron_record record" + msg="$msg\n$(date "+%F %T") $cron_record record" + else + echo -e "$(date "+%F %T") $cron_record records" + msg="$msg\n$(date "+%F %T") $cron_record records" + fi + # Restore cron records cp $tmpdir/cron/cron.conf $USER_DATA/cron.conf # Rebuild cron sync_cron_jobs + # Restart cron + $BIN/v-restart-cron "$EVENT" echo msg="$msg\n" fi @@ -601,6 +713,19 @@ if [ "$udir" != 'no' ]; then # unpack user dir container if [ ! -z "$(tar -tf $BACKUP/$backup |grep './user_dir')" ]; then + # Unpack pam container + tar xf $BACKUP/$backup -C $tmpdir ./pam + if [ "$?" -ne 0 ]; then + echo "Error: can't unpack PAM contaner" + echo "Can't unpack PAM contaner" | $send_mail -s "$subj" $email + rm -rf $tmpdir + exit $E_PARSING + fi + + # Get user id + old_uid=$(cut -f 3 -d : $tmpdir/pam/passwd) + new_uid=$(grep "^$user:" /etc/passwd | cut -f 3 -d :) + # Create user dir list udir_list=$(tar -tf $BACKUP/$backup | grep "^./user_dir" |\ grep tar.gz | cut -f 3 -d '/' | sed -e "s/.tar.gz//") @@ -636,6 +761,12 @@ if [ "$udir" != 'no' ]; then rm -rf $tmpdir exit $E_PARSING fi + + # ReChown files if uid differs + if [ "$old_uid" -ne "$new_uid" ]; then + find $HOMEDIR/$user/$user_dir -user $old_uid \ + -exec chown -h $user:$user {} \; + fi done fi echo @@ -662,6 +793,7 @@ fi # Update user counters $BIN/v-update-user-counters $user +$BIN/v-update-sys-ip-counters # Logging log_event "$OK" "$EVENT" diff --git a/func/main.sh b/func/main.sh index b62fa273..b44b52d8 100644 --- a/func/main.sh +++ b/func/main.sh @@ -148,6 +148,15 @@ is_type_valid() { fi } +# Check if backup is available for user +is_backup_available() { + if [ "$user" != "$(echo $backup | cut -f 1 -d '.')" ]; then + echo "Error: User $user don't have permission to use $backup" + log_event "$E_FORBIDEN" "$EVENT" + exit $E_FORBIDEN + fi +} + # Check user backup settings is_backup_enabled() { BACKUPS=$(grep "^BACKUPS=" $USER_DATA/user.conf | cut -f2 -d \')