Download | Plain Text | No Line Numbers


  1. #!/bin/sh
  2. #
  3. # Copyright (C) 2008 Manuel Mausz (manuel@mausz.at)
  4. # http://manuel.mausz.at/coding/autoresponder/
  5. #
  6. # This program is free software; you can redistribute it and/or
  7. # modify it under the terms of the GNU General Public License
  8. # as published by the Free Software Foundation; either
  9. # version 2 of the License, or (at your option) any later
  10. # version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program; if not, write to the Free Software Foundation,
  19. # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20.  
  21.  
  22. cfx_conf=""
  23. debug=0
  24. alwaysyes=0
  25. nobackup=0
  26. arbin="autoresponder.pl"
  27. arsql="autoresponder.sql"
  28. arbackup=".old"
  29.  
  30. aruid=""
  31. argid=""
  32. archmod="0550"
  33. smrsh="/etc/smrsh /etc/mail/smrsh"
  34.  
  35. #-------------------------------------------------------------------------------
  36.  
  37. cfx_getconf()
  38. {
  39. file="$1"
  40. name="$2"
  41. var="$3"
  42. maybezero="$4"
  43. value=$(grep "$name" "$file" | tail -n 1 | cut -d"'" -f2 2>/dev/null)
  44. eval "$var=\"$value\""
  45. if [ -z "$maybezero" ] && [ -z "$value" ]
  46. then
  47. echo "ERROR: Unable to get configuration value for $name from $cfx_conf"
  48. exit 1
  49. fi
  50. }
  51.  
  52. askuser()
  53. {
  54. yes=$1
  55. if [ $yes -ne 1 ]
  56. then
  57. read -p "OK (y/n)? " ok
  58. if [ "$ok" != "y" ]
  59. then
  60. echo "Aborting..."
  61. exit
  62. fi
  63. fi
  64. }
  65.  
  66. echodbg()
  67. {
  68. if [ "$debug" -eq 1 ]
  69. then
  70. echo "DEBUG: $*"
  71. fi
  72. }
  73.  
  74. print_usage()
  75. {
  76. echo "Usage: ./autoresponder.run /path/to/confixx_main.conf"
  77. echo " ./autoresponder.run -- [-y] [-d] [-nb] /path/to/confixx_main.conf"
  78. echo "Options:"
  79. echo " -y, --yes enter yes to all questions"
  80. echo " -nb, --nobackup don't do any backups"
  81. echo " -d, --debug enable debug messages"
  82. }
  83.  
  84. #-------------------------------------------------------------------------------
  85.  
  86. echo ""
  87. echo "Running setup..."
  88.  
  89. # fetch OS
  90. arch=$(uname -s)
  91.  
  92. # parse additional commandline parameters
  93. while [ $# -gt 0 ]
  94. do
  95. case "$1" in
  96. -d|--debug)
  97. debug=1
  98. ;;
  99. -y|--yes)
  100. alwaysyes=1
  101. ;;
  102. -nb|--nobackup)
  103. nobackup=1
  104. ;;
  105. *)
  106. if [ -z "$cfx_conf" ]
  107. then
  108. cfx_conf="$1"
  109. fi
  110. ;;
  111. esac
  112. shift
  113. done
  114.  
  115. # disabled as it might confuse users
  116. # fallback to default path
  117. #[ -z "$cfx_conf" ] && cfx_conf="/root/confixx/confixx_main.conf"
  118.  
  119. # check confixx config
  120. if [ -z "$cfx_conf" ]
  121. then
  122. print_usage
  123. exit 1
  124. fi
  125. if [ ! -r "$cfx_conf" ]
  126. then
  127. echo "ERROR: Unable to read $cfx_conf. Maybe wrong path."
  128. echo ""
  129. print_usage
  130. exit 1
  131. fi
  132.  
  133. # check package file exists
  134. if [ ! -f "$arbin" ] || [ ! -f "$arsql" ]
  135. then
  136. echo "ERROR: Couldn't find package files. Setup run manually?"
  137. exit 1
  138. fi
  139.  
  140. # get some configuration values
  141. echo "Fetching confixx variables from $cfx_conf..."
  142. cfx_getconf "$cfx_conf" '$ServerID =' "cfx_serverid"
  143. cfx_getconf "$cfx_conf" '$dbType =' "cfx_db_type"
  144. cfx_getconf "$cfx_conf" '$dbServer =' "cfx_db_address"
  145. cfx_getconf "$cfx_conf" '$dbPort =' "cfx_db_port"
  146. cfx_getconf "$cfx_conf" '$db_address =' "cfx_db_dsn"
  147. cfx_getconf "$cfx_conf" '$dbUser =' "cfx_db_user"
  148. cfx_getconf "$cfx_conf" '$dbPw =' "cfx_db_pass"
  149. cfx_getconf "$cfx_conf" '$dbDB =' "cfx_db_name"
  150. cfx_getconf "$cfx_conf" '$bin_autorespond =' "cfx_bin_autorespond"
  151. cfx_getconf "$cfx_conf" '$bin_mysql =' "cfx_bin_mysql" 1
  152. cfx_getconf "$cfx_conf" '$bin_psql =' "cfx_bin_psql" 1
  153. cfx_getconf "$cfx_conf" '$bin_sendmail =' "cfx_bin_sendmail"
  154. cfx_getconf "$cfx_conf" '$mta =' "cfx_mta"
  155. cfx_getconf "$cfx_conf" '$mta_uid =' "cfx_mta_uid" 1
  156. cfx_getconf "$cfx_conf" '$mta_gid =' "cfx_mta_gid" 1
  157. cfx_getconf "$cfx_conf" '$MailConfigFile =' "cfx_mta_config" 1
  158. cfx_getconf "$cfx_conf" '$passwdDir =' "cfx_passwd"
  159.  
  160. echodbg "cfx_serverid = $cfx_serverid"
  161. echodbg "cfx_db_type = $cfx_db_type"
  162. echodbg "cfx_db_address = $cfx_db_address"
  163. echodbg "cfx_db_port = $cfx_db_port"
  164. echodbg "cfx_db_dsn = $cfx_db_dsn"
  165. echodbg "cfx_db_user = $cfx_db_user"
  166. echodbg "cfx_db_pass = $cfx_db_pass"
  167. echodbg "cfx_db_name = $cfx_db_name"
  168. echodbg "cfx_bin_autorespond = $cfx_bin_autorespond"
  169. echodbg "cfx_bin_sendmail = $cfx_bin_sendmail"
  170. echodbg "cfx_bin_mysql = $cfx_bin_mysql"
  171. echodbg "cfx_bin_psql = $cfx_bin_psql"
  172. echodbg "cfx_mta = $cfx_mta"
  173. echodbg "cfx_mta_uid = $cfx_mta_uid"
  174. echodbg "cfx_mta_gid = $cfx_mta_gid"
  175. echodbg "cfx_mta_config = $cfx_mta_config"
  176. echodbg "cfx_passwd = $cfx_passwd"
  177.  
  178. #-------------------------------------------------------------------------------
  179.  
  180. # check for an existing autoresponder backup
  181. echo "Checking for an existing autoresponder backup..."
  182. if [ $nobackup -eq 0 ] && [ -f "${cfx_bin_autorespond}${arbackup}" ]
  183. then
  184. echo "ERROR: Autoresponder backup ${cfx_bin_autorespond}${arbackup} already exist."
  185. echo " In order to run this setup you've to move or remove this file."
  186. exit 1
  187. fi
  188.  
  189. #-------------------------------------------------------------------------------
  190.  
  191. # check/build database commandline
  192. echo ""
  193. echo "Checking database settings..."
  194. dbtool=""
  195. dbbin=""
  196. if [ "$cfx_db_type" = "mysql" ]
  197. then
  198. dbbin="$cfx_bin_mysql"
  199. dbtool='$cfx_bin_mysql -u"$cfx_db_user" -p"$cfx_db_pass" -D"$cfx_db_name"'
  200. if [ "$cfx_db_port" -ge 0 2>/dev/null ]
  201. then
  202. dbtool=$dbtool' -h"$cfx_db_address" -P"$cfx_db_port"'
  203. else
  204. dbtool=$dbtool' -S"$cfx_db_port"'
  205. fi
  206. elif [ "$cfx_db_type" = "pgsql" ]
  207. then
  208. # TODO this isn't tested!
  209. dbbin="$cfx_bin_psql"
  210. dbtool='$cfx_bin_psql -U"$cfx_db_user" -d"$cfx_db_name"'
  211. if [ "$cfx_db_port" -ge 0 2>/dev/null ]
  212. then
  213. dbtool=$dbtool' -h"$cfx_db_address" -p"$cfx_db_port"'
  214. else
  215. dbtool=$dbtool' -S"$cfx_db_port"'
  216. fi
  217. else
  218. echo "ERROR: Unknown database type ($cfx_db_type)."
  219. exit 1
  220. fi
  221. if [ -z "$dbbin" ]
  222. then
  223. echo "ERROR: Database is $cfx_db_type but commandline tool (\$bin_mysql/\$bin_psql) is not defined."
  224. exit 1
  225. fi
  226.  
  227. # display results and ask user
  228. eval "cmdstr=\"$dbtool\""
  229. echo "Found database type \"$cfx_db_type\". Trying to execute:"
  230. echo " $cmdstr < $arsql"
  231. askuser $alwaysyes
  232.  
  233. # create password for pgsql and execute command
  234. if [ "$cfx_db_type" = "pgsql" ]
  235. then
  236. export PGPASSFILE="$HOME/.pgpasscfx"
  237. touch "$PGPASSFILE"
  238. chmod 0600 "$PGPASSFILE"
  239. echo "*:*:$cfx_db_name:$cfx_db_user:$cfx_db_pass" > "$PGPASSFILE"
  240. fi
  241. eval $dbtool < $arsql
  242. ret=$?
  243. [ ! -z "$PGPASSFILE" ] && [ -e "$PGPASSFILE" ] && rm -f "$PGPASSFILE"
  244. if [ $ret != 0 ]
  245. then
  246. echo "ERROR: Unable to create/update autoresponder database table."
  247. exit 1
  248. fi
  249. echo "Created/updated database table successfully."
  250.  
  251. #-------------------------------------------------------------------------------
  252.  
  253. # first change file permissions
  254. chmod 0600 "$arbin"
  255.  
  256. # replace placeholders in our autoresponder
  257. echo ""
  258. echo "Trying to replace the following variables in enhanced autoresponder:"
  259. echo " Database DSN = $cfx_db_dsn"
  260. echo " Database user = $cfx_db_user"
  261. echo " Database pass = $cfx_db_pass"
  262. echo " Confixx ServerID = $cfx_serverid"
  263. echo " Mailer Binary = $cfx_bin_sendmail"
  264. askuser $alwaysyes
  265.  
  266. sed -i -e "s%INSERT VALUE OF \$db_address FROM confixx_main\.conf%${cfx_db_dsn}%" "$arbin"
  267. sed -i -e "s%INSERT VALUE OF \$dbUser FROM confixx_main\.conf%${cfx_db_user}%" "$arbin"
  268. sed -i -e "s%INSERT VALUE OF \$dbPw FROM confixx_main\.conf%${cfx_db_pass}%" "$arbin"
  269. sed -i -e "s%INSERT VALUE OF \$ServerID FROM confixx_main\.conf%${cfx_serverid}%" "$arbin"
  270. sed -i -e "s%INSERT VALUE OF \$bin_sendmail FROM confixx_main\.conf%${cfx_bin_sendmail}%" "$arbin"
  271. echo "Replaced variables successfully."
  272.  
  273. #-------------------------------------------------------------------------------
  274.  
  275. # check for old autoresponder
  276. echo ""
  277. echo "Trying to determine uid/gid/chmod from origin autoresponder..."
  278. if [ ! -f "$cfx_bin_autorespond" ]
  279. then
  280. echo "WARNING: Origin autoresponder ($cfx_bin_autorespond) doesn't exist."
  281.  
  282. # the following block contains some ugly stuff
  283. if [ "$cfx_mta" = "postfix" ]
  284. then
  285. echo "Trying to determine values from postfix configuration..."
  286.  
  287. defuser=""
  288. if [ -f "$cfx_mta_config" ]
  289. then
  290. defuser=$(awk -F'=' '{
  291. if ($1 ~ /^\s*default_privs\s*/) {
  292. str="";
  293. for(i=2; i<=NF; i++) {
  294. str=str""$i;
  295. if (i < NF) str=str""FS
  296. };
  297. sub(/^ */, "", str);
  298. sub(/ *$/, "", str);
  299. print str
  300. };
  301. }' "$cfx_mta_config")
  302. if [ $? != 0 ]
  303. then
  304. echo "ERROR: Unable to read setting 'default_privs' from $cfx_mta_config."
  305. exit 1
  306. fi
  307.  
  308. echo "Using value from setting 'default_privs' from $cfx_mta_config..."
  309. fi
  310. if [ -z "$defuser" ]
  311. then
  312. echo "WARNING: Unable to read postfix configuration ($cfx_mta_config)."
  313. echo "Fallback to unprivileged user (nobody)..."
  314. defuser="nobody"
  315. fi
  316.  
  317. # someone know a better way to do this without using
  318. # arrays from bash?
  319. line=$(grep "$defuser" "$cfx_passwd")
  320. aruid=$(echo "$line" | awk -F':' '{print $3}')
  321. argid=$(echo "$line" | awk -F':' '{print $4}')
  322. else
  323. echo "Using values from confixx_main.conf..."
  324. aruid="$cfx_mta_uid"
  325. argid="$cfx_mta_gid"
  326. fi
  327. else
  328. echo "Using values from origin autoresponder..."
  329. if [ "$arch" = "Linux" ]
  330. then
  331. stat=$(stat -c '%u %g %a' "$cfx_bin_autorespond")
  332. else
  333. stat=$(stat -f "%u %g %OMp%OLp" "$cfx_bin_autorespond")
  334. fi
  335. aruid=$(echo "$stat" | awk '{print $1}')
  336. argid=$(echo "$stat" | awk '{print $2}')
  337. archmod=$(echo "$stat" | awk '{print $3}')
  338. fi
  339.  
  340. # sanity check
  341. if [ -z "$aruid" ] || [ -z "$argid" ]
  342. then
  343. echo "ERROR: Unable to read uid and/or gid for user $defuser from $cfx_passwd."
  344. exit 1
  345. fi
  346.  
  347. # display results and ask user
  348. echo "Trying to install enhanced autoresponder using the following parameters:"
  349. echo " Destination = $cfx_bin_autorespond"
  350. [ $nobackup -eq 0 ] && echo " Backup = ${cfx_bin_autorespond}${arbackup}"
  351. echo " UID = $aruid"
  352. echo " GID = $argid"
  353. echo " CHMOD = $archmod"
  354. echo " shmrsh = $smrsh"
  355. askuser $alwaysyes
  356.  
  357. # chown + chmod
  358. chown -h $aruid:$argid "$arbin" && chmod $archmod "$arbin"
  359. if [ $? != 0 ]
  360. then
  361. echo "ERROR: Unable to change ownership or change file permissions for file $arbin."
  362. exit 1
  363. fi
  364.  
  365. # create backup
  366. if [ $nobackup -eq 0 ] && [ -f "$cfx_bin_autorespond" ]
  367. then
  368. mv "$cfx_bin_autorespond" "${cfx_bin_autorespond}${arbackup}"
  369. if [ $? != 0 ]
  370. then
  371. echo "ERROR: Unable to create backup of origin autoresponder in ${cfx_bin_autorespond}${arbackup}."
  372. exit 1
  373. fi
  374. fi
  375.  
  376. # move enchanced autoresponder to destination
  377. mv "$arbin" "$cfx_bin_autorespond"
  378. if [ $? != 0 ]
  379. then
  380. echo "ERROR: Unable to move enhanced autoresponder from setup directory to $cfx_bin_autorespond."
  381. exit 1
  382. fi
  383.  
  384. # create symlinks for smrsh
  385. for dir in $smrsh; do
  386. if [ ! -d "$dir" ] || [ -e "$dir/$arbin" ]
  387. then
  388. continue
  389. fi
  390. ln -s "$cfx_bin_autorespond" "$dir/$arbin"
  391. echo "Created symlinks for smrsh in $dir."
  392. done
  393.  
  394. # additional info for sendmail
  395. if [ "$cfx_mta" = "sendmail" ]
  396. then
  397. cat <<"EOF"
  398.  
  399. NOTES FOR SENDMAIL
  400. ==================
  401. Sendmail is not passing the envelope sender (also known as the value of header
  402. "Return-Path") to the executable. Although it won't be a fatal error, the header
  403. should be checked to detect bounces more easily.
  404. In order to let sendmail pass the header, you need to modify your sendmail config
  405. (sendmail.cf) and add the char "P" to the field "F" in line "prog".
  406. e.g from:
  407. Mprog, P=/usr/sbin/smrsh, F=lsDFMoqeu9, S=EnvFromL/HdrFromL, ....
  408. to
  409. Mprog, P=/usr/sbin/smrsh, F=lsDFMoqeu9P, S=EnvFromL/HdrFromL, ....
  410. "P" should already be defined as "HP?Return-Path: <$g>" (in sendmail.cf too).
  411. Don't forget to restart sendmail afterwards.
  412. EOF
  413. fi
  414.  
  415. # we're done
  416. echo ""
  417. echo "Installation completed successfully."
  418.