Not able to change privileges with MySQL database - php

I am looking to backup a MySQL database. When the following command is entered into the command line it works:
SELECT * INTO OUTFILE 'backup.txt' FROM table_name;
The file backup.txt is created. All is well.
When the above command is submitted via the MySQL query in a php file:
mysql_query("SELECT * INTO OUTFILE 'backup.txt' FROM table_name");
it does not work. The file backup.txt is not created.
Next, the privileges were looked at and the following command was entered using the command line:
GRANT FILE ON *.* TO 'root'#'localhost';
This command was accepted but the MySQL query still does not work.
The complete php file is shown below:
// connect to db host
//mysql_connect(DATABASE_HOST, DATABASE_USERNAME, DATABASE_PASSWORD)
$connection = mysql_connect("localhost", "mysql -u root", "")
or die('Could not connect: ' . mysql_error($connection));
// select db
$db = mysql_select_db("test", $connection);
// change privileges
mysql_query("GRANT FILE ON *.* TO 'root'#'localhost'");
// create query
$query = "SELECT * INTO OUTFILE 'backup.txt' FROM table_name";
//perform query
mysql_query($query);
// close mysql connection
mysql_close($connection);
Can anybody explain what is happening here and how I can get the MySQL query to work and create the outfile backup.txt.
WampServer on a Windows machine is being used.

