Просмотр исходного кода

SecImprov: File operations in user home folder will be executed as the real user

Robert Zollner 6 лет назад
Родитель
Сommit
54c3c73a9a
5 измененных файлов с 71 добавлено и 78 удалено
  1. 11 10
      bin/v-add-web-domain
  2. 1 1
      bin/v-add-web-domain-ftp
  3. 1 1
      bin/v-change-web-domain-ftp-path
  4. 11 8
      bin/v-restore-user
  5. 47 58
      func/rebuild.sh

+ 11 - 10
bin/v-add-web-domain

@@ -46,7 +46,8 @@ is_object_valid 'user' 'USER' "$user"
 is_object_unsuspended 'user' 'USER' "$user"
 is_package_full 'WEB_DOMAINS' 'WEB_ALIASES'
 is_domain_new 'web' "$domain,$aliases"
-is_dir_symlink $HOMEDIR/$user/web
+is_dir_symlink "$HOMEDIR/$user/web"
+is_dir_symlink "$HOMEDIR/$user/web/$domain"
 if [ ! -z "$ip" ]; then
     is_ip_valid "$ip" "$user"
 else
@@ -65,14 +66,14 @@ check_hestia_demo_mode
 source $USER_DATA/user.conf
 
 # Creating domain directories
-mkdir -p $HOMEDIR/$user/web/$domain \
-      $HOMEDIR/$user/web/$domain/public_html \
-      $HOMEDIR/$user/web/$domain/public_shtml \
-      $HOMEDIR/$user/web/$domain/document_errors \
-      $HOMEDIR/$user/web/$domain/cgi-bin \
-      $HOMEDIR/$user/web/$domain/private \
-      $HOMEDIR/$user/web/$domain/stats \
-      $HOMEDIR/$user/web/$domain/logs
+$BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain"
+$BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/public_html"
+$BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/public_shtml"
+$BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/document_errors"
+$BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/cgi-bin"
+$BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/private"
+$BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/stats"
+$BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/logs"
 
 # Creating domain logs
 touch /var/log/$WEB_SYSTEM/domains/$domain.bytes \
@@ -82,7 +83,7 @@ ln -f -s /var/log/$WEB_SYSTEM/domains/$domain.*log \
     $HOMEDIR/$user/web/$domain/logs/
 
 # Adding domain skeleton
