How to pass login parameters to mysql - mysql

I have a shell script which calls the mysql command line client, it looks like this:
$ cat ms
mysql --host=titanic --user=fred --password="foobar"
It works OK:
$ ./ms
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 810
...
Now, I'd like to keep the script in a git repository, but without the user and password details. So, I thought I would have a file SECRET with: --host=titanic --user=fred --password="foobar" which I wouldn't add to the git repository, and change the ms script like this:
mysql $(cat SECRET)
Unfortunately, it doesn't work. I get this error when I run it:
$ ./ms
ERROR 1045 (28000): Access denied for user 'fred'#'example.com' (using password: YES)
I cannot understand it - when the $(cat SECRET) is evaluated/expanded it looks exactly the same as the straightforward invocation of mysql. Still, it doesn't work. The same happens if I try to do it directly in interactive shell:
$ mysql --host=titanic --user=fred --password="foobar"
works OK, but the below does not:
$ cat SECRET
--host=titanic --user=fred --password="foobar"
$ mysql $(cat SECRET)
ERROR 1045 (28000): Access denied for user 'fred'#'example.com' (using password: YES)
$ echo mysql $(cat SECRET)
mysql --host=titanic --user=fred --password="foobar"
Anybody can shed some light on what's going on here and how to fix it? Many thanks in advance.

Change the file to:
--host=titanic --user=fred --password=foobar
Quotes aren't processed on the result of command or variable substitution, only word splitting and filename expansion are done.
But a better solution would probably be to use an option file, e.g. mysecret.cnf:
[mysql]
user=fred
password=foobar
host=titanic
Then run mysql as:
mysql --defaults-file=mysecret.cnf

Related

Issue with mysqldump returning Permission denied

I'm trying to setup a backup system for MySQL from PHP by using mysqldump command but I'm having a Permission denied error.
I'm on MacOS Catalina 10.15.6, using system PHP and Homebrew mysql#57.
After many attempts, I could reproduce this issue in Terminal. If I run the command as me, it works fine and the backup file is correctly created, but when I run it as _www I get the error.
This works:
% mysqldump --defaults-extra-file="crd" --extended-insert mydb > backup.sql.gz
And this does not work:
% sudo -u _www mysqldump --defaults-extra-file="crd" --extended-insert mydb > backup.sql.gz
sudo: unable to execute /usr/local/opt/mysql#5.7/bin/mysqldump: Permission denied
I checked and mysqldump can be executed by user, group and other:
% ls -la /usr/local/opt/mysql#5.7/bin | grep mysqldump
-r-xr-xr-x 1 jbogdani staff 3853364 Aug 17 21:22 mysqldump
Other attempts to provide username and password in the command also fail.
mysqldump will need a password for the mysql user root. If you don't supply that password it won't work, sudo or no sudo.
instead of using sudo -u _www just execute it with current mysql user account.
if you need further reading
You need to use a full path on the output.
You do not have permissions to write to /usr/local/opt/mysql#5.7/bin/backup.sql.gz. Specify full path of the target backup archive to another directory
I think you'll find the _www user is restricted in some way. It might not have a valid shell, it might be locked, or there might be apparmour/selinux restrictions preventing it from running.
Check the output of dmesg and /var/log/secure for useful logs, otherwise check and change the shell and status of the user using usermod to find and isolate the issue.
Make sure you consider the security ramifications before doing anything in production though.

MySql 1045 When using --defaults-file

I am having a strange issue. I have MySql running on RHEL. I can logon to MySql with
mysql -uroot -pmyPassword
and it works fine. Also, when I try to execute a query from a .sh script as below it works fine
mysql --user=root --password=myPassword --host=localhost --port=3306 -se "SELECT 1 as testConnect" 2>&1>> $OUTPUT
But when I store the userid and password in a msql.conf file as below
[clientroot]
user=root
password=myPassword
and then change the line in the script as below
mysql --defaults-file=msql.conf --defaults-group-suffix=root -hlocalhost -P3306 -se "SELECT 1 as testConnect" 2>&1>> $OUTPUT
When I run it, I get the error:
ERROR 1045 (28000): Access denied for user 'root'#'localhost' (using password: YES)
I am running the script with sudo and the config file is at the same directory as the script
I have permission 0600 on the config file.
How do I make this work?
It worked for me, but it was a bit of a 'tricky' fix that isn't shown in the actual documentation. All you have to do is change
[clientroot]
user=root
password=myPassword
to
[clientroot]
user="root"
password="myPassword"
Basically just add the double quotes.
Then running your command:
mysql --defaults-file=msql.conf --defaults-group-suffix=root -hlocalhost -P3306 -se
"SELECT 1 as testConnect" 2>&1>> $OUTPUT
Should work (it worked for me).
I discovered this by looking through an obscure part of the documentation on something almost unrelated, so I don't blame everyone for missing it.
Options files are not meant for auto-login credentials.
Try this:
export MYSQL_PWD=myPassword
And try to connect using the root user.
Note that this approach is "insecure", but so is the basic idea of what you're trying to do.
When your goal is to not use the password in scripts or on command line, may I suggest a different approach?
You can create a file with the login credentials encrypted and use that for logging in.
Here's an example:
Create the file with
mysql_config_editor --set-login-path=local --host=localhost --user=localuser --password
This creates the file ~/.mylogin.cnf. You can now login with
mysql --login-path=local
local is a name you can specify, btw.
Here's another plus: You can also create different files for different projects. For example, I sometimes create files for certain scripts. I put the .mylogin.cnf in the same folder as the script and use it like this in the script:
RESULT=($(MYSQL_TEST_LOGIN_FILE=./.mylogin.cnf mysql --login-path=$HOST -B --skip-column-names -e "SELECT whatever FROM whatever"))
Read more about mysql_config_editor here.