At the moment I run mysql command line (MCL), I am an o/s user that has rights (let's call them creds for credentials) at some level to all o/s directories. Let's say the creds don't change for the duration of this code attempt, can't imagine they would. Point is, I am that user with those creds.
Without a path, full or relative just as you did, MCL writes to the data directory for the schema in the outfile call. So for instance on my system at the moment that would be
C:\Users\All Users\MySQL\MySQL Server 5.6\data\so_gibberish
where so_gibberish is the schema/db name that I would have gotten into with the use so_gibberish command or supplied as the db to use upon running mysql command line with a switch. Or it would be some linux path equivalent.
Via the MCL, I would have gotten into a db (use), as opposed to an MCL connect with no use. Meaning that I would not have issued the outfile command prior to getting into a db sandboxed, most likely (I am making the point later as it relates to Error 1046). And your command would have dumped the .txt file there (the above path a ways up) on my system. And it did in my test.
Now on to PHP.
If you are running a PHP script that connects but does not use the mysql_select_db function, then
Error 1046: No database selected
would have returned only if you were running code like the below to check for an error:
<?php
//error_reporting(E_ALL);
//ini_set('display_errors', 1);
...
... (load credential variables used below)
...
$link = mysql_connect($dbhost, $dbuser, $dbpass) or die("Unable to Connect to '$dbhost'");
//mysql_select_db($dbname) or die("Could not open the db '$dbname'");
echo "I made it here<br/>";
$test_query = "SELECT * INTO OUTFILE 'file456.txt' FROM mytable";
$result = mysql_query($test_query);
echo mysql_errno($link) . ": " . mysql_error($link) . "<br>";
mysql_close($link);
Not that people tend to check for errors. I would wager you are not in this call. They just plow foward thinking all is well.
Note though that error_reporting has no impact on this. What does impact it is whether or not you are checking for errors after mysql_query. You can rem out or clear rems and test this theory as I did. So you could be getting the 1046 Error and not know it.
Now there is the case for what o/s users and therefore the creds that the php to mysql process is masquerading as. This is driven by the original setup. Now why is this important? Because that user/those creds can very well be different than those used when at the o/s prompt you did the very first part of this using the MCL.
It is possible that the file is created thru php, but as you are not pathing with a full path to the file, just the filename, it might be sitting somewhere on your system without you knowing it, if you were to check for errors and none arrive. To test this theory, include the above error check after mysql_user without a full path, and do a directory scan to find it.
So in my test, in MCL I write out file123.txt, and in php I write out file456.txt (or whatever). And barring any error messages, I scan the file system to see where they showed up.
You would not be the first person to think OUTFILE failed, only later, maybe months later, find residue files in some directory and have a eureka moment: Oh yeah, I remember those files, what are they doing here?
It is possible that the call simply fails because of a creds issue from PHP, having to do with user or group world or some other setup chmod issue.
Via PHP, fully pathing to the outfile such as /full/path/here/out123.txt can have a good solution if the o/s user masquerading has the creds. But, in hosted environments, you can't simply say make it /tmp/out123.txt, as you will fail with permissions there. So there is no broad brush stroke "plug in this answer" that is going to solve it without a somewhat decent tinkering session by you.
So in summary for PHP, I would look into the following:
The file is being written out, you just don't know where.
The file fails but you don't know it because of no error checking after
mysql_query (such as a general mysql error, no db selected,
whatever).
Creds issue due to the o/s user masquerading from PHP into
mysql and is creds at the o/s file system level required for that
file i/o.
As for the Error 1221 error, as mentioned in comments and link to that part of it, you cannot GRANT FILE on a single db. That answer type was provided here

Related

The used command is not allowed with this MySQL version

Alright, so after a week of trying all the different ideas answers I have found with no success, I am going to ask. This is for the LOAD DATA LOCAL INFILE, for MySQL. There have been many posts regarding this, but I am still unable to get it work from the web browser, but am able to run it from the mysql command prompt on the server, with the same user and pass connecting to the same database. What I have tried so far
MySQL version 5.5
Ubuntu 12.04
PHP version 5.3
In my.cnf
local-infile=1
in mysqld,mysql,mysql-safe
loose-local-infile=1 client
Restarted MySQL Server. At this point I was then able to run the query from the command prompt, and previously had not.
I have given the directory in which the files are being pulled from 777 access.
I have confirmed the php.ini has the local file parameter enabled.
I have updated apparmor.
Actual Query:
LOAD DATA LOCAL INFILE '/var/www/ui/uploads/r_import.csv' INTO TABLE r_data FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS (first_name,last_name,apt,user_id)
Above query works from the mysql command with no special arguments in the connection to the server.
If anyone has anymore ideas on this, I would be happy to try anything....
Thanks in advance.
<?php
include 'includes/header.php';
if($_FILES['file']['type'] != "application/vnd.ms-excel"){
die("This is not a CSV file.");
}
elseif(is_uploaded_file($_FILES['file']['tmp_name'])){
$filename = $_FILES['file']['tmp_name'];
$name = $_FILES['file']['name'];
copy( $filename, 'uploads/'.$name ) or die( "Could not copy file!");
$file_to_import = '/var/www/ui/uploads/'.$name;
$query = 'LOAD DATA LOCAL INFILE \''.$file_to_import.'\' INTO TABLE r_data FIELDS TERMINATED BY \',\' ENCLOSED BY \'"\' LINES TERMINATED BY \'\n\' IGNORE 1 ROWS (first_name,last_name,apt,user_id)';
echo $query;
$result = mysqli_query($link,$query) or die(mysqli_error($link));
}
else{
die("You shouldn't be here");
}
?>
$link = mysqli_init();
mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, true);
mysqli_real_connect($link, 'localhost', $username, $password, $database);
The connection string to the database is what worked for me. I found it in the last comment in the link given by developerwjk
Your problem is the use of the LOCAL keyword. When you use LOCAL the server expects the MySQL client to read the file and send it. This applies when the client software is running on a remote machine, or when you're running the MySQL client on the server itself. (This is why you can run your query from the server command line).
If you're running PHP there is no client software involved. PHP makes calls directly to the server, so the LOCAL keyword is invalid in this context.
To use LOAD DATA INFILE from PHP you must make sure that the file is placed in a location in the server filesystem that the MySQL server has read access to, and that the full path to that file is passed as part of your query. Don't use the LOCAL keyword.
If you're trying to load a file from a remote client you'll need to upload the file to the file system first, then execute your query.
Note this sentence from the MySQL manual: If LOCAL is specified, the file is read by the client program on the client host and sent to the server.
Reference: http://dev.mysql.com/doc/refman/5.5/en/load-data.html

connecting to another db from one server