-cp -r $WEBTPL/skel/* $HOMEDIR/$user/web/$domain/ >/dev/null 2>&1
+sudo -u $user -- cp -r $WEBTPL/skel/* "$HOMEDIR/$user/web/$domain/" >/dev/null 2>&1
 for file in $(find "$HOMEDIR/$user/web/$domain/" -type f); do
     sed -i "s/%domain%/$domain/g" $file
 done

+ 1 - 1
bin/v-add-web-domain-ftp

@@ -77,7 +77,7 @@ else
     fi
     # Creating ftp user home directory
     if [ ! -e "$ftp_path_a" ]; then
-        mkdir -p $ftp_path_a
+        $BIN/v-add-fs-directory "$user" "$ftp_path_a"
         chown $user:$user "$ftp_path_a"
         chmod 751 "$ftp_path_a"
     fi

+ 1 - 1
bin/v-change-web-domain-ftp-path

@@ -61,7 +61,7 @@ check_hestia_demo_mode
 
 # MKDIR if path doesn't exist
 if [ ! -e "$ftp_path_a" ]; then
-    mkdir -p "$ftp_path_a"
+    $BIN/v-add-fs-directory "$user" "$ftp_path_a"
     chown $user:$user "$ftp_path_a"
     chmod 751 "$ftp_path_a"
 fi

+ 11 - 8
bin/v-restore-user

@@ -230,7 +230,7 @@ fi
 backup_system="hestia"
 
 # Check if it is a Vesta backup
-if tar -tf $BACKUP/$backup ./vesta >/dev/null 2>&1; then
+if tar -tf "$BACKUP/$backup" ./vesta >/dev/null 2>&1; then
     backup_system="vesta"
 fi
 
@@ -240,7 +240,7 @@ if [ "$create_user" = 'yes' ]; then
     echo -e "$(date "+%F %T") $user" |tee -a $tmpdir/restore.log
 
     # Unpacking user container
-    tar xf $BACKUP/$backup -C $tmpdir ./$backup_system 2>/dev/null
+    tar xf "$BACKUP/$backup" -C "$tmpdir" --no-wildcards "./$backup_system" 2>/dev/null
     if [ "$?" -ne 0 ]; then
         rm -rf $tmpdir
         echo "Can't unpack user container" |$SENDMAIL -s "$subj" $email $notify
@@ -259,6 +259,7 @@ if [ "$create_user" = 'yes' ]; then
 fi
 
 # Unpacking pam container
+chown "$user" "$tmpdir"
 tar xf $BACKUP/$backup -C $tmpdir ./pam
 if [ "$?" -ne 0 ]; then
     rm -rf $tmpdir
@@ -402,8 +403,10 @@ if [ "$web" != 'no' ] && [ ! -z "$WEB_SYSTEM" ]; then
         if [ -d "$HOMEDIR/$user/web/$domain/public_html" ]; then
             rm -rf $HOMEDIR/$user/web/$domain/public_html/*
         fi
-        tar -xzpf $tmpdir/web/$domain/domain_data.tar.gz \
-            -C $HOMEDIR/$user/web/$domain/
+        chmod u+w "$HOMEDIR/$user/web/$domain"
+        sudo -u $user -- tar -xzpf $tmpdir/web/$domain/domain_data.tar.gz \
+            -C "$HOMEDIR/$user/web/$domain/" \
+            --exclude='logs/*'
         if [ "$?" -ne 0 ]; then
             rm -rf $tmpdir
             error="Can't unpack $domain data tarball"
@@ -595,8 +598,8 @@ if [ "$mail" != 'no' ] && [ ! -z "$MAIL_SYSTEM" ]; then
 
         # Restoring emails
         if [ -e "$tmpdir/mail/$domain/accounts.tar.gz" ]; then
-            tar -xzpf $tmpdir/mail/$domain/accounts.tar.gz \
-                -C $HOMEDIR/$user/mail/$domain_idn/
+            chmod u+w "$HOMEDIR/$user/mail/$domain_idn"
+            $BIN/v-extract-fs-archive "$user" "$tmpdir/mail/$domain/accounts.tar.gz" "$HOMEDIR/$user/mail/$domain_idn/"
             if [ "$?" -ne 0 ]; then
                 rm -rf $tmpdir
                 error="Can't unpack $domain mail account container"
@@ -746,7 +749,7 @@ if [ "$udir" != 'no' ]; then
 
         for user_dir in $user_dirs; do
             echo -e "$(date "+%F %T") $user_dir" |tee -a $tmpdir/restore.log
-            tar xf $BACKUP/$backup -C $tmpdir ./user_dir/$user_dir.tar.gz
+            tar xf "$BACKUP/$backup" -C "$tmpdir" --no-wildcards "./user_dir/$user_dir.tar.gz"
             if [ "$?" -ne 0 ]; then
                 error="Can't unpack $user_dir user dir container"
                 echo "$error" |$SENDMAIL -s "$subj" $email $notify
@@ -754,7 +757,7 @@ if [ "$udir" != 'no' ]; then
                 check_result "$E_PARSING" "$error"
             fi
 
-            tar xzf $tmpdir/user_dir/$user_dir.tar.gz -C $HOMEDIR/$user
+            $BIN/v-extract-fs-archive "$user" "$tmpdir/user_dir/$user_dir.tar.gz" "$HOMEDIR/$user"
             if [ "$?" -ne 0 ]; then
                 error="Can't unpack $user_dir user dir container"
                 echo "$error" |$SENDMAIL -s "$subj" $email $notify

+ 47 - 58
func/rebuild.sh

@@ -24,24 +24,26 @@ rebuild_user_conf() {
     /usr/sbin/useradd "$user" -s "$shell" -c "$CONTACT" \
         -m -d "$HOMEDIR/$user" > /dev/null 2>&1
 
+    # Add a general group for normal users created by Hestia
+    if [ -z "$(grep "^hestia-users:" /etc/group)" ]; then
+        groupadd --system "hestia-users"
+    fi
+
+    # Add membership to hestia-users group to non-admin users
+    if [ "$user" = "admin" ]; then
+        setfacl -m "g:admin:r-x" "$HOMEDIR/$user"
+    else
+        usermod -a -G "hestia-users" "$user"
+        setfacl -m "u:$user:r-x" "$HOMEDIR/$user"
+    fi
+    setfacl -m "g:hestia-users:---" "$HOMEDIR/$user"
+
     # Update user shell
     /usr/bin/chsh -s "$shell" "$user" &>/dev/null
 
     # Update password
-    shadow=$(grep ^$user: /etc/shadow)
-    shdw3=$(echo "$shadow" | cut -f3 -d :)
-    shdw4=$(echo "$shadow" | cut -f4 -d :)
-    shdw5=$(echo "$shadow" | cut -f5 -d :)
-    shdw6=$(echo "$shadow" | cut -f6 -d :)
-    shdw7=$(echo "$shadow" | cut -f7 -d :)
-    shdw8=$(echo "$shadow" | cut -f8 -d :)
-    shdw9=$(echo "$shadow" | cut -f9 -d :)
-    shadow_str="$user:$MD5:$shdw3:$shdw4:$shdw5:$shdw6"
-    shadow_str="$shadow_str:$shdw7:$shdw8:$shdw9"
-
     chmod u+w /etc/shadow
-    sed -i "/^$user:*/d" /etc/shadow
-    echo "$shadow_str" >> /etc/shadow
+    sed -i 's/^$user:[^:]*:/$user:$MD5:/' /etc/shadow
     chmod u-w /etc/shadow
 
     # Building directory tree
