5

I want to execute a shell script from php page which will execute a MySQL command.

To do this I followed the way shown here: https://stackoverflow.com/a/8055745/2117868

Here is my sqlscript.sh

#!/bin/sh
sudo wget -t 50 -O /tmp/update.sql http://example.com/update.sql
if [ $? -eq 0 ]; then
    mysql -h "localhost" -u "root" "-pXXXXXXXX" "database-name" < "/tmp/update.sql"
    if [ $? -eq 0 ]; then
        sudo rm /tmp/update.sql
        echo "200"
    else
        echo "502"
    fi
else
    echo "404"
fi

And my php page is runscript.php

<?php
    shell_exec("sudo /path/to/script/sqlscript.sh");
?>

Now, when I'm calling the sqlscript.sh from the server console or php page runscript.php it works perfectly and returns 200 as expected.

But when I take MYSQL user and password in ~/.my.cnf so I don't have to put it on the command-line at all:

[client]
user = root
password = XXXXXXXX

And added credentials in sudoer to execute this script without password.

User_Alias WWW_USER = www-data
Cmnd_Alias WWW_COMMANDS_SQL = /path/to/script/sqlscript.sh
WWW_USER ALL = (ALL) NOPASSWD: WWW_COMMANDS_SQL

Here is my sqlscript.sh

#!/bin/sh
sudo wget -t 50 -O /tmp/update.sql http://example.com/update.sql
if [ $? -eq 0 ]; then
    mysql -h "localhost" "database-name" < "/tmp/update.sql"
    if [ $? -eq 0 ]; then
        sudo rm /tmp/update.sql
        echo "200"
    else
        echo "502"
    fi
else
    echo "404"
fi

Now, when I'm calling the sqlscript.sh from the server console it works perfectly and returns 200 as expected. But if I call it from the php page

http://example.com/runscript.php

it returns 502 as it couldn't execute the SQL command.

Update:

Here is the Apache error.log

--2014-12-05 10:51:55--  http://example.com/update.sql
Resolving example.com (example.com)... 162.144.71.XXX
Connecting to example.com (example.com)|162.144.71.XXX|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 146 [text/x-sql]
Saving to: `/tmp/update.sql'

     0K                                                       100% 10.9M=0s

2014-12-05 10:51:55 (10.9 MB/s) - `/tmp/update.sql' saved [146/146]

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

So, please help me to solve the issue.

Community
  • 1
  • 1
kuttumiah
  • 525
  • 1
  • 11
  • 19
  • 2
    This is probably a permission issue. you're running php with web server user, and in console with a different user. to analyze the problem you should check apache logs, and see (maybe also edit your question with it) the exact error message. – Volkan Ulukut Dec 05 '14 at 09:10
  • still, check the error.log, believe me it helps. – Volkan Ulukut Dec 05 '14 at 09:40
  • This is clearly a permission issue. The user who executes the PHP script and therefore your bash script (and mysql), is not allowed to access my.cnf file. – PauloASilva Dec 05 '14 at 09:50
  • Hi, @VolkanUlukut thanks for you support. I updated the question adding the Apache error log. But why this script is causing this permission error? – kuttumiah Dec 05 '14 at 10:01
  • You don’t need root privileges for the commands you are executing. – Gumbo Dec 05 '14 at 10:32
  • Do you mean I should change the php page to `` I changed the php page as explained and got `404` – kuttumiah Dec 05 '14 at 10:35
  • @kuttumiah show here your `.my.cnf` file permissions (`ls -lahZ ~/.my.cnf`). As you're running PHP with Apache, who is calling your bash script is the `www-data` (or `apache`) user: is it allowed to read `.my.cnf` file? – PauloASilva Dec 05 '14 at 23:18
  • Here is the permission scenario of `.my.cnf` `-rw-r--r-- 1 root root ? 55 Dec 5 10:28 /home/user/.my.cnf` – kuttumiah Dec 06 '14 at 00:49

2 Answers2

1

Solved by adding the --defaults-extra-file option.
mysql --defaults-extra-file=~/.my.cnf ...

Or with absolute path (might be required via apache, depends on server config):
mysql --defaults-extra-file=/absolute/path/to/.my.cnf ...

oori
  • 5,533
  • 1
  • 30
  • 37
0

Have you tried this?

In your shell script, instead of

mysql -h "localhost" "database-name" < "/tmp/update.sql"

use

mysql -h "localhost"-u root -ppassword "database-name" < "/tmp/update.sql"

Basically, try to pass MySQL username and password inside your shell script. Of course you can put them into variables/configs/whatever to obsecure it

MySQL 28000 error showed that your script was able to attempt to login as a root but because there was no parameter password, it failed

Don Djoe
  • 705
  • 1
  • 10
  • 21
  • Thanks for your answer. Yes, I've tried it. And it's at the beginning of my question that this way is working. But I don't want to write password directly in the script. That's what I wanted. – kuttumiah Feb 26 '15 at 21:15
  • Apologies for not reading the question properly. For some reason I mis-read the original script. Have you tried to either put `.my.cnf` into www-data home folder instead of your user's home folder? Alternatively set the apache user into your user (which arguably not preferred by some people) – Don Djoe Feb 26 '15 at 22:22