rebuild.sh 28 KB

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