Ok so I have a client that is trying to move half his site to another server...in this i still need to pull data from both databases. SO i have the new site and i need to do a mysql db query on the old site so i can include the old nav....but when i do
<?php include("http://www.othersite.com/includes/db.php"); ?>
<?php include("http://www.othersite.com/includes/nav.php"); ?>
I get
Warning: mysql_query(): Access denied for user 'www-data'#'localhost'
(using password: NO) in /vol/www/othersite.com/public_html/includes/nav.php
on line 223 Warning:
How do i access another db from the new site and not allow it to interfere with the new db connection
you can use:
$newLink = mysql_connect($host, $user, $password);
mysql_select_db($db, $newLink);
and the you should add the $newLink to your queries so it will not use the "old" database link connection, like:
mysql_query('SELECT * FROM USERS', $newLink);
Hope it helps
P.S. It'll be more easy if you put the code from db.php and nav.php
You'd need to show us the actual code used to connect to these dataases (with passwords blanked out). But even without it I can tell you that the remote server is NOT called localhost.
It seems you're including these files from the remote site. It won't work this way, since the code is still executed on local server.
You must also make sure, that the remote MySQL allows remote connections, and that there is a MySQL user account with appropriate privileges created.
See: http://dev.mysql.com/doc/refman/5.5/en/privilege-system.html
...in this i still need to pull data
from both databases.
Good luck with this!
The way I would do this:
Copy code to server #2
Adjust it to fetch data from server #1
Change DNS record from ip of server #1 to ip of server #2
Wait 1 day
Give blocking 'server maintenance' for 5 minutes on server #1
rsync db from server #2 to #1 / adjust server #2 to fetch data from itself
Remove 'server maintenance'
Sell server #1 on ebay and get boozed
NOTE:
Sure, if you are talking about some private host.. There are far more successful yet complicated mechanisms to do the same without putting server offline.
Load http://www.othersite.com/includes/db.php in your browser. You'll notice that you cannot see the PHP code: what you obtain is the output of the PHP code. That means than changing all your ìnclude constructs to point to a remote HTTP server will simply break your site since you'll no longer have access to the source code.
Now, answering to your question, if you want to connect to a remote database you must find wherever you have the DB password and change the data: localhost with the new server address, www-data with your new user, etc. However, you probably need to configure the remote MySQL server so it accepts external connections from your new server's IP address.

php returns different mysql result

I have just moved my host to another machine but now a problem has occured. I get different mysql results from php. To be more spefecific, php returns the last result when i got back-up. I am checking database via mysql console but there are new entries. But php continues to return the old results. What do i need to do fix this?
P.S i can download php files which are on my new host. I can see the source code. Weird...
Thank you.
Your php might still be connecting to the old database
If you can download the php files, your server isn't set up to run PHP and/or has a mis-configured .htaccess file
Check your database connection code.
It's possible that you're connecting to a remote host, rather than 'localhost':
$mysql_connection = mysql_connect('mysql.example.com', 'user', 'pass');
There is another possibility, different databases:
mysql_select_db('using_old_db', $mysql_connection);

Create MySQL user and database from PHP