mysqldump access denied when being used in bash script

I am trying to create a bash script that uses mysqldump to create a backup of the database that is specified as parameter. However mysqldump fails with an access denied error. Using the same command directly (copying it to the shell an executing it) works without any problem.
#!/bin/bash
# ... use parameters to get db name and password
# build the mysqldump command and execute it...
command="mysqldump -alv -h127.0.0.3 --default-character-set=utf8 -u ${database} -p'${pw}' --extended-insert ${database} | gzip > ${path}"
echo "$command"
echo ""
$command
This gives me the following output:
$ ./dbbak DBUSER DBNAME PASSWORD
mysqldump -alv -h127.0.0.3 --default-character-set=utf8 -u DBUSER -p'PASSWORD' --extended-insert DBNAME | gzip > /path/to/backup/backup.sql.gz
Warning: Using a password on the command line interface can be insecure.
-- Connecting to 127.0.0.3...
mysqldump: Got error: 1045: Access denied for user 'DBUSER'#'localhost' (using password: YES) when trying to connect
As said before: When I copy the echoed mysqldump command and execute it directly, the backup works just fine.
What is the problem here? Since the command is executed correctly when being used manually all parameters (password, username, etc.) seem to be correct. Additionally the bash script is executed with the same user account as the manual command.
So why does the manual execution work while the bash script fails?
EDIT:
As Jens pointed out in his comment, removing the quotes from the password will solve the problem. ...-p${pw}... will work, BUT this will also lead to a new problem, if the password contains special characters like $ < > ...
I assume that the problem with the quotes is how bash parses the string. Meanwhile I found some docs that say, that it is a bad habit to store commands in variables and execute them. Instead one should execute commands directly. However the following does not work as well:
result=$(mysqldump -alv -h127.0.0.3 --default-character-set=utf8 -u ${database} -p'${pw}' --extended-insert ${database} | gzip > ${path})
When executing this with bash -x dbbak the output shows the problem:
...
++ mysqldump -alv -h127.0.0.3 --default-character-set=utf8 -u DBUSER '-p'\''DBPASS'\''' --extended-insert DBNAME
While I do understand why the quotes around DBPASS are added ('DBPASS' --> \''DBPASS'\'), I do not understand why there are also quotes around-p`.
How do I get rid of these quotes when executing the command?
You can either:
store the password in an environment variable MYSQL_PWD
store the password in a plain-text file .my.cnf which you need to put into
the home directory of the user that executes the script
use the mysql_config_editor utility to store the password in an encrypted
file
The first one is the easiest to use/implement but obviously the least secure.
I recommend to take a look at the documentation where all the possibilities are described. ;)
Configure it by .cnf file and provide it in --defaults-file
mysqldump --defaults-file=~/my_mysql.cnf db table > table.sql
In ~/my_msyql.cnf
[mysqldump]
user=user_name
password=my_password
host=my_host
This is also safe if you version this. You can save my_mysql.cnf differently per environment.
To remove the single quotes around the password solved for me.

How to change mysql root password

I'm trying to change the mysql root password on my machine. Another engineer created the password and left the company so I don't have access. I'd rather not have to reinstall the whole shebang.
I'm trying to follow the instructions here: http://dev.mysql.com/doc/refman/5.0/en/resetting-permissions.html
But when I execute the command on step 2 of the "Resetting the Root Password: Unix Systems" instructions I get the following error:
FitValet-MacBook-Pro:~ fitvalet$ kill `cat /usr/local/mysql/data/FitValet-MacBook-Pro.local.pid`
cat: /usr/local/mysql/data/FitValet-MacBook-Pro.local.pid: Permission denied
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
And I can't figure it out for the life of me...permission is denied? How can I get past this? Thanks!
Try adding sudo in front of the kill and cat commands. Like this:
sudo kill `sudo cat /usr/local/mysql/data/FitValet-MacBook-Pro.local.pid`
It will then ask you for the root password for your Mac (not mysql). Enter it, and the command should execute without giving you a permission denied error.

bash check mysql connect

I'm writing a bash script to do some operations against a database on my debian squeeze Server.
I have noticed that if I enter a wrong password for root, the prompt will be closed and I won't be asked to try again... that's not very convenient!
So I was trying to create a loop that attempts to connect to MYSQL and save the password for later if successful.
I tried this, but it doesn't work.
Instead, I receive this error:
ERROR 1045 (28000): Access denied for user 'root'#'localhost' (using password: YES)
read -s -p "Enter MYSQL root password: " mysqlRootPassword
while [[ -n `mysql -u root -p$mysqlRootPassword` ]]; do
read -p "Can't connect, please retry: " mysqlRootPassword
done
I am not very experienced in bash scripting, any help would be awesome!
I don't think you need the [[ -n backtic ... ]]; test nested like that. Try:
read -s -p "Enter MYSQL root password: " mysqlRootPassword
while ! mysql -u root -p$mysqlRootPassword -e ";" ; do
read -s -p "Can't connect, please retry: " mysqlRootPassword
done
while evaluates any command group upto a closing ; do and checks the return code of last command executed to determine if the loop should be executed. Because you are looking for a failure, you have to precede the test with a logical NOT (!) OR you can use the syntactic equivalent, i.e.
until mysql -u root -p$mysqlRootPassword -e ";" ; do
read -s -p "Can't connect, please retry: " mysqlRootPassword
done
which you can think of as 'until mysql works correctly, keep trying to get the right password'.
Unfortunately, I don't have access to a mysql installation, so this is untested.
I hope this helps.