@@ -169,17 +171,17 @@ rebuild_web_domain_conf() {
 
     # Rebuilding domain directories
     if [ -d "$HOMEDIR/$user/web/$domain/document_errors" ]; then
-        rm -rf "$HOMEDIR/$user/web/$domain/document_errors"
+        $BIN/v-delete-fs-directory "$user" "$HOMEDIR/$user/web/$domain/document_errors"
     fi
 
-    mkdir -p $HOMEDIR/$user/web/$domain \
-        $HOMEDIR/$user/web/$domain/public_html \
-        $HOMEDIR/$user/web/$domain/public_shtml \
-        $HOMEDIR/$user/web/$domain/document_errors \
-        $HOMEDIR/$user/web/$domain/cgi-bin \
-        $HOMEDIR/$user/web/$domain/private \
-        $HOMEDIR/$user/web/$domain/stats \
-        $HOMEDIR/$user/web/$domain/logs
+    $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain"
+    $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/public_html"
+    $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/public_shtml"
+    $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/document_errors"
+    $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/cgi-bin"
+    $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/private"
+    $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/stats"
+    $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/logs"
 
     # Creating domain logs
     if [ ! -e "/var/log/$WEB_SYSTEM/domains" ]; then
@@ -198,22 +200,23 @@ rebuild_web_domain_conf() {
 
     # Propagating html skeleton
     if [ -d "$WEBTPL/skel/document_errors/" ]; then
-        cp -r $WEBTPL/skel/document_errors/ $HOMEDIR/$user/web/$domain/
+        sudo -u $user -- cp -r "$WEBTPL/skel/document_errors/" "$HOMEDIR/$user/web/$domain/"
     fi
 
     # Set folder permissions
-    chmod 551 $HOMEDIR/$user/web/$domain \
-        $HOMEDIR/$user/web/$domain/stats \
-        $HOMEDIR/$user/web/$domain/logs
-    chmod 751 $HOMEDIR/$user/web/$domain/private \
-        $HOMEDIR/$user/web/$domain/cgi-bin \
-        $HOMEDIR/$user/web/$domain/public_html \
-        $HOMEDIR/$user/web/$domain/public_shtml \
-        $HOMEDIR/$user/web/$domain/document_errors
+    chmod 551   $HOMEDIR/$user/web/$domain \
+                $HOMEDIR/$user/web/$domain/stats \
+                $HOMEDIR/$user/web/$domain/logs
+    chmod 751   $HOMEDIR/$user/web/$domain/private \
+                $HOMEDIR/$user/web/$domain/cgi-bin \
+                $HOMEDIR/$user/web/$domain/public_html \
+                $HOMEDIR/$user/web/$domain/public_shtml \
+                $HOMEDIR/$user/web/$domain/document_errors
     chmod 640 /var/log/$WEB_SYSTEM/domains/$domain.*
 
     # Set ownership
-    chown $user:$user $HOMEDIR/$user/web/$domain \
+    chown $user:$user \
+        $HOMEDIR/$user/web/$domain \
         $HOMEDIR/$user/web/$domain/private \
         $HOMEDIR/$user/web/$domain/cgi-bin \
         $HOMEDIR/$user/web/$domain/public_html \
@@ -285,16 +288,15 @@ rebuild_web_domain_conf() {
         if [ ! -z "$STATS_USER" ]; then
             stats_dir="$HOMEDIR/$user/web/$domain/stats"
             if [ "$WEB_SYSTEM" = 'nginx' ]; then
-                echo "auth_basic \"Web Statistics\";" > $stats_dir/auth.conf
-                echo "auth_basic_user_file $stats_dir/.htpasswd;" >> \
-                    $stats_dir/auth.conf
+                echo "auth_basic \"Web Statistics\";"               |sudo -u $user -- tee    $stats_dir/auth.conf
+                echo "auth_basic_user_file $stats_dir/.htpasswd;"   |sudo -u $user -- tee -a $stats_dir/auth.conf
             else
-                echo "AuthUserFile $stats_dir/.htpasswd" > $stats_dir/.htaccess
-                echo "AuthName \"Web Statistics\"" >> $stats_dir/.htaccess
-                echo "AuthType Basic" >> $stats_dir/.htaccess
-                echo "Require valid-user" >> $stats_dir/.htaccess
+                echo "AuthUserFile $stats_dir/.htpasswd"    |sudo -u $user -- tee    $stats_dir/.htaccess
+                echo "AuthName \"Web Statistics\""          |sudo -u $user -- tee -a $stats_dir/.htaccess
+                echo "AuthType Basic"                       |sudo -u $user -- tee -a $stats_dir/.htaccess
+                echo "Require valid-user"                   |sudo -u $user -- tee -a $stats_dir/.htaccess
             fi
-            echo "$STATS_USER:$STATS_CRYPT" > $stats_dir/.htpasswd
+            echo "$STATS_USER:$STATS_CRYPT" |sudo -u $user -- tee $stats_dir/.htpasswd
         fi
     fi
 
@@ -316,26 +318,13 @@ rebuild_web_domain_conf() {
             ftp_md5=$(echo $FTP_MD5 | tr ':' '\n' |grep -n '' |\
                 grep "^$position:" |cut -f 2 -d :)
 
-            /usr/sbin/useradd $ftp_user \
-                -s $shell \
-                -o -u $(id -u $user) \
-                -g $(id -u $user) \
-                -M -d "$HOMEDIR/$user/web/$domain${ftp_path}" >/dev/null 2>&1
+            # rebuild S/FTP users
+            $BIN/v-delete-web-domain-ftp "$user" "$domain" "$ftp_user"
+            $BIN/v-add-web-domain-ftp "$user" "$domain" "${ftp_user#*_}" "!xplaceholder$FTP_MD5" "$ftp_path"
 
             # Updating ftp user password
-            shadow=$(grep "^$ftp_user:" /etc/shadow)
-            shdw3=$(echo "$shadow" |cut -f3 -d :)
-            shdw4=$(echo "$shadow" |cut -f4 -d :)
-            shdw5=$(echo "$shadow" |cut -f5 -d :)
-            shdw6=$(echo "$shadow" |cut -f6 -d :)
-            shdw7=$(echo "$shadow" |cut -f7 -d :)
-            shdw8=$(echo "$shadow" |cut -f8 -d :)
-            shdw9=$(echo "$shadow" |cut -f9 -d :)
-            shadow_str="$ftp_user:$ftp_md5:$shdw3:$shdw4:$shdw5:$shdw6"
-            shadow_str="$shadow_str:$shdw7:$shdw8:$shdw9"
             chmod u+w /etc/shadow
-            sed -i "/^$ftp_user:*/d" /etc/shadow
-            echo "$shadow_str" >> /etc/shadow
+            sed -i 's/^$ftp_user:[^:]*:/$ftp_user:$ftp_md5:/' /etc/shadow
             chmod u-w /etc/shadow
         fi
     done
@@ -500,7 +489,7 @@ rebuild_mail_domain_conf() {
 
         # Adding mail directiry
         if [ ! -e $HOMEDIR/$user/mail/$domain_idn ]; then
-            mkdir $HOMEDIR/$user/mail/$domain_idn
+            $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/mail/$domain_idn"
         fi
 
         # Adding catchall email