Is there a way to create a new MySQL database, a new MySQL user and give the new user privileges on the new database all using PHP?
EDIT - should be pointed out this is run from 1 server to another, so Server A trying to install a DB/user on Server B
i've got this:
$con = mysql_connect("REMOTE.IP.ADDRESS","root","pass");
mysql_query("CREATE DATABASE ".$db."",$con)or die(mysql_error());
mysql_query("GRANT ALL ON ".$db.".* to ".$user." identified by '".$dbpass."'",$con) or die(mysql_error());
but i'm getting an error on the grant query:
"Access denied for user 'root'#'MY.REMOTE.SERVER.HOST.NAME' to database 'dbname'"
This answer has been edited several times based on new info provided by the OP
Is root actually allowed to connect to the server from the host that you are connecting from? If the error string is returning the canonical name of the server, there's a very good chance that 'localhost' is not pointing to 127.0.0.1 :
"Access denied for user
'root'#'MY.SERVER.HOST.NAME' to
database 'dbname'"
That should echo something like "Access denied for user 'root'#localhost'", not the name of the server.
Try:
$con = mysql_connect("127.0.0.1","root","pass");
Edit (After more information provided in comments)
If you are connecting from a totally different host, you have to tell MySQL user#remote_hostname_or_ip is allowed to connect, and has appropriate privileges to create a database and users.
You can do this rather easily using phpmyadmin (on the MySQL server), or a query like:
CREATE USER 'root'#'192.168.1.1' IDENTIFIED BY PASSWORD 'secret';
GRANT ALL PRIVILEGES ON * . * TO 'root'#'192.168.1.1' IDENTIFIED BY PASSWORD 'secret' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
I would advise not naming this user 'root' , just create a user with all of the global privileges needed. In the example, I used 192.168.1.1, that could easily be a hostname, just make sure DNS is set up appropriately. Specify the host to match exactly as it appears in logs when you connect to the remote server.
You may also want to adjust limits to taste. More information on the CREATE USER syntax can be found here, GRANT here.
Edit
If using MySQL 4 - CREATE is not an option. You would just use GRANT (4.1 Docs On User Management)
Edit
If using C-Panel, just use the API. While yes, it does have its quirks, its easier to maintain stuff that uses it rather than ad-hoc work arounds. A lot of successful applications use it without issue. Like any other API, you need to stay on top of changes when using it.
I believe you'd have to create a connection (with the root user) to an existing database (like mysql) and then run the create query.
You don't see a database connect in this example for the obvious reason: it is supposed that you learned already that any database action requires connect first.
It's the way the books being written: the things from the previous lessons being omitted in the next ones. Or every chapter will be 2 times bigger and you'll never finish the book.
so yes, you need to connect to the database first, using mysql_connect().
to create a user you can use mysql GRANT query
though I am never done it from the script but from the shell only
You would need to connect to the sql server first:
$conn=#mysql_connect(DB_HOST, DB_USER, DB_PASSWORD)
or die("Err:Conn");
Then the query will execute. A lot of shared hosting servers disable the creation of databases via PHP though.

Connecting to MySQL with PHP

I have MySQL running such that I can open a client command line and log on and make databases, tables, etc.
I wanted to do some AJAX. Doing AJAX with ASP, SQL Server, etc is not advisable since both places where I am hosting my websites do not use the Microsoft products. So I am forced to do my development with PHP and MySQL.
I just about have everything set up. I have set up IIS so that I can go to my localhost and I can test out web pages. I have PHP installed so that I can pull up the PHP setting pages.
The problem occurs when I try to bring up the MySQL database in PHP. I use this very simple PHP command:
<?php
$con = mysql_connect('localhost', 'testuser', 'testpassword');
?>
When I try to connect to the mysql database through PHP, I get this error:
Click here
I figure the problem must be in the settings that are in the php.ini. But it seems that my php.ini is set up for MySQL although it is not mentioned in the output when I query the phpinfo page with this code
Here is the result from this:
Click here
It looks that your php is missing mysql module
in php.ini make sure that you have correct extensions path eg.:
extension_dir = "C:\php\ext"
and make sure you have commented out:
extension=php_mysql.dll
extension=php_mysqli.dll
Which version of PHP are you running and are you sure you have MySQL installed and running on localhost with a username of "testuser" and a password of "testpassword" (and have you reloaded the privilege tables after creating those users)?
Have you got IIS configured to log errors into a file - does that provide any more information?
Create a new PHP file that contains the following:
<?php
phpinfo();
?>
This will helpy you to discover if MySQL has been compiled in properly etc. Can you access the MySQL server from the command line; using something similar to:
mysql -u testuser -ptestpassword testdatabase
If you get a prompt from MySQL, the service is running and we can better help from there.
Hope that helps a little!
Are you selecting the database? After your connect statement, you need to use:
mysql_select_db($databaseName, $conn);
Documentation here: http://php.net/mysql_select_db
What I would do is to download the complete package in one go (Server, MySQL and PHP). There are tons of good resources like WAMP or MAMP (for MAC users). Once you download the package the installation is just easy and you don't have to set anything as it does it automatically.
They also have phpMyAdmin where you can manage your database and its users and privileges.
Once you got your server running you can test that code that seems fine for me. Try running something like this:
<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
die('Could not connect: ' . mysql_error());
}
echo 'Connected';
mysql_close($link);
?>
Cheers

Categories