1#!/bin/sh 2# Copyright (c) 2000, 2013, Oracle and/or its affiliates. 3# Copyright (c) 2009, 2013, Monty Program Ab 4# 5# This program is free software; you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation; version 2 of the License. 8# 9# This program is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with this program; if not, write to the Free Software 16# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA 17 18# This scripts creates the MariaDB Server system tables 19# 20# All unrecognized arguments to this script are passed to mysqld. 21 22basedir="" 23builddir="" 24ldata="@localstatedir@" 25langdir="" 26srcdir="" 27log_error="" 28 29args="" 30defaults="" 31defaults_group_suffix="" 32mysqld_opt="" 33user="" 34group="" 35silent_startup="--silent-startup" 36 37force=0 38in_rpm=0 39ip_only=0 40cross_bootstrap=0 41auth_root_authentication_method=socket 42auth_root_socket_user="" 43skip_test_db=0 44 45dirname0=`dirname $0 2>/dev/null` 46dirname0=`dirname $dirname0 2>/dev/null` 47 48usage() 49{ 50 cat <<EOF 51Usage: $0 [OPTIONS] 52 --auth-root-authentication-method=normal|socket 53 Chooses the authentication method for the created 54 initial root user. The historical behavior is 'normal' 55 to creates a root user that can login without password, 56 which can be insecure. The default behavior 'socket' 57 sets an invalid root password but allows the system root 58 user to login as MariaDB root without a password. 59 --auth-root-socket-user=user 60 Used with --auth-root-authentication-method=socket. It 61 specifies the name of the second MariaDB root account, 62 as well as of the system account allowed to access it. 63 Defaults to the value of --user. 64 --basedir=path The path to the MariaDB installation directory. 65 --builddir=path If using --srcdir with out-of-directory builds, you 66 will need to set this to the location of the build 67 directory where built files reside. 68 --cross-bootstrap For internal use. Used when building the MariaDB system 69 tables on a different host than the target. 70 --datadir=path The path to the MariaDB data directory. 71 --no-defaults Don't read default options from any option file. 72 --defaults-extra-file=name 73 Read this file after the global files are read. 74 --defaults-file=name Only read default options from the given file name. 75 --defaults-group-suffix=name 76 In addition to the given groups, read also groups with 77 this suffix 78 --force Causes mysql_install_db to run even if DNS does not 79 work. In that case, grant table entries that 80 normally use hostnames will use IP addresses. 81 --help Display this help and exit. 82 --ldata=path The path to the MariaDB data directory. Same as 83 --datadir. 84 --rpm For internal use. This option is used by RPM files 85 during the MariaDB installation process. 86 --skip-name-resolve Use IP addresses rather than hostnames when creating 87 grant table entries. This option can be useful if 88 your DNS does not work. 89 --skip-test-db Don't install a test database. 90 --srcdir=path The path to the MariaDB source directory. This option 91 uses the compiled binaries and support files within the 92 source tree, useful for if you don't want to install 93 MariaDB yet and just want to create the system tables. 94 --user=user_name The login username to use for running mysqld. Files 95 and directories created by mysqld will be owned by this 96 user. You must be root to use this option. By default 97 mysqld runs using your current login name and files and 98 directories that it creates will be owned by you. 99 --group=group_name The login group to use for running mysqld. Files and 100 directories created by mysqld will be owned by this 101 group. You must be root to use this option. By default 102 mysqld runs using your current group and files and 103 directories that it creates will be owned by you. 104 105All other options are passed to the mysqld program 106 107EOF 108 exit 1 109} 110 111s_echo() 112{ 113 if test "$in_rpm" -eq 0 -a "$cross_bootstrap" -eq 0 114 then 115 echo "$1" 116 fi 117} 118 119link_to_help() 120{ 121 echo 122 echo "The latest information about mysql_install_db is available at" 123 echo "https://mariadb.com/kb/en/installing-system-tables-mysql_install_db" 124} 125 126parse_arg() 127{ 128 echo "$1" | sed -e 's/^[^=]*=//' 129} 130 131parse_arguments() 132{ 133 # We only need to pass arguments through to the server if we don't 134 # handle them here. So, we collect unrecognized options (passed on 135 # the command line) into the args variable. 136 pick_args= 137 if test "$1" = PICK-ARGS-FROM-ARGV 138 then 139 pick_args=1 140 shift 141 fi 142 143 for arg 144 do 145 case "$arg" in 146 --force) force=1 ;; 147 --basedir=*) basedir=`parse_arg "$arg"` ;; 148 --builddir=*) builddir=`parse_arg "$arg"` ;; 149 --srcdir=*) srcdir=`parse_arg "$arg"` ;; 150 --ldata=*|--datadir=*|--data=*) ldata=`parse_arg "$arg"` ;; 151 --log-error=*) 152 log_error=`parse_arg "$arg"` ;; 153 # Note that the user will be passed to mysqld so that it runs 154 # as 'user' (crucial e.g. if log-bin=/some_other_path/ 155 # where a chown of datadir won't help) 156 --user=*) user=`parse_arg "$arg"` ;; 157 --group=*) group=`parse_arg "$arg"` ;; 158 --skip-name-resolve) ip_only=1 ;; 159 --verbose) verbose=1 ; silent_startup="" ;; 160 --rpm) in_rpm=1 ;; 161 --help) usage ;; 162 --no-defaults|--defaults-file=*|--defaults-extra-file=*) 163 defaults="$arg" ;; 164 --defaults-group-suffix=*) 165 defaults_group_suffix="$arg" ;; 166 167 --cross-bootstrap|--windows) 168 # Used when building the MariaDB system tables on a different host than 169 # the target. The platform-independent files that are created in 170 # --datadir on the host can be copied to the target system. 171 # 172 # The most common use for this feature is in the Windows installer 173 # which will take the files from datadir and include them as part of 174 # the install package. See top-level 'dist-hook' make target. 175 # 176 # --windows is a deprecated alias 177 cross_bootstrap=1 ;; 178 --auth-root-authentication-method=normal) 179 auth_root_authentication_method=normal ;; 180 --auth-root-authentication-method=socket) 181 auth_root_authentication_method=socket ;; 182 --auth-root-authentication-method=*) 183 usage ;; 184 --auth-root-socket-user=*) 185 auth_root_socket_user="$(parse_arg "$arg")" ;; 186 --skip-test-db) skip_test_db=1 ;; 187 188 *) 189 if test -n "$pick_args" 190 then 191 # This sed command makes sure that any special chars are quoted, 192 # so the arg gets passed exactly to the server. 193 # XXX: This is broken; true fix requires using eval and proper 194 # quoting of every single arg ($basedir, $ldata, etc.) 195 #args="$args "`echo "$arg" | sed -e 's,\([^a-zA-Z0-9_.-]\),\\\\\1,g'` 196 args="$args $arg" 197 fi 198 ;; 199 esac 200 done 201} 202 203# Try to find a specific file within --basedir which can either be a binary 204# release or installed source directory and return the path. 205find_in_dirs() 206{ 207 case "$1" in 208 --dir) 209 return_dir=1; shift 210 ;; 211 esac 212 213 file=$1; shift 214 215 for dir in "$@" 216 do 217 if test -f "$dir/$file" 218 then 219 if test -n "$return_dir" 220 then 221 echo "$dir" 222 else 223 echo "$dir/$file" 224 fi 225 break 226 fi 227 done 228} 229 230cannot_find_file() 231{ 232 echo 233 echo "FATAL ERROR: Could not find $1" 234 235 shift 236 if test $# -ne 0 237 then 238 echo 239 echo "The following directories were searched:" 240 echo 241 for dir in "$@" 242 do 243 echo " $dir" 244 done 245 fi 246 247 echo 248 echo "If you compiled from source, you need to either run 'make install' to" 249 echo "copy the software into the correct location ready for operation." 250 echo "If you don't want to do a full install, you can use the --srcdir" 251 echo "option to only install the mysql database and privilege tables." 252 echo 253 echo "If you are using a binary release, you must either be at the top" 254 echo "level of the extracted archive, or pass the --basedir option" 255 echo "pointing to that location." 256 link_to_help 257} 258 259# Ok, let's go. We first need to parse arguments which are required by 260# my_print_defaults so that we can execute it first, then later re-parse 261# the command line to add any extra bits that we need. 262parse_arguments "$@" 263 264# 265# We can now find my_print_defaults. This script supports: 266# 267# --srcdir=path pointing to compiled source tree 268# --basedir=path pointing to installed binary location 269# 270# or default to compiled-in locations. 271# 272if test -n "$srcdir" && test -n "$basedir" 273then 274 echo "ERROR: Specify either --basedir or --srcdir, not both." 275 link_to_help 276 exit 1 277fi 278if test -n "$srcdir" 279then 280 # In an out-of-source build, builddir is not srcdir. Try to guess where 281 # builddir is by looking for my_print_defaults. 282 if test -z "$builddir" 283 then 284 if test -x "$dirname0/extra/my_print_defaults" 285 then 286 builddir="$dirname0" 287 else 288 builddir="$srcdir" 289 fi 290 fi 291 print_defaults="$builddir/extra/my_print_defaults" 292elif test -n "$basedir" 293then 294 print_defaults=`find_in_dirs my_print_defaults $basedir/bin $basedir/extra` 295 if test -z "$print_defaults" 296 then 297 cannot_find_file my_print_defaults $basedir/bin $basedir/extra 298 exit 1 299 fi 300elif test -n "$dirname0" -a -x "$dirname0/@bindir@/my_print_defaults" 301then 302 print_defaults="$dirname0/@bindir@/my_print_defaults" 303elif test -x "./extra/my_print_defaults" 304then 305 srcdir="." 306 builddir="." 307 print_defaults="./extra/my_print_defaults" 308else 309 print_defaults="@bindir@/my_print_defaults" 310fi 311 312if test ! -x "$print_defaults" 313then 314 cannot_find_file "$print_defaults" 315 exit 1 316fi 317 318# Now we can get arguments from the groups [mysqld] and [mysql_install_db] 319# in the my.cfg file, then re-run to merge with command line arguments. 320parse_arguments `"$print_defaults" $defaults $defaults_group_suffix --mysqld mysql_install_db mariadb-install-db` 321 322parse_arguments PICK-ARGS-FROM-ARGV "$@" 323 324rel_mysqld="$dirname0/@INSTALL_SBINDIR@/mysqld" 325 326# Configure paths to support files 327if test -n "$srcdir" 328then 329 basedir="$builddir" 330 bindir="$basedir/client" 331 resolveip="$basedir/extra/resolveip" 332 mysqld="$basedir/sql/mysqld" 333 langdir="$basedir/sql/share/english" 334 srcpkgdatadir="$srcdir/scripts" 335 buildpkgdatadir="$builddir/scripts" 336 plugindir="$builddir/plugin/auth_socket" 337 pamtooldir="$builddir/plugin/auth_pam" 338elif test -n "$basedir" 339then 340 bindir="$basedir/bin" # only used in the help text 341 resolveip=`find_in_dirs resolveip @resolveip_locations@` 342 if test -z "$resolveip" 343 then 344 cannot_find_file resolveip @resolveip_locations@ 345 exit 1 346 fi 347 mysqld=`find_in_dirs mysqld @mysqld_locations@` 348 if test -z "$mysqld" 349 then 350 cannot_find_file mysqld @mysqld_locations@ 351 exit 1 352 fi 353 langdir=`find_in_dirs --dir errmsg.sys @errmsg_locations@` 354 if test -z "$langdir" 355 then 356 cannot_find_file errmsg.sys @errmsg_locations@ 357 exit 1 358 fi 359 srcpkgdatadir=`find_in_dirs --dir fill_help_tables.sql @pkgdata_locations@` 360 buildpkgdatadir=$srcpkgdatadir 361 if test -z "$srcpkgdatadir" 362 then 363 cannot_find_file fill_help_tables.sql @pkgdata_locations@ 364 exit 1 365 fi 366 plugindir=`find_in_dirs --dir auth_pam.so $basedir/lib*/plugin $basedir/lib*/mysql/plugin $basedir/lib/*/mariadb19/plugin` 367 pamtooldir=$plugindir 368# relative from where the script was run for a relocatable install 369elif test -n "$dirname0" -a -x "$rel_mysqld" -a ! "$rel_mysqld" -ef "@sbindir@/mysqld" 370then 371 basedir="$dirname0" 372 bindir="$basedir/@INSTALL_BINDIR@" 373 resolveip="$bindir/resolveip" 374 mysqld="$rel_mysqld" 375 srcpkgdatadir="$basedir/@INSTALL_MYSQLSHAREDIR@" 376 buildpkgdatadir="$basedir/@INSTALL_MYSQLSHAREDIR@" 377 plugindir="$basedir/@INSTALL_PLUGINDIR@" 378 pamtooldir=$plugindir 379else 380 basedir="@prefix@" 381 bindir="@bindir@" 382 resolveip="$bindir/resolveip" 383 mysqld="@sbindir@/mysqld" 384 srcpkgdatadir="@pkgdatadir@" 385 buildpkgdatadir="@pkgdatadir@" 386 plugindir="@pkgplugindir@" 387 pamtooldir="@pkgplugindir@" 388fi 389 390# Set up paths to SQL scripts required for bootstrap 391fill_help_tables="$srcpkgdatadir/fill_help_tables.sql" 392create_system_tables="$srcpkgdatadir/mysql_system_tables.sql" 393create_system_tables2="$srcpkgdatadir/mysql_performance_tables.sql" 394fill_system_tables="$srcpkgdatadir/mysql_system_tables_data.sql" 395maria_add_gis_sp="$buildpkgdatadir/maria_add_gis_sp_bootstrap.sql" 396mysql_test_db="$srcpkgdatadir/mysql_test_db.sql" 397 398for f in "$fill_help_tables" "$create_system_tables" "$create_system_tables2" "$fill_system_tables" "$maria_add_gis_sp" "$mysql_test_db" 399do 400 if test ! -f "$f" 401 then 402 cannot_find_file "$f" 403 exit 1 404 fi 405done 406 407if test ! -x "$mysqld" 408then 409 cannot_find_file "$mysqld" 410 exit 1 411fi 412 413if test -n "$langdir" 414then 415 if test ! -f "$langdir/errmsg.sys" 416 then 417 cannot_find_file "$langdir/errmsg.sys" 418 exit 1 419 fi 420 mysqld_opt="--lc-messages-dir=$langdir/.." 421else 422 mysqld_opt="--lc-messages=en_US" 423fi 424 425 426# Try to determine the hostname 427hostname=`@HOSTNAME@` 428 429# Check if hostname is valid 430if test "$cross_bootstrap" -eq 0 -a "$in_rpm" -eq 0 -a "$force" -eq 0 431then 432 resolved=`"$resolveip" $hostname 2>&1` 433 if test $? -ne 0 434 then 435 resolved=`"$resolveip" localhost 2>&1` 436 if test $? -ne 0 437 then 438 echo "Neither host '$hostname' nor 'localhost' could be looked up with" 439 echo "'$resolveip'" 440 echo "Please configure the 'hostname' command to return a correct" 441 echo "hostname." 442 echo "If you want to solve this at a later stage, restart this script" 443 echo "with the --force option" 444 link_to_help 445 exit 1 446 fi 447 echo "WARNING: The host '$hostname' could not be looked up with $resolveip." 448 echo "This probably means that your libc libraries are not 100 % compatible" 449 echo "with this binary MariaDB version. The MariaDB daemon, mysqld, should work" 450 echo "normally with the exception that host name resolving will not work." 451 echo "This means that you should use IP addresses instead of hostnames" 452 echo "when specifying MariaDB privileges !" 453 fi 454fi 455 456if test "$ip_only" -eq 1 457then 458 hostname=`echo "$resolved" | awk '/ /{print $6}'` 459fi 460 461# Create database directories 462for dir in "$ldata" 463do 464 if test ! -d "$dir" 465 then 466 if ! `mkdir -p "$dir"` 467 then 468 echo "Fatal error Can't create database directory '$dir'" 469 link_to_help 470 exit 1 471 fi 472 chmod 700 "$dir" 473 fi 474 if test -n "$user" 475 then 476 if test -z "$group" 477 then 478 chown $user $dir 479 else 480 chown $user:$group $dir 481 fi 482 if test $? -ne 0 483 then 484 echo "Cannot change ownership of the database directories to the '$user'" 485 echo "user. Check that you have the necessary permissions and try again." 486 exit 1 487 fi 488 fi 489done 490 491if test -n "$user" 492then 493 if test -z "$srcdir" -a "$in_rpm" -eq 0 494 then 495 chown 0 "$pamtooldir/auth_pam_tool_dir/auth_pam_tool" && \ 496 chmod 04755 "$pamtooldir/auth_pam_tool_dir/auth_pam_tool" 497 if test $? -ne 0 498 then 499 echo "Couldn't set an owner to '$pamtooldir/auth_pam_tool_dir/auth_pam_tool'." 500 echo "It must be root, the PAM authentication plugin doesn't work otherwise.." 501 echo 502 fi 503 chown $user "$pamtooldir/auth_pam_tool_dir" && \ 504 chmod 0700 "$pamtooldir/auth_pam_tool_dir" 505 if test $? -ne 0 506 then 507 echo "Cannot change ownership of the '$pamtooldir/auth_pam_tool_dir' directory" 508 echo "to the '$user' user. Check that you have the necessary permissions and try again." 509 echo 510 fi 511 fi 512 args="$args --user=$user" 513fi 514 515if test -n "$group" 516then 517 args="$args --group=$group" 518fi 519 520if test -f "$ldata/mysql/user.frm" 521then 522 echo "mysql.user table already exists!" 523 echo "Run mysql_upgrade, not mysql_install_db" 524 exit 0 525fi 526 527# When doing a "cross bootstrap" install, no reference to the current 528# host should be added to the system tables. So we filter out any 529# lines which contain the current host name. 530if test $cross_bootstrap -eq 1 531then 532 filter_cmd_line="sed -e '/@current_hostname/d'" 533else 534 filter_cmd_line="cat" 535fi 536 537# Configure mysqld command line 538mysqld_bootstrap="${MYSQLD_BOOTSTRAP-$mysqld}" 539mysqld_install_cmd_line() 540{ 541 "$mysqld_bootstrap" $defaults $defaults_group_suffix "$mysqld_opt" --bootstrap $silent_startup\ 542 "--basedir=$basedir" "--datadir=$ldata" --log-warnings=0 --enforce-storage-engine="" \ 543 "--plugin-dir=${plugindir}" --loose-disable-plugin-file-key-management \ 544 $args --max_allowed_packet=8M \ 545 --net_buffer_length=16K 546} 547 548# Use $auth_root_socket_user if explicitly specified. 549# Otherwise use the owner of datadir - ${user:-$USER} 550# Use 'root' as a fallback 551auth_root_socket_user=${auth_root_socket_user:-${user:-${USER:-root}}} 552 553cat_sql() 554{ 555 echo "create database if not exists mysql;" 556 echo "use mysql;" 557 558 case "$auth_root_authentication_method" in 559 normal) 560 echo "SET @auth_root_socket=NULL;" 561 ;; 562 socket) 563 echo "SET @auth_root_socket='$auth_root_socket_user';" 564 ;; 565 esac 566 567 cat "$create_system_tables" "$create_system_tables2" "$fill_system_tables" "$fill_help_tables" "$maria_add_gis_sp" 568 if test "$skip_test_db" -eq 0 569 then 570 cat "$mysql_test_db" 571 fi 572} 573 574# Create the system and help tables by passing them to "mysqld --bootstrap" 575s_echo "Installing MariaDB/MySQL system tables in '$ldata' ..." 576if cat_sql | eval "$filter_cmd_line" | mysqld_install_cmd_line > /dev/null 577then 578 printf "@VERSION@-MariaDB" > "$ldata/mysql_upgrade_info" 579 s_echo "OK" 580else 581 log_file_place=$ldata 582 if test -n "$log_error" 583 then 584 log_file_place="$log_error or $log_file_place" 585 fi 586 echo 587 echo "Installation of system tables failed! Examine the logs in" 588 echo "$log_file_place for more information." 589 echo 590 echo "The problem could be conflicting information in an external" 591 echo "my.cnf files. You can ignore these by doing:" 592 echo 593 echo " shell> $0 --defaults-file=~/.my.cnf" 594 echo 595 echo "You can also try to start the mysqld daemon with:" 596 echo 597 echo " shell> $mysqld --skip-grant-tables --general-log &" 598 echo 599 echo "and use the command line tool $bindir/mysql" 600 echo "to connect to the mysql database and look at the grant tables:" 601 echo 602 echo " shell> $bindir/mysql -u root mysql" 603 echo " mysql> show tables;" 604 echo 605 echo "Try 'mysqld --help' if you have problems with paths. Using" 606 echo "--general-log gives you a log in $ldata that may be helpful." 607 link_to_help 608 echo "You can find the latest source at https://downloads.mariadb.org and" 609 echo "the maria-discuss email list at https://launchpad.net/~maria-discuss" 610 echo 611 echo "Please check all of the above before submitting a bug report" 612 echo "at http://mariadb.org/jira" 613 echo 614 exit 1 615fi 616 617# Don't output verbose information if running inside bootstrap or using 618# --srcdir for testing. In such cases, there's no end user looking at 619# the screen. 620if test "$cross_bootstrap" -eq 0 && test -z "$srcdir" 621then 622 s_echo 623 s_echo "To start mysqld at boot time you have to copy" 624 s_echo "support-files/mysql.server to the right place for your system" 625 626 if test "$auth_root_authentication_method" = normal 627 then 628 echo 629 echo 630 echo "PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !" 631 echo "To do so, start the server, then issue the following command:" 632 echo 633 echo "'$bindir/mysql_secure_installation'" 634 echo 635 echo "which will also give you the option of removing the test" 636 echo "databases and anonymous user created by default. This is" 637 echo "strongly recommended for production servers." 638 else 639 echo 640 echo 641 echo "Two all-privilege accounts were created." 642 echo "One is root@localhost, it has no password, but you need to" 643 echo "be system 'root' user to connect. Use, for example, sudo mysql" 644 echo "The second is $auth_root_socket_user@localhost, it has no password either, but" 645 echo "you need to be the system '$auth_root_socket_user' user to connect." 646 echo "After connecting you can set the password, if you would need to be" 647 echo "able to connect as any of these users with a password and without sudo" 648 fi 649 650 echo 651 echo "See the MariaDB Knowledgebase at http://mariadb.com/kb" 652 653 if test "$in_rpm" -eq 0 654 then 655 echo 656 echo "You can start the MariaDB daemon with:" 657 echo "cd '$basedir' ; $bindir/mysqld_safe --datadir='$ldata'" 658 echo 659 echo "You can test the MariaDB daemon with mysql-test-run.pl" 660 echo "cd '$basedir/mysql-test' ; perl mysql-test-run.pl" 661 fi 662 663 echo 664 echo "Please report any problems at http://mariadb.org/jira" 665 echo 666 echo "The latest information about MariaDB is available at http://mariadb.org/." 667 echo 668 echo "Consider joining MariaDB's strong and vibrant community:" 669 echo "https://mariadb.org/get-involved/" 670 echo 671fi 672 673exit 0 674