summaryrefslogtreecommitdiff
path: root/localaddmysqldb
blob: 2e8c7802c82e213597afa31141384f76b081b0bc (plain)
  1. #!/bin/bash
  2. #
  3. # /usr/local/sbin/localaddmysqldb
  4. # Copyright 2001-2006 Jonas Smedegaard <dr@jones.dk>
  5. #
  6. # $Id: localaddmysqldb,v 1.11 2006-07-16 12:34:00 jonas Exp $
  7. #
  8. # Add/update MySQL database
  9. #
  10. # This script makes use of the Debian package wwwconfig-common if installed
  11. #
  12. # TODO: Make script (mostly) work as noon-root
  13. # TODO: Add a --dry-run or --test option showing what would be done (how options are set, and a descriptive text about how they are used)
  14. # TODO: Add option to reset access for all existing databases owned by user:
  15. # echo $alldb | egrep "^$dbuser(_|$)"
  16. # TODO: Split in init-mysql-user and add-mysql-db
  17. # TODO: Disallow same password for <user> and <user>-admin
  18. # TODO: Only ask for password if it doesn't exist already
  19. # TODO: Creating a new unix user and mysql user sets <user>-admin password equal to unix password
  20. # TODO: Have database administrator default to root when asked for but input is blank
  21. # TODO: Don't ask for admin password (or hint that it may not be needed) if /root/.my.cnf exists
  22. set -e
  23. prg=`basename $0`
  24. TEMP=`getopt -o hu:U:D:Z:i::v::q::f::z:: --long help,user:,dbuser:,dbserver:,dballow:,info::,verbose::,debug::,query::,force::,ez:: -n "$prg" -- "$@"`
  25. # Check for non-GNU getopt
  26. if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
  27. eval set -- "$TEMP"
  28. # Defaults are evaluated at runtime in this order
  29. # (If changing defaults, you might need to change these as well)
  30. opts1="user dbserver dballow ez" # Options with self-contained defaults
  31. opts2="dbuser home" # Options requiring $opts1 to resolve default
  32. optsboolean="debug verbose info query force" # Do not touch these!
  33. # Defaults
  34. defaultuser="www-data"
  35. defaultdbuser='$user'
  36. defaultdbserver="localhost"
  37. defaultdballow="localhost"
  38. defaultinfo="on"
  39. defaultverbose="off"
  40. defaultdebug="off"
  41. defaultquery="on"
  42. defaultforce="off"
  43. defaultez="off"
  44. # Defaults not (yet) user configurable
  45. defaulthome="/var/www"
  46. # Override defaults from config file if available
  47. if [ -e /etc/local/localaddmysqldb.conf ]; then
  48. . /etc/local/localaddmysqldb.conf
  49. fi
  50. # This needs to exist from before parsing options
  51. debug="off"
  52. function usage() {
  53. echo "Usage: $prg [OPTION]... DBNAME [DBNAME]..."
  54. echo "Add/update MySQL database"
  55. echo
  56. echo "Mandatory arguments to long options are mandatory for short options too."
  57. echo " -h, --help Show this help"
  58. echo " -u, --user=UID System user id (default: $defaultuser)"
  59. echo " -U, --dbuser=UID MySQL database user (default: $defaultdbuser)"
  60. echo " -D, --dbserver=HOST IP or host of MySQL server (default:"
  61. echo " $defaultdbserver)"
  62. echo " -Z, --dballow=HOST IP or host of application server (default:"
  63. echo " $defaultdballow)"
  64. echo " -i, --info[=on|off] Show info during installation (default: $defaultinfo)"
  65. echo " -v, --verbose[=on|off] Show details during installation (default: $defaultverbose)"
  66. echo " --debug[=on|off] Show debug during installation (default: $defaultdebug)"
  67. echo " -q, --query[=on|off] Ask for missing options (default: $defaultquery)"
  68. echo " -f, --force[=on|off] Replace existing installation (default: $defaultforce)"
  69. echo " -z, --ez=[=on|off] Setup as eZ site (default: $defaultez)"
  70. echo
  71. echo "Each DBNAME can contain only alphanumerics."
  72. echo
  73. echo "MySQL password for \$dbuser can be stored in \$HOME/.my.cnf of \$user."
  74. }
  75. function setopts () {
  76. for opt in $@; do
  77. defaultvalue="`eval echo \$\{default$opt\}`"
  78. value="`eval echo \$\{$opt:-$defaultvalue\}`"
  79. if [ "$value" = '[[ASK]]' ]; then
  80. if [ -n "$query" ]; then
  81. echo -n "Enter value for $opt: "
  82. read value
  83. echo
  84. else
  85. echo "ERROR: value for $opt requested, but not running interactively!"
  86. exit 1
  87. fi
  88. fi
  89. if [ -z "$value" ]; then
  90. echo "ERROR: Value of \"$opt\" is empty!"
  91. exit 1
  92. fi
  93. eval $opt=\"$value\"
  94. if [ "$debug" = "1" -o "$debug" = "on" ]; then
  95. echo "----> $opt=\"$value\" (default: \"$defaultvalue\")"
  96. fi
  97. done
  98. }
  99. while true ; do
  100. case "$1" in
  101. -h|--help) usage; exit 0;;
  102. -u|--user) user="$2"; shift 2;;
  103. -U|--dbuser) dbuser="$2"; shift 2;;
  104. -D|--dbserver) dbserver="$2"; shift 2;;
  105. -Z|--dballow) dballow="$2"; shift 2;;
  106. -i|--info) case "$2" in ""|on) info="on";; *) info="off";; esac; shift 2;;
  107. -v|--verbose) case "$2" in ""|on) verbose="on";; *) verbose="off";; esac; shift 2;;
  108. --debug) case "$2" in ""|on) debug="on";; *) debug="off";; esac; shift 2;;
  109. -q|--query) case "$2" in ""|on) query="on";; *) query="off";; esac; shift 2;;
  110. -f|--force) case "$2" in ""|on) force="on";; *) force="off";; esac; shift 2;;
  111. -z|--ez) case "$2" in ""|on) ez="on";; *) ez="off";; esac; shift 2;;
  112. --) shift; break;;
  113. *) echo "Internal error!" ; exit 1 ;;
  114. esac
  115. done
  116. setopts $optsboolean
  117. if [ "$debug" = "1" -o "$debug" = "on" ]; then
  118. verbose="on" # Debug implies verbose
  119. fi
  120. for boolean in $optsboolean; do
  121. case `eval echo \$\{$boolean\}` in
  122. on) eval $boolean="1";;
  123. off) eval $boolean="";;
  124. *) echo "ERROR: Value of boolean option \"$boolean\" must be \"on\" or \"off\"!"; exit 1;;
  125. esac
  126. done
  127. setopts $opts1
  128. setopts $opts2
  129. optdbserver="-h$dbserver"
  130. if [ "$dbserver" = "localhost" ]; then
  131. optdbserver="" # Do not force TCP/IP access when connecting locally
  132. fi
  133. if [ -n "$verbose" ]; then
  134. echo "--> Figure out database users and passwords"
  135. fi
  136. if [ -z "$dbpass" ]; then
  137. if [ -f $home/.my.cnf ]; then
  138. dbpass=$(grep password $home/.my.cnf | awk -F= '{print $2}' | head -n 1 | sed 's/^ //g')
  139. fi
  140. if [ -z "$dbpass" ]; then
  141. if [ -n "$query" ]; then
  142. echo -n "Enter database password for MySQL user $dbuser: "
  143. read -s dbpass
  144. echo
  145. else
  146. echo "ERROR: Database password for MySQL $dbuser not found!"
  147. exit 1
  148. fi
  149. fi
  150. fi
  151. if [ -e /usr/share/wwwconfig-common/mysql-localadmpass.get -a "$dbserver" = "localhost" ] ; then
  152. status=""
  153. . /usr/share/wwwconfig-common/mysql-localadmpass.get
  154. if [ "$status" = "error" ] ; then
  155. if [ -n "$info" ]; then
  156. echo "--> $error"
  157. fi
  158. fi
  159. fi
  160. if [ -z "$dbadmin" ]; then
  161. if [ -n "$query" ]; then
  162. echo -n "Enter database administrator user (usually root): "
  163. read dbadmin
  164. echo
  165. else
  166. echo "ERROR: Database administrator user not resolved!"
  167. exit 1
  168. fi
  169. fi
  170. if [ -z "$dbadmpass" ]; then
  171. if [ -n "$query" ]; then
  172. echo -n "Enter database password for administrator $sbadmin: "
  173. read -s dbadmpass
  174. echo
  175. else
  176. echo "ERROR: Database password for administrator $dbadmin not found!"
  177. exit 1
  178. fi
  179. fi
  180. alldb=`mysql -u$dbadmin $optdbserver mysql -e "show databases;" | grep -v '^Database$'`
  181. ##############################################
  182. # The rest of the script is dbname-specific... #
  183. ##############################################
  184. for dbname do
  185. if [ -n "$info" ]; then
  186. echo "Creating $dbname..."
  187. fi
  188. if [ -n "$verbose" ]; then
  189. echo "--> Check for existing installation"
  190. fi
  191. error=""
  192. if echo $alldb | egrep -q "\<$dbname\>"; then
  193. if [ -n "$verbose" ]; then
  194. error="Database $dbname already exists."
  195. else
  196. error="Database already exists."
  197. fi
  198. fi
  199. if [ -n "$error" ]; then
  200. if [ -n "$query" ]; then
  201. echo "WARNING: $error"
  202. echo -n "Overwrite existing installation (y/N)?: "
  203. read ack
  204. echo
  205. case $ack in
  206. y|Y) force="1";;
  207. *) echo "Installation aborted!"; exit 1;;
  208. esac
  209. fi
  210. if [ -n "$force" ]; then
  211. # if [ -e /usr/share/wwwconfig-common/mysql-dropdb.sh ] ; then
  212. # status=""
  213. # . /usr/share/wwwconfig-common/mysql-dropdb.sh
  214. # if [ "$status" = "error" ] ; then
  215. # echo "$error"
  216. # exit 1
  217. # fi
  218. # else
  219. mysql -u$dbadmin $optdbserver -f -e "DROP DATABASE $dbname;"
  220. # fi
  221. else
  222. echo "ERROR: $error!"
  223. exit 1
  224. fi
  225. fi
  226. if [ -n "$verbose" -a "$dbhost" != "localhost" ]; then
  227. echo "--> Create database $dbname on $dbserver"
  228. elif [ -n "$verbose" ]; then
  229. echo "--> Create database $dbname"
  230. fi
  231. if [ -e /usr/share/wwwconfig-common/mysql-createdb.sh ] ; then
  232. status=""
  233. . /usr/share/wwwconfig-common/mysql-createdb.sh
  234. if [ "$status" = "error" ] ; then
  235. echo "$error"
  236. exit 1
  237. fi
  238. else
  239. # TODO: Purge existing database as the wwwconfig-common script does
  240. mysql -u$dbadmin $optdbserver -e "CREATE DATABASE $dbname;"
  241. fi
  242. if [ -n "$verbose" ]; then
  243. echo "--> Create/update database user $dbuser"
  244. fi
  245. if [ -e /usr/share/wwwconfig-common/mysql-createuser.sh ] ; then
  246. status=""
  247. . /usr/share/wwwconfig-common/mysql-createuser.sh
  248. if [ "$status" = "error" ] ; then
  249. echo "$error"
  250. # exit 1
  251. fi
  252. for h in `echo "localhost $dballow" | sort -u`; do
  253. mysql -u$dbadmin $optdbserver mysql -e "REVOKE CREATE,DROP ON $dbname.* FROM '$dbuser'@'$h';"
  254. done
  255. else
  256. for h in `echo "localhost $dballow" | sort -u`; do
  257. if [ "$ez" = "on" ]; then # eZ Publish 2.2.x requires CREATE,DROP,INDEX for the search routines
  258. mysql -u$dbadmin $optdbserver mysql -e "GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX ON $dbname.* TO '$dbuser'@'$h' IDENTIFIED BY '$dbpass';"
  259. else
  260. mysql -u$dbadmin $optdbserver mysql -e "GRANT SELECT,INSERT,UPDATE,DELETE ON $dbname.* TO '$dbuser'@'$h' IDENTIFIED BY '$dbpass';"
  261. fi
  262. done
  263. fi
  264. for h in `echo "localhost $dballow" | sort -u`; do
  265. mysql -u$dbadmin $optdbserver mysql -e "GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER ON $dbname.* TO '$dbuser-admin'@'$h' IDENTIFIED BY '$dbpass';"
  266. done
  267. done