#!/bin/bash # info: add system user # options: USER PASSWORD EMAIL [PACKAGE] [NAME] [LASTNAME] # # example: v-add-user admin2 P4$$w@rD bgates@aol.com # # This function creates new user account. #----------------------------------------------------------# # Variables & Functions # #----------------------------------------------------------# # Argument definition user=$1 password=$2 HIDE=2 email=$3 package=${4-default} name=$5 # Last name has been added for backward compatibility with WHMCS / Blesta VestaCP Plugins if [ -n "$6" ]; then name="$name $6" fi # Includes # shellcheck source=/etc/hestiacp/hestia.conf source /etc/hestiacp/hestia.conf # shellcheck source=/usr/local/hestia/func/main.sh source $HESTIA/func/main.sh # load config file source_conf "$HESTIA/conf/hestia.conf" is_user_free() { # these names may cause issues with MariaDB/MySQL database names and should be reserved: # sudo has been added due to Privilege escalation as sudo group has always sudo permission check_sysuser=$(php -r '$reserved_names=array("aria", "aria_log", "mysql", "mysql_upgrade", "ib", "ib_buffer", "ddl", "ddl_recovery", "performance", "sudo"); if(in_array(strtolower($argv[1]), $reserved_names, true)){echo implode(", ", $reserved_names);}' "$user") if [ -n "$check_sysuser" ]; then check_result "$E_INVALID" "The user name '$user' is reserved and cannot be used. List of reserved names: $check_sysuser" return fi check_sysuser=$(cut -f 1 -d : /etc/passwd | grep "^$user$") if [ -n "$check_sysuser" ] || [ -e "$USER_DATA" ]; then check_result "$E_EXISTS" "user $user exists" fi } #----------------------------------------------------------# # Verifications # #----------------------------------------------------------# check_args '3' "$#" 'USER PASSWORD EMAIL [PACKAGE] [NAME] ' is_format_valid 'user' 'email' 'package' if [ -n "$name" ]; then is_format_valid 'name' fi is_user_free "$user" is_password_valid is_package_valid # Perform verification if read-only mode is enabled check_hestia_demo_mode #----------------------------------------------------------# # Action # #----------------------------------------------------------# # Parsing package data pkg_data=$(cat $HESTIA/data/packages/$package.pkg | egrep -v "TIME|DATE") # Checking shell shell_conf=$(echo "$pkg_data" | grep 'SHELL' | cut -f 2 -d \') shell=$(grep -w "$shell_conf" /etc/shells | head -n1) # Adding user /usr/sbin/useradd "$user" -s "$shell" -c "$email" -m -d "$HOMEDIR/$user" -U check_result $? "user creation failed" "$E_INVALID" # Adding password echo "$user:$password" | /usr/sbin/chpasswd if [ $? -ne 0 ]; then # Delete user on failure /usr/sbin/deluser "$user" > /dev/null 2>&1 echo "Error: Password not accepted due to PAM restrictions" exit 2 fi # 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" # Building directory tree mkdir $HOMEDIR/$user/conf if [ -n "$WEB_SYSTEM" ]; then mkdir $HOMEDIR/$user/conf/web $HOMEDIR/$user/web $HOMEDIR/$user/tmp chmod 751 $HOMEDIR/$user/conf/web chmod 700 $HOMEDIR/$user/tmp chown $user:$user $HOMEDIR/$user/tmp chown root:$user $HOMEDIR/$user/web/ fi if [ -n "$MAIL_SYSTEM" ]; then mkdir $HOMEDIR/$user/conf/mail $HOMEDIR/$user/mail chmod 751 $HOMEDIR/$user/mail chmod 755 $HOMEDIR/$user/conf/mail fi if [ -n "$DNS_SYSTEM" ]; then if [ "$DNS_SYSTEM" = 'named' ]; then dns_group='named' else dns_group='bind' fi mkdir $HOMEDIR/$user/conf/dns chmod 771 $HOMEDIR/$user/conf/dns chown root:$dns_group $HOMEDIR/$user/conf/dns fi # Create default writeable folders mkdir $HOMEDIR/$user/.config \ $HOMEDIR/$user/.cache \ $HOMEDIR/$user/.local \ $HOMEDIR/$user/.composer \ $HOMEDIR/$user/.vscode-server \ $HOMEDIR/$user/.ssh \ $HOMEDIR/$user/.npm chown $user:$user \ $HOMEDIR/$user/.config \ $HOMEDIR/$user/.cache \ $HOMEDIR/$user/.local \ $HOMEDIR/$user/.composer \ $HOMEDIR/$user/.vscode-server \ $HOMEDIR/$user/.ssh \ $HOMEDIR/$user/.npm # Set permissions chmod a+x $HOMEDIR/$user chattr +i $HOMEDIR/$user/conf > /dev/null 2>&1 # Adding user dir mkdir -p $USER_DATA/ssl $USER_DATA/dns $USER_DATA/mail # Creating configuration files and pipes touch $USER_DATA/backup.conf \ $USER_DATA/history.log \ $USER_DATA/stats.log \ $USER_DATA/web.conf \ $USER_DATA/dns.conf \ $USER_DATA/mail.conf \ $USER_DATA/db.conf \ $USER_DATA/cron.conf chmod 770 $USER_DATA \ $USER_DATA/ssl \ $USER_DATA/dns \ $USER_DATA/mail chmod 660 $USER_DATA/backup.conf \ $USER_DATA/history.log \ $USER_DATA/stats.log \ $USER_DATA/web.conf \ $USER_DATA/dns.conf \ $USER_DATA/mail.conf \ $USER_DATA/db.conf \ $USER_DATA/cron.conf # Updating queue pipes echo "$BIN/v-update-user-disk $user" >> $HESTIA/data/queue/disk.pipe if [ -n "$WEB_SYSTEM" ]; then echo "$BIN/v-update-web-domains-traff $user" \ >> $HESTIA/data/queue/traffic.pipe echo "$BIN/v-update-web-domains-disk $user" >> $HESTIA/data/queue/disk.pipe fi if [ -n "$MAIL_SYSTEM" ]; then echo "$BIN/v-update-mail-domains-disk $user" >> $HESTIA/data/queue/disk.pipe fi if [ -n "$DB_SYSTEM" ]; then echo "$BIN/v-update-databases-disk $user" >> $HESTIA/data/queue/disk.pipe fi # Generating timestamp time_n_date=$(date +'%T %F') time=$(echo "$time_n_date" | cut -f 1 -d \ ) date=$(echo "$time_n_date" | cut -f 2 -d \ ) # Filling user config if [ "$user" != 'admin' ]; then ip_avail=$($BIN/v-list-user-ips admin plain | grep -w shared | wc -l) u_users=0 else ip_avail=0 u_users=1 fi echo "NAME='$name' PACKAGE='$package' $pkg_data CONTACT='$email' CRON_REPORTS='yes' MD5='$(awk -v user=$user -F : 'user == $1 {print $2}' /etc/shadow)' RKEY='$(generate_password)' TWOFA='' QRCODE='' PHPCLI='' ROLE='user' SUSPENDED='no' SUSPENDED_USERS='0' SUSPENDED_WEB='0' SUSPENDED_DNS='0' SUSPENDED_MAIL='0' SUSPENDED_DB='0' SUSPENDED_CRON='0' IP_AVAIL='$ip_avail' IP_OWNED='0' U_USERS='$u_users' U_DISK='0' U_DISK_DIRS='0' U_DISK_WEB='0' U_DISK_MAIL='0' U_DISK_DB='0' U_BANDWIDTH='0' U_WEB_DOMAINS='0' U_WEB_SSL='0' U_WEB_ALIASES='0' U_DNS_DOMAINS='0' U_DNS_RECORDS='0' U_MAIL_DOMAINS='0' U_MAIL_DKIM='0' U_MAIL_ACCOUNTS='0' U_MAIL_SSL='0' U_DATABASES='0' U_CRON_JOBS='0' U_BACKUPS='0' LANGUAGE='' THEME='' NOTIFICATIONS='no' PREF_UI_SORT='name' LOGIN_DISABLED='no' LOGIN_USE_IPLIST='no' LOGIN_ALLOW_IPS='' TIME='$time' DATE='$date'" > $USER_DATA/user.conf chmod 660 $USER_DATA/user.conf # Updating quota if [ "$DISK_QUOTA" = 'yes' ]; then $BIN/v-update-user-quota "$user" fi # Updating admin counter if [ "$user" != 'admin' ]; then increase_user_value 'admin' '$U_USERS' fi # Run template trigger if [ -x "$HESTIA/data/packages/$package.sh" ]; then $HESTIA/data/packages/$package.sh "$user" "$email" "$name" fi # Adding jailed sftp env $BIN/v-add-user-sftp-jail $user #----------------------------------------------------------# # Hestia # #----------------------------------------------------------# # Logging $BIN/v-log-action "system" "Info" "Users" "User account added (Name: $user)." $BIN/v-log-action "$user" "Info" "System" "Welcome!" log_event "$OK" "$ARGUMENTS" exit