rebuild.sh 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  1. # User account rebuild
  2. rebuild_user_conf() {
  3. # Get user variables
  4. source $USER_DATA/user.conf
  5. # Creating user data files
  6. chmod 770 $USER_DATA
  7. chmod 660 $USER_DATA/user.conf
  8. touch $USER_DATA/backup.conf
  9. chmod 660 $USER_DATA/backup.conf
  10. touch $USER_DATA/history.log
  11. chmod 660 $USER_DATA/history.log
  12. touch $USER_DATA/stats.log
  13. chmod 660 $USER_DATA/stats.log
  14. # Update FNAME LNAME to NAME
  15. if [ -z "$NAME" ]; then
  16. NAME="$FNAME $LNAME"
  17. if [ -z $FNAME ]; then NAME=""; fi
  18. sed -i "s/FNAME='$FNAME'/NAME='$NAME'/g" $USER_DATA/user.conf
  19. sed -i "/LNAME='$LNAME'/d" $USER_DATA/user.conf
  20. fi
  21. if [ -z "${TWOFA+x}" ]; then
  22. sed -i "/RKEY/a TWOFA=''" $USER_DATA/user.conf
  23. fi
  24. if [ -z "${QRCODE+x}" ]; then
  25. sed -i "/TWOFA/a QRCODE=''" $USER_DATA/user.conf
  26. fi
  27. if [ -z "${PHPCLI+x}" ]; then
  28. sed -i "/QRCODE/a PHPCLI=''" $USER_DATA/user.conf
  29. fi
  30. if [ -z "${ROLE+x}" ]; then
  31. sed -i "/PHPCLI/a ROLE='user'" $USER_DATA/user.conf
  32. fi
  33. # Run template trigger
  34. if [ -x "$HESTIA/data/packages/$PACKAGE.sh" ]; then
  35. $HESTIA/data/packages/$PACKAGE.sh "$user" "$CONTACT" "$NAME"
  36. fi
  37. # Rebuild user
  38. shell=$(grep -w "$SHELL" /etc/shells |head -n1)
  39. /usr/sbin/useradd "$user" -s "$shell" -c "$CONTACT" \
  40. -m -d "$HOMEDIR/$user" > /dev/null 2>&1
  41. # Add a general group for normal users created by Hestia
  42. if [ -z "$(grep "^hestia-users:" /etc/group)" ]; then
  43. groupadd --system "hestia-users"
  44. fi
  45. # Add membership to hestia-users group to non-admin users
  46. if [ "$user" = "admin" ]; then
  47. setfacl -m "g:admin:r-x" "$HOMEDIR/$user"
  48. else
  49. usermod -a -G "hestia-users" "$user"
  50. setfacl -m "u:$user:r-x" "$HOMEDIR/$user"
  51. fi
  52. setfacl -m "g:hestia-users:---" "$HOMEDIR/$user"
  53. # Update user shell
  54. /usr/bin/chsh -s "$shell" "$user" &>/dev/null
  55. # Update password
  56. chmod u+w /etc/shadow
  57. sed -i "s|^$user:[^:]*:|$user:$MD5:|" /etc/shadow
  58. chmod u-w /etc/shadow
  59. # Building directory tree
  60. if [ -e "$HOMEDIR/$user/conf" ]; then
  61. chattr -i $HOMEDIR/$user/conf > /dev/null 2>&1
  62. fi
  63. # Create default writeable folders
  64. mkdir -p \
  65. $HOMEDIR/$user/conf \
  66. $HOMEDIR/$user/.config \
  67. $HOMEDIR/$user/.cache \
  68. $HOMEDIR/$user/.local \
  69. $HOMEDIR/$user/.composer \
  70. $HOMEDIR/$user/.ssh
  71. chmod a+x $HOMEDIR/$user
  72. chmod a+x $HOMEDIR/$user/conf
  73. chown --no-dereference $user:$user \
  74. $HOMEDIR/$user \
  75. $HOMEDIR/$user/.config \
  76. $HOMEDIR/$user/.cache \
  77. $HOMEDIR/$user/.local \
  78. $HOMEDIR/$user/.composer \
  79. $HOMEDIR/$user/.ssh
  80. chown root:root $HOMEDIR/$user/conf
  81. $BIN/v-add-user-sftp-jail "$user"
  82. # Update disk pipe
  83. sed -i "/ $user$/d" $HESTIA/data/queue/disk.pipe
  84. echo "$BIN/v-update-user-disk $user" >> $HESTIA/data/queue/disk.pipe
  85. # WEB
  86. if [ ! -z "$WEB_SYSTEM" ] && [ "$WEB_SYSTEM" != 'no' ]; then
  87. mkdir -p $USER_DATA/ssl
  88. chmod 770 $USER_DATA/ssl
  89. touch $USER_DATA/web.conf
  90. chmod 660 $USER_DATA/web.conf
  91. if [ "$(grep -w $user $HESTIA/data/queue/traffic.pipe)" ]; then
  92. echo "$BIN/v-update-web-domains-traff $user" \
  93. >> $HESTIA/data/queue/traffic.pipe
  94. fi
  95. echo "$BIN/v-update-web-domains-disk $user" \
  96. >> $HESTIA/data/queue/disk.pipe
  97. if [[ -L "$HOMEDIR/$user/web" ]]; then
  98. rm $HOMEDIR/$user/web
  99. fi
  100. mkdir -p $HOMEDIR/$user/conf/web/$domain
  101. mkdir -p $HOMEDIR/$user/web
  102. mkdir -p $HOMEDIR/$user/tmp
  103. chmod 751 $HOMEDIR/$user/conf/web
  104. chmod 751 $HOMEDIR/$user/web
  105. chmod 771 $HOMEDIR/$user/tmp
  106. chown --no-dereference $user:$user $HOMEDIR/$user/web
  107. if [ -z "$create_user" ]; then
  108. $BIN/v-rebuild-web-domains $user $restart
  109. fi
  110. fi
  111. # DNS
  112. if [ ! -z "$DNS_SYSTEM" ] && [ "$DNS_SYSTEM" != 'no' ]; then
  113. mkdir -p $USER_DATA/dns
  114. chmod 770 $USER_DATA/dns
  115. touch $USER_DATA/dns.conf
  116. chmod 660 $USER_DATA/dns.conf
  117. mkdir -p $HOMEDIR/$user/conf/dns
  118. chmod 751 $HOMEDIR/$user/conf/dns
  119. if [ -z "$create_user" ]; then
  120. $BIN/v-rebuild-dns-domains $user $restart
  121. fi
  122. fi
  123. if [ ! -z "$MAIL_SYSTEM" ] && [ "$MAIL_SYSTEM" != 'no' ]; then
  124. mkdir -p $USER_DATA/mail
  125. chmod 770 $USER_DATA/mail
  126. touch $USER_DATA/mail.conf
  127. chmod 660 $USER_DATA/mail.conf
  128. echo "$BIN/v-update-mail-domains-disk $user" \
  129. >> $HESTIA/data/queue/disk.pipe
  130. if [[ -L "$HOMEDIR/$user/mail" ]]; then
  131. rm $HOMEDIR/$user/mail
  132. fi
  133. mkdir -p $HOMEDIR/$user/conf/mail/$domain
  134. mkdir -p $HOMEDIR/$user/mail
  135. chmod 751 $HOMEDIR/$user/mail
  136. chmod 751 $HOMEDIR/$user/conf/mail
  137. if [ -z "$create_user" ]; then
  138. $BIN/v-rebuild-mail-domains $user
  139. fi
  140. fi
  141. if [ ! -z "$DB_SYSTEM" ] && [ "$DB_SYSTEM" != 'no' ]; then
  142. touch $USER_DATA/db.conf
  143. chmod 660 $USER_DATA/db.conf
  144. echo "$BIN/v-update-databases-disk $user" >> $HESTIA/data/queue/disk.pipe
  145. if [ -z "$create_user" ]; then
  146. $BIN/v-rebuild-databases $user
  147. fi
  148. fi
  149. if [ ! -z "$CRON_SYSTEM" ] && [ "$CRON_SYSTEM" != 'no' ]; then
  150. touch $USER_DATA/cron.conf
  151. chmod 660 $USER_DATA/cron.conf
  152. if [ -z "$create_user" ]; then
  153. $BIN/v-rebuild-cron-jobs $user $restart
  154. fi
  155. fi
  156. # Set immutable flag
  157. chattr +i $HOMEDIR/$user/conf > /dev/null 2>&1
  158. }
  159. # WEB domain rebuild
  160. rebuild_web_domain_conf() {
  161. # Ensure that global domain folders are available
  162. if [ ! -d /etc/$WEB_SYSTEM/conf.d/domains ]; then
  163. mkdir -p /etc/$WEB_SYSTEM/conf.d/domains
  164. fi
  165. if [ ! -d /etc/$PROXY_SYSTEM/conf.d/domains ]; then
  166. mkdir -p /etc/$PROXY_SYSTEM/conf.d/domains
  167. fi
  168. get_domain_values 'web'
  169. is_ip_valid $IP
  170. prepare_web_domain_values
  171. # Remove old web configuration files
  172. if [ -f /etc/$WEB_SYSTEM/conf.d/$domain.conf ]; then
  173. rm -f /etc/$WEB_SYSTEM/conf.d/$domain*.conf
  174. fi
  175. if [ -f /etc/$PROXY_SYSTEM/conf.d/$domain.conf ]; then
  176. rm -f /etc/$PROXY_SYSTEM/conf.d/$domain*.conf
  177. fi
  178. # Temporary allow write permissions to owner
  179. [ -d "$HOMEDIR/$user/web/$domain" ] && chmod 751 "$HOMEDIR/$user/web/$domain"
  180. # Rebuilding domain directories
  181. if [ -d "$HOMEDIR/$user/web/$domain/document_errors" ]; then
  182. $BIN/v-delete-fs-directory "$user" "$HOMEDIR/$user/web/$domain/document_errors"
  183. fi
  184. $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain"
  185. $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/public_html"
  186. $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/public_shtml"
  187. $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/document_errors"
  188. $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/cgi-bin"
  189. $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/private"
  190. $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/stats"
  191. $BIN/v-add-fs-directory "$user" "$HOMEDIR/$user/web/$domain/logs"
  192. # Creating domain logs
  193. if [ ! -e "/var/log/$WEB_SYSTEM/domains" ]; then
  194. mkdir -p /var/log/$WEB_SYSTEM/domains
  195. chmod 771 /var/log/$WEB_SYSTEM/domains
  196. fi
  197. touch /var/log/$WEB_SYSTEM/domains/$domain.bytes \
  198. /var/log/$WEB_SYSTEM/domains/$domain.log \
  199. /var/log/$WEB_SYSTEM/domains/$domain.error.log
  200. # Creating symlinks
  201. cd $HOMEDIR/$user/web/$domain/logs/
  202. ln -f -s /var/log/$WEB_SYSTEM/domains/$domain.log .
  203. ln -f -s /var/log/$WEB_SYSTEM/domains/$domain.error.log .
  204. cd /
  205. # Propagating html skeleton
  206. if [ -d "$WEBTPL/skel/document_errors/" ]; then
  207. user_exec cp -r "$WEBTPL/skel/document_errors/" "$HOMEDIR/$user/web/$domain/"
  208. fi
  209. # Set ownership
  210. chown --no-dereference $user:$user \
  211. $HOMEDIR/$user/web/$domain \
  212. $HOMEDIR/$user/web/$domain/private \
  213. $HOMEDIR/$user/web/$domain/cgi-bin \
  214. $HOMEDIR/$user/web/$domain/public_html \
  215. $HOMEDIR/$user/web/$domain/public_shtml
  216. chown -R $user:$user $HOMEDIR/$user/web/$domain/document_errors
  217. chown root:$user /var/log/$WEB_SYSTEM/domains/$domain.*
  218. # Adding vhost configuration
  219. conf="$HOMEDIR/$user/conf/web/$domain/$WEB_SYSTEM.conf"
  220. add_web_config "$WEB_SYSTEM" "$TPL.tpl"
  221. # Adding SSL vhost configuration
  222. if [ "$SSL" = 'yes' ]; then
  223. ssl_file_dir="$HOMEDIR/$user/conf/web/$domain/ssl"
  224. conf="$HOMEDIR/$user/conf/web/$domain/$WEB_SYSTEM.ssl.conf"
  225. if [ ! -d "$ssl_file_dir" ]; then
  226. mkdir -p $ssl_file_dir
  227. fi
  228. add_web_config "$WEB_SYSTEM" "$TPL.stpl"
  229. cp -f $USER_DATA/ssl/$domain.crt \
  230. $HOMEDIR/$user/conf/web/$domain/ssl/$domain.crt
  231. cp -f $USER_DATA/ssl/$domain.key \
  232. $HOMEDIR/$user/conf/web/$domain/ssl/$domain.key
  233. cp -f $USER_DATA/ssl/$domain.pem \
  234. $HOMEDIR/$user/conf/web/$domain/ssl/$domain.pem
  235. if [ -e "$USER_DATA/ssl/$domain.ca" ]; then
  236. cp -f $USER_DATA/ssl/$domain.ca \
  237. $HOMEDIR/$user/conf/web/$domain/ssl/$domain.ca
  238. fi
  239. fi
  240. # Refresh HTTPS redirection if previously enabled
  241. if [ "$SSL_FORCE" = 'yes' ]; then
  242. $BIN/v-delete-web-domain-ssl-force $user $domain no
  243. $BIN/v-add-web-domain-ssl-force $user $domain yes
  244. fi
  245. if [ "$SSL_HSTS" = 'yes' ]; then
  246. $BIN/v-delete-web-domain-ssl-hsts $user $domain no
  247. $BIN/v-add-web-domain-ssl-hsts $user $domain yes
  248. fi
  249. # Adding proxy configuration
  250. if [ ! -z "$PROXY_SYSTEM" ] && [ ! -z "$PROXY" ]; then
  251. conf="$HOMEDIR/$user/conf/web/$domain/$PROXY_SYSTEM.conf"
  252. add_web_config "$PROXY_SYSTEM" "$PROXY.tpl"
  253. if [ "$SSL" = 'yes' ]; then
  254. conf="$HOMEDIR/$user/conf/web/$domain/$PROXY_SYSTEM.ssl.conf"
  255. add_web_config "$PROXY_SYSTEM" "$PROXY.stpl"
  256. fi
  257. fi
  258. # Adding web stats parser
  259. if [ ! -z "$STATS" ]; then
  260. domain_idn=$domain
  261. format_domain_idn
  262. cat $WEBTPL/$STATS/$STATS.tpl |\
  263. sed -e "s|%ip%|$local_ip|g" \
  264. -e "s|%web_system%|$WEB_SYSTEM|g" \
  265. -e "s|%domain_idn%|$domain_idn|g" \
  266. -e "s|%domain%|$domain|g" \
  267. -e "s|%user%|$user|g" \
  268. -e "s|%apache_group%|$WEB_RGROUPS|g"\
  269. -e "s|%home%|$HOMEDIR|g" \
  270. -e "s|%alias%|${aliases//,/ }|g" \
  271. -e "s|%alias_idn%|${aliases_idn//,/ }|g" \
  272. > $HOMEDIR/$user/conf/web/$domain/$STATS.conf
  273. if [ "$STATS" == 'awstats' ]; then
  274. if [ -e "/etc/awstats/$STATS.$domain_idn.conf" ]; then
  275. rm -f "/etc/awstats/$STATS.$domain_idn.conf"
  276. fi
  277. ln -f -s $HOMEDIR/$user/conf/web/$domain/$STATS.conf \
  278. /etc/awstats/$STATS.$domain_idn.conf
  279. fi
  280. webstats="$BIN/v-update-web-domain-stat $user $domain"
  281. check_webstats=$(grep "$webstats" $HESTIA/data/queue/webstats.pipe)
  282. if [ -z "$check_webstats" ]; then
  283. echo "$webstats" >> $HESTIA/data/queue/webstats.pipe
  284. fi
  285. if [ ! -z "$STATS_USER" ]; then
  286. stats_dir="$HOMEDIR/$user/web/$domain/stats"
  287. if [ "$WEB_SYSTEM" = 'nginx' ]; then
  288. echo "auth_basic \"Web Statistics\";" |user_exec tee $stats_dir/auth.conf > /dev/null
  289. echo "auth_basic_user_file $stats_dir/.htpasswd;" |user_exec tee -a $stats_dir/auth.conf > /dev/null
  290. else
  291. echo "AuthUserFile $stats_dir/.htpasswd" |user_exec tee $stats_dir/.htaccess > /dev/null
  292. echo "AuthName \"Web Statistics\"" |user_exec tee -a $stats_dir/.htaccess > /dev/null
  293. echo "AuthType Basic" |user_exec tee -a $stats_dir/.htaccess > /dev/null
  294. echo "Require valid-user" |user_exec tee -a $stats_dir/.htaccess > /dev/null
  295. fi
  296. echo "$STATS_USER:$STATS_CRYPT" |user_exec tee $stats_dir/.htpasswd > /dev/null
  297. fi
  298. fi
  299. # Adding ftp users
  300. if [ -z "$FTP_SHELL" ]; then
  301. shell=$(which nologin)
  302. if [ -e "/usr/bin/rssh" ]; then
  303. shell='/usr/bin/rssh'
  304. fi
  305. else
  306. shell=$FTP_SHELL
  307. fi
  308. for ftp_user in ${FTP_USER//:/ }; do
  309. if [ -z "$(grep ^$ftp_user: /etc/passwd)" ]; then
  310. position=$(echo $FTP_USER |tr ':' '\n' |grep -n '' |\
  311. grep ":$ftp_user$" |cut -f 1 -d:)
  312. ftp_path=$(echo $FTP_PATH |tr ':' '\n' |grep -n '' |\
  313. grep "^$position:" |cut -f 2 -d :)
  314. ftp_md5=$(echo $FTP_MD5 | tr ':' '\n' |grep -n '' |\
  315. grep "^$position:" |cut -f 2 -d :)
  316. # rebuild S/FTP users
  317. $BIN/v-delete-web-domain-ftp "$user" "$domain" "$ftp_user"
  318. $BIN/v-add-web-domain-ftp "$user" "$domain" "${ftp_user#*_}" "!xplaceholder$FTP_MD5" "$ftp_path"
  319. # Updating ftp user password
  320. chmod u+w /etc/shadow
  321. sed -i "s|^$ftp_user:[^:]*:|$ftp_user:$ftp_md5:|" /etc/shadow
  322. chmod u-w /etc/shadow
  323. fi
  324. done
  325. # Adding http auth protection
  326. htaccess="$HOMEDIR/$user/conf/web/$domain/htaccess"
  327. htpasswd="$HOMEDIR/$user/conf/web/$domain/htpasswd"
  328. docroot="$HOMEDIR/$user/web/$domain/public_html"
  329. for auth_user in ${AUTH_USER//:/ }; do
  330. # Parsing auth user variables
  331. position=$(echo $AUTH_USER |tr ':' '\n' |grep -n '' |\
  332. grep ":$auth_user$" |cut -f 1 -d:)
  333. auth_hash=$(echo $AUTH_HASH |tr ':' '\n' |grep -n '' |\
  334. grep "^$position:" |cut -f 2 -d :)
  335. # Adding http auth user
  336. touch $htpasswd
  337. sed -i "/^$auth_user:/d" $htpasswd
  338. echo "$auth_user:$auth_hash" >> $htpasswd
  339. # Checking web server include
  340. if [ ! -e "$htaccess" ]; then
  341. if [ "$WEB_SYSTEM" != 'nginx' ]; then
  342. echo "<Directory $docroot>" > $htaccess
  343. echo " AuthUserFile $htpasswd" >> $htaccess
  344. echo " AuthName \"$domain access\"" >> $htaccess
  345. echo " AuthType Basic" >> $htaccess
  346. echo " Require valid-user" >> $htaccess
  347. echo "</Directory>" >> $htaccess
  348. else
  349. echo "auth_basic \"$domain password access\";" > $htaccess
  350. echo "auth_basic_user_file $htpasswd;" >> $htaccess
  351. fi
  352. chmod 640 $htpasswd $htaccess >/dev/null 2>&1
  353. fi
  354. done
  355. # Set folder permissions
  356. no_symlink_chmod 551 $HOMEDIR/$user/web/$domain \
  357. $HOMEDIR/$user/web/$domain/stats \
  358. $HOMEDIR/$user/web/$domain/logs
  359. no_symlink_chmod 751 $HOMEDIR/$user/web/$domain/private \
  360. $HOMEDIR/$user/web/$domain/cgi-bin \
  361. $HOMEDIR/$user/web/$domain/public_html \
  362. $HOMEDIR/$user/web/$domain/public_shtml \
  363. $HOMEDIR/$user/web/$domain/document_errors
  364. chmod 640 /var/log/$WEB_SYSTEM/domains/$domain.*
  365. chown --no-dereference $user:$WEB_RGROUPS $HOMEDIR/$user/web/$domain/public_*html
  366. }
  367. # DNS domain rebuild
  368. rebuild_dns_domain_conf() {
  369. # Get domain values
  370. get_domain_values 'dns'
  371. domain_idn=$(idn -t --quiet -a "$domain")
  372. # Checking zone file
  373. if [ ! -e "$USER_DATA/dns/$domain.conf" ]; then
  374. cat $DNSTPL/$TPL.tpl |\
  375. sed -e "s/%ip%/$IP/g" \
  376. -e "s/%domain_idn%/$domain_idn/g" \
  377. -e "s/%domain%/$domain/g" \
  378. -e "s/%ns1%/$ns1/g" \
  379. -e "s/%ns2%/$ns2/g" \
  380. -e "s/%ns3%/$ns3/g" \
  381. -e "s/%ns4%/$ns4/g" \
  382. -e "s/%time%/$TIME/g" \
  383. -e "s/%date%/$DATE/g" > $USER_DATA/dns/$domain.conf
  384. fi
  385. # Sorting records
  386. sort_dns_records
  387. # Updating zone
  388. update_domain_zone
  389. # Set permissions
  390. if [ "$DNS_SYSTEM" = 'named' ]; then
  391. dns_group='named'
  392. else
  393. dns_group='bind'
  394. fi
  395. # Set file permissions
  396. chmod 640 $HOMEDIR/$user/conf/dns/$domain.db
  397. chown root:$dns_group $HOMEDIR/$user/conf/dns/$domain.db
  398. # Get dns config path
  399. if [ -e '/etc/named.conf' ]; then
  400. dns_conf='/etc/named.conf'
  401. fi
  402. if [ -e '/etc/bind/named.conf' ]; then
  403. dns_conf='/etc/bind/named.conf'
  404. fi
  405. # Bind config check
  406. if [ "$SUSPENDED" = 'yes' ]; then
  407. rm_string=$(grep -n /etc/namedb/$domain.db $dns_conf | cut -d : -f 1)
  408. if [ ! -z "$rm_string" ]; then
  409. sed -i "$rm_string d" $dns_conf
  410. fi
  411. suspended_dns=$((suspended_dns + 1))
  412. else
  413. if [ -z "$(grep /$domain.db $dns_conf)" ]; then
  414. named="zone \"$domain_idn\" {type master; file"
  415. named="$named \"$HOMEDIR/$user/conf/dns/$domain.db\";};"
  416. echo "$named" >> $dns_conf
  417. fi
  418. fi
  419. user_domains=$((user_domains + 1))
  420. records=$(wc -l $USER_DATA/dns/$domain.conf | cut -f 1 -d ' ')
  421. user_records=$((user_records + records))
  422. update_object_value 'dns' 'DOMAIN' "$domain" '$RECORDS' "$records"
  423. }
  424. # MAIL domain rebuild
  425. rebuild_mail_domain_conf() {
  426. get_domain_values 'mail'
  427. if [[ "$domain" = *[![:ascii:]]* ]]; then
  428. domain_idn=$(idn -t --quiet -a $domain)
  429. else
  430. domain_idn=$domain
  431. fi
  432. # Inherit web domain local ip address
  433. unset -v nat ip local_ip domain_ip
  434. local domain_ip=$(get_object_value 'web' 'DOMAIN' "$domain" '$IP')
  435. if [ ! -z "$domain_ip" ]; then
  436. local local_ip=$(get_real_ip "$domain_ip")
  437. is_ip_valid "$local_ip" "$user"
  438. else
  439. get_user_ip
  440. fi
  441. if [ "$SUSPENDED" = 'yes' ]; then
  442. SUSPENDED_MAIL=$((SUSPENDED_MAIL +1))
  443. fi
  444. if [ ! -d "$USER_DATA/mail" ]; then
  445. rm -f $USER_DATA/mail
  446. mkdir $USER_DATA/mail
  447. fi
  448. # Rebuilding exim config structure
  449. if [[ "$MAIL_SYSTEM" =~ exim ]]; then
  450. rm -f /etc/$MAIL_SYSTEM/domains/$domain_idn
  451. mkdir -p $HOMEDIR/$user/conf/mail/$domain
  452. ln -s $HOMEDIR/$user/conf/mail/$domain \
  453. /etc/$MAIL_SYSTEM/domains/$domain_idn
  454. rm -f $HOMEDIR/$user/conf/mail/$domain/aliases
  455. rm -f $HOMEDIR/$user/conf/mail/$domain/antispam
  456. rm -f $HOMEDIR/$user/conf/mail/$domain/antivirus
  457. rm -f $HOMEDIR/$user/conf/mail/$domain/protection
  458. rm -f $HOMEDIR/$user/conf/mail/$domain/passwd
  459. rm -f $HOMEDIR/$user/conf/mail/$domain/fwd_only
  460. rm -f $HOMEDIR/$user/conf/mail/$domain/ip
  461. touch $HOMEDIR/$user/conf/mail/$domain/aliases
  462. touch $HOMEDIR/$user/conf/mail/$domain/passwd
  463. touch $HOMEDIR/$user/conf/mail/$domain/fwd_only
  464. # Setting outgoing ip address
  465. if [ ! -z "$local_ip" ]; then
  466. echo "$local_ip" > $HOMEDIR/$user/conf/mail/$domain/ip
  467. fi
  468. # Setting HELO for mail domain
  469. if [ ! -z "$local_ip" ]; then
  470. IP_RDNS=$(is_ip_rdns_valid "$local_ip")
  471. sed -i "/^${domain}:/d" $OSAL_DIR_EXIM_CONF/mailhelo.conf >/dev/null 2>&1
  472. if [ ! -z "$IP_RDNS" ]; then
  473. echo ${domain}:${IP_RDNS} >> $OSAL_DIR_EXIM_CONF/mailhelo.conf
  474. fi
  475. fi
  476. # Adding antispam protection
  477. if [ "$ANTISPAM" = 'yes' ]; then
  478. touch $HOMEDIR/$user/conf/mail/$domain/antispam
  479. fi
  480. # Adding antivirus protection
  481. if [ "$ANTIVIRUS" = 'yes' ]; then
  482. touch $HOMEDIR/$user/conf/mail/$domain/antivirus
  483. fi
  484. # Adding dkim
  485. if [ "$DKIM" = 'yes' ]; then
  486. cp $USER_DATA/mail/$domain.pem \
  487. $HOMEDIR/$user/conf/mail/$domain/dkim.pem
  488. fi
  489. # Removing configuration files if domain is suspended
  490. if [ "$SUSPENDED" = 'yes' ]; then
  491. rm -f $OSAL_DIR_EXIM_CONF/domains/$domain_idn
  492. rm -f /etc/dovecot/conf.d/domains/$domain_idn.conf
  493. fi
  494. # Adding mail directory
  495. if [ ! -e $HOMEDIR/$user/mail/$domain_idn ]; then
  496. mkdir "$HOMEDIR/$user/mail/$domain_idn"
  497. fi
  498. # Adding catchall email
  499. dom_aliases=$HOMEDIR/$user/conf/mail/$domain/aliases
  500. if [ ! -z "$CATCHALL" ]; then
  501. echo "*@$domain_idn:$CATCHALL" >> $dom_aliases
  502. fi
  503. fi
  504. # Rebuild domain accounts
  505. accs=0
  506. dom_disk=0
  507. if [ -e "$USER_DATA/mail/$domain.conf" ]; then
  508. accounts=$(search_objects "mail/$domain" 'SUSPENDED' "no" 'ACCOUNT')
  509. else
  510. accounts=''
  511. fi
  512. for account in $accounts; do
  513. (( ++accs))
  514. object=$(grep "ACCOUNT='$account'" $USER_DATA/mail/$domain.conf)
  515. FWD_ONLY='no'
  516. parse_object_kv_list "$object"
  517. if [ "$SUSPENDED" = 'yes' ]; then
  518. MD5='SUSPENDED'
  519. fi
  520. if [[ "$MAIL_SYSTEM" =~ exim ]]; then
  521. if [ "$QUOTA" = 'unlimited' ]; then
  522. QUOTA=0
  523. fi
  524. str="$account:$MD5:$user:mail::$HOMEDIR/$user::userdb_quota_rule=*:storage=${QUOTA}M"
  525. echo $str >> $HOMEDIR/$user/conf/mail/$domain/passwd
  526. for malias in ${ALIAS//,/ }; do
  527. echo "$malias@$domain_idn:$account@$domain_idn" >> $dom_aliases
  528. done
  529. if [ ! -z "$FWD" ]; then
  530. echo "$account@$domain_idn:$FWD" >> $dom_aliases
  531. fi
  532. if [ "$FWD_ONLY" = 'yes' ]; then
  533. echo "$account" >> $HOMEDIR/$user/conf/mail/$domain/fwd_only
  534. fi
  535. fi
  536. done
  537. # Set permissions and ownership
  538. if [[ "$MAIL_SYSTEM" =~ exim ]]; then
  539. chmod 660 $USER_DATA/mail/$domain.*
  540. chmod 771 $HOMEDIR/$user/conf/mail/$domain
  541. chmod 660 $HOMEDIR/$user/conf/mail/$domain/*
  542. chmod 771 /etc/$MAIL_SYSTEM/domains/$domain_idn
  543. chmod 770 $HOMEDIR/$user/mail/$domain_idn
  544. chown -R $MAIL_USER:mail $HOMEDIR/$user/conf/mail/$domain
  545. if [ "$IMAP_SYSTEM" = "dovecot" ]; then
  546. chown -R dovecot:mail $HOMEDIR/$user/conf/mail/$domain/passwd
  547. fi
  548. chown $user:mail $HOMEDIR/$user/mail/$domain_idn
  549. fi
  550. # Add missing SSL configuration flags to existing domains
  551. # for per-domain SSL migration
  552. sslcheck=$(grep "DOMAIN='$domain'" $USER_DATA/mail.conf | grep SSL)
  553. if [ -z "$sslcheck" ]; then
  554. sed -i "s|$domain'|$domain' SSL='no' LETSENCRYPT='no'|g" $USER_DATA/mail.conf
  555. fi
  556. # Remove and recreate SSL configuration
  557. if [ -f "$HOMEDIR/$user/conf/mail/$domain/ssl/$domain.crt" ]; then
  558. del_mail_ssl_config
  559. add_mail_ssl_config
  560. update_object_value 'mail' 'DOMAIN' "$domain" '$SSL' "yes"
  561. else
  562. update_object_value 'mail' 'DOMAIN' "$domain" '$SSL' "no"
  563. fi
  564. dom_disk=0
  565. for account in $(search_objects "mail/$domain" 'SUSPENDED' "no" 'ACCOUNT'); do
  566. home_dir=$HOMEDIR/$user/mail/$domain/$account
  567. if [ -e "$home_dir" ]; then
  568. udisk=$(nice -n 19 du -shm $home_dir | cut -f 1 )
  569. else
  570. udisk=0
  571. fi
  572. update_object_value "mail/$domain" 'ACCOUNT' "$account" '$U_DISK' "$udisk"
  573. dom_disk=$((dom_disk + udisk))
  574. done
  575. update_object_value 'mail' 'DOMAIN' "$domain" '$ACCOUNTS' "$accs"
  576. update_object_value 'mail' 'DOMAIN' "$domain" '$U_DISK' "$dom_disk"
  577. # Update usage counters
  578. U_MAIL_ACCOUNTS=$((U_MAIL_ACCOUNTS + accs))
  579. U_MAIL_DOMAINS=$((U_MAIL_DOMAINS + 1))
  580. recalc_user_disk_usage
  581. }
  582. # Rebuild MySQL
  583. rebuild_mysql_database() {
  584. mysql_connect $HOST
  585. mysql_query "CREATE DATABASE \`$DB\` CHARACTER SET $CHARSET" >/dev/null
  586. if [ "$mysql_fork" = "mysql" ]; then
  587. # mysql
  588. if [ "$(echo $mysql_ver |cut -d '.' -f2)" -ge 7 ]; then
  589. # mysql >= 5.7
  590. mysql_query "CREATE USER IF NOT EXISTS \`$DBUSER\`" > /dev/null
  591. mysql_query "CREATE USER IF NOT EXISTS \`$DBUSER\`@localhost" > /dev/null
  592. query="UPDATE mysql.user SET authentication_string='$MD5'"
  593. query="$query WHERE User='$DBUSER'"
  594. else
  595. # mysql < 5.7
  596. query="UPDATE mysql.user SET Password='$MD5' WHERE User='$DBUSER'"
  597. fi
  598. else
  599. # mariadb
  600. if [ "$(echo $mysql_ver |cut -d '.' -f1)" -eq 5 ]; then
  601. # mariadb = 5
  602. mysql_query "CREATE USER \`$DBUSER\`" > /dev/null
  603. mysql_query "CREATE USER \`$DBUSER\`@localhost" > /dev/null
  604. else
  605. # mariadb = 10
  606. mysql_query "CREATE USER IF NOT EXISTS \`$DBUSER\` IDENTIFIED BY PASSWORD '$MD5'" > /dev/null
  607. mysql_query "CREATE USER IF NOT EXISTS \`$DBUSER\`@localhost IDENTIFIED BY PASSWORD '$MD5'" > /dev/null
  608. fi
  609. # mariadb any version
  610. query="UPDATE mysql.user SET Password='$MD5' WHERE User='$DBUSER'"
  611. fi
  612. mysql_query "GRANT ALL ON \`$DB\`.* TO \`$DBUSER\`@\`%\`" >/dev/null
  613. mysql_query "GRANT ALL ON \`$DB\`.* TO \`$DBUSER\`@localhost" >/dev/null
  614. mysql_query "$query" >/dev/null
  615. mysql_query "FLUSH PRIVILEGES" >/dev/null
  616. }
  617. # Rebuild PostgreSQL
  618. rebuild_pgsql_database() {
  619. host_str=$(grep "HOST='$HOST'" $HESTIA/conf/pgsql.conf)
  620. parse_object_kv_list "$host_str"
  621. export PGPASSWORD="$PASSWORD"
  622. if [ -z $HOST ] || [ -z $USER ] || [ -z $PASSWORD ] || [ -z $TPL ]; then
  623. echo "Error: postgresql config parsing failed"
  624. if [ ! -z "$SENDMAIL" ]; then
  625. echo "Can't parse PostgreSQL config" | $SENDMAIL -s "$subj" $email
  626. fi
  627. log_event "$E_PARSING" "$ARGUMENTS"
  628. exit $E_PARSING
  629. fi
  630. query='SELECT VERSION()'
  631. psql -h $HOST -U $USER -c "$query" > /dev/null 2>&1
  632. if [ '0' -ne "$?" ]; then
  633. echo "Error: Connection failed"
  634. if [ ! -z "$SENDMAIL" ]; then
  635. echo "Database connection to PostgreSQL host $HOST failed" |\
  636. $SENDMAIL -s "$subj" $email
  637. fi
  638. log_event "$E_CONNECT" "$ARGUMENTS"
  639. exit $E_CONNECT
  640. fi
  641. query="CREATE ROLE $DBUSER"
  642. psql -h $HOST -U $USER -c "$query" > /dev/null 2>&1
  643. query="UPDATE pg_authid SET rolpassword='$MD5' WHERE rolname='$DBUSER'"
  644. psql -h $HOST -U $USER -c "$query" > /dev/null 2>&1
  645. query="CREATE DATABASE $DB OWNER $DBUSER"
  646. if [ "$TPL" = 'template0' ]; then
  647. query="$query ENCODING '$CHARSET' TEMPLATE $TPL"
  648. else
  649. query="$query TEMPLATE $TPL"
  650. fi
  651. psql -h $HOST -U $USER -c "$query" > /dev/null 2>&1
  652. query="GRANT ALL PRIVILEGES ON DATABASE $DB TO $DBUSER"
  653. psql -h $HOST -U $USER -c "$query" > /dev/null 2>&1
  654. query="GRANT CONNECT ON DATABASE template1 to $DBUSER"
  655. psql -h $HOST -U $USER -c "$query" > /dev/null 2>&1
  656. }
  657. # Import MySQL dump
  658. import_mysql_database() {
  659. host_str=$(grep "HOST='$HOST'" $HESTIA/conf/mysql.conf)
  660. parse_object_kv_list "$host_str"
  661. if [ -z $HOST ] || [ -z $USER ] || [ -z $PASSWORD ]; then
  662. echo "Error: mysql config parsing failed"
  663. log_event "$E_PARSING" "$ARGUMENTS"
  664. exit $E_PARSING
  665. fi
  666. mysql -h $HOST -u $USER -p$PASSWORD $DB < $1 > /dev/null 2>&1
  667. }
  668. # Import PostgreSQL dump
  669. import_pgsql_database() {
  670. host_str=$(grep "HOST='$HOST'" $HESTIA/conf/pgsql.conf)
  671. parse_object_kv_list "$host_str"
  672. export PGPASSWORD="$PASSWORD"
  673. if [ -z $HOST ] || [ -z $USER ] || [ -z $PASSWORD ] || [ -z $TPL ]; then
  674. echo "Error: postgresql config parsing failed"
  675. log_event "$E_PARSING" "$ARGUMENTS"
  676. exit $E_PARSING
  677. fi
  678. psql -h $HOST -U $USER $DB < $1 > /dev/null 2>&1
  679. }