I am trying to create periodic backups (poor man's cron) of my database using mysqldump with exec() function. I am using XAMPP/PHP7 on macOS.
$command = "$mysqldump_location -u$db_user -h$db_host -p$db_password $db_name > $backup_file_location";
exec($command);
When I run the PHP script, I get no SQL dump in the path mentioned in $backup_file_location but if I execute the same $command string on the terminal directly I get the desired SQL file in the desired location.
I am unable to understand what could be the problem here. Also open to suggestions on better ways to dump the entire DB.
Edit 1:
The value of $mysqldump_location is /Applications/XAMPP/xamppfiles/bin/mysqldump
The value of $backup_file_location is /Applications/XAMPP/xamppfiles/htdocs/app5/data/sqldumps/sql_data.sql
/app5/ is the folder in while I am developing my app.
Edit 2:
Possible duplicate suggestion does not apply since the issue here was not on how to dump SQL backups. The key issue here was that the backup using mysqldump was working through terminal, but not through PHP's exec() function.
The resolution of the issue, from above comments, was that the PHP request executes in XAMPP as a user that has limited privileges, and the mysqldump process inherits those privileges.
Checking the exit status of the process run by exec() confirmed that mysqldump exited with a nonzero exit status, indicating it failed for some reason.
Opening write privileges to 777 on the directory where the mysqldump process tries to write resolved the error.
It should also be adequate to figure out the specific uid & gid of Apache processes (check the User and Group config values in the Apache config file (e.g. xampp-home/apache/conf/httpd.conf) and make the output directory writeable by that uid or gid.
Related
$output = shell_exec('echo "php '.$realFile.'" | at '.$targTime.' '.$targDate.' 2>&1');
print $output;
Can someone please help me figure out why the above line isn't doing what it's supposed to be doing? The idea is for it to create an 'at' job that will execute a php script. If I switch to the user apache(which will ideally control the at function when the php file is complete) I can run
echo "php $realFile.php" | at 00:00 05/30/17
and it'll do EXACTLY what I want. The problem is in the above snippet from my php file it will not create the at job correctly. when I do a at -c job# on both of them the job made from my file is about a 3rd the length missing the User info and everything. It basically starts at PATH= and goes down. Doesn't include HOSTNAME=, SHELL=, SSH_CLIENT=, SSH_TTY=, USER=. I assume it needs most of this info to run correctly. The end output (below)is always the same though it just doesn't have any of the top part for some reason. Let me know if you need more info. I didn't want to paste all of my code here as it contains job specific information.
${SHELL:-/bin/sh} << 'marcinDELIMITER0e4bb3e8'
php "$realFile".php
marcinDELIMITER0e4bb3e8
It doesn't seem to be a permission issue because I can su to apache and run the exact command needed. The folder the files are located in are also owned by apache. I've also resulted to giving each file I try to run 777 or 755 permissions through chmod so I don't think that's the issue.
I figured out a coupe ways around it a while back. The way I'm using right now is an ssh2 connect to my own server as root and creating it that way. No compromise as you have to enter the password manually each time. Really bad work around. The main issue is that apache doesn't have the correct permissions to do everything needed for the AT job so someone figuring that out would be awesome. Another option I found on a random webpage would be to use sudo through the php script, but basically the same minus having to reconnect to your own server. Any other options would be appreciated.
Reading the manual and logs would be a good place to start. In particular:
The value of the SHELL environment variable at the time of at invocation will determine which shell is used to execute the at job commands. If SHELL is unset when at is invoked, the user’s login shell will be used; otherwise, if SHELL is set when at is invoked, it must contain the path of a shell interpreter executable that will be used to run the commands at the specified time.
Other things to check are that the user is included in at.allow, SELinux is disabled and the webserver is not running chrrot.
TL;DR:
I have a PHP page which executes a shell script containing impdp which imports dump to a new schema.
PHP file:
echo shell_exec("./DumpCreator.sh 22");
DumpCreator.sh
#!/bin/bash
echo $1
impdp U_$1/Pass DIRECTORY=dmpdir DUMPFILE=MYDMP.DMP remap_schema=PARENT:U_$1
It echos 22 but impdp doesn't execute although all permissions are given to a single user (admin).
Full
I have a PHP page which creates a shell script file and overwrites its contents as the following:
$shellFile = fopen("myfile.sh" , "w");
$field = "1";
$command = "#!/bin/bash\n"
."echo $field\n"
."sqlplus system/pass as sysdba << SQLEND\n"
."create user U_$field identified by newpass;\n"
."grant dba to U_$field;\n"
."exit;\n"
."SQLEND\n";
fwrite($shellFile, $command);
$output = shell_exec("bash myfile.sh");
echo $output;
fclose($shellFile);
contents of .sh file
#!/bin/bash
echo 1
sqlplus system/pass sysdba << SQLEND
create user U_1 identified by pass;
grant dba to U_1;
exit;
SQLEND
My problem is the part of sqlplus isn't executing.
so what is wrong with this, thanks in advance.
UPDATE
When I execute .sh file itself everything executes well (user is added and granted).
UPDATE 2
I tried doing mentioned above using php oci and it ran successfully.
Now the problem is with when user is granted permission I need to copy some dump to it using a script which I will be needing to execute using PHP.
My new .sh file
#!/bin/bash
echo $1
impdp U_$1/pass DIRECTORY=DATA_PUMP_DIR DUMPFILE=something.DMP remap_schema=something:U_$1
Even if I removed $1, it doesn't execute this part and I think it doesn't require sudo or to su to root, so what am I doing wrong ? also what permissions that could be missing in the process ?
Update 3
Executing the script directly from terminal using 'admin' account which is the one Oracle is installed on, also getting the current user in PHP shows that it's 'admin'.
So the problem is with How Can I execute any non-os related commands (anything but echo, ls .. etc) from my PHP page ?
So after searching about permissions, I found that it's possible to execute anything (root or non-root commands) by editing sudoers file which will allow any php to execute any command and that's as far as I can tell is a very poor solution.
Ref : How to call shell script from php that requires SUDO?
Make sure you have the required environment variables set.
In particular you'll probably have to set LD_LIBRARY_PATH to the location of the shared libraries that come with your Oracle installation.
The PHP code is probably hiding the error messages related with this.
Compare your environment where you normally run SQL*Plus or IMP before and after running oraenv, you will need to set at least a few of those (and probably most if not all).
I have been scratching my head over why my code didn't work for a couple of days now (since when I printed my variables out they were fine, but wouldn't record into the database) but now I realized that the issue is that PHP isn't reading the CSV file (basically what I needed to do was take a CSV file, and port it to a PostgreSQL database).
I now realize that the reason it doesn't work is because I am executing the code through the command line when trying to write to the database, but in the browser when testing.
This led me to realize that the file isn't being read when I execute the code through cmd. The CSV file is too big to execute in a browser and causes an internal server error so I have to execute it through cmd, and yet when I do, it doesn't read the file, so how would I go about fixing that?
Most likely you have file owner/permission problems. When you execute script in browser it is exectuted as user www-data (or whatever your user is). When you run from command line you run it as yourself, which is another user.
Either change file permissions or run your script from web user, for example
sudo -u www-data php yourscriptname.php
I have created a PHP script that generates some .gz files, when I execute the PHP script through command line (cli), it generate the .gz file having 'desert' as user but when the script is executed through browser it generates the .gz file with 'nobody' as user which should not happen. I want the generated file to have 'desert' user rather than 'nobody' user when the script is executed through browser.
Here is the code I have created:
$file='test';
$newFileGZipCommand = 'cat '.$file.'_new | gzip > '.$file.'.gz';
//$newFileGZipCommand = 'sudo -u desert cat '.$file.'_new | gzip > '.$file.'.gz'; // This does not work
$newFileGZipCommandExecute = shell_exec($newFileGZipCommand);
//chmod($file.'.gz',0777) or die("Unable to change file permission");
//chown($file.'.gz', 'directu') or die("Unable to change file Owner");
I tried doing changing the file permissions and owner through chmod() and chown() functions in php but it say "chown(): operation not permitted".
Any pointer to this is highly appreciated.
[Note: I cannot change the httpd.conf or any other configuration files]
Sudo normally requires an interactive shell to enter your password. That's obviously not going to happen in a PHP script. If you're sure you know what you're doing and you've got your security issues covered, try allowing the Apache user to run sudo without a password, but only for certain commands.
For example, adding the following line in your sudoers file will allow Apache to run sudo without a password, only for the gzip command.
nobody ALL=NOPASSWD: gzip
Adjust the path and add any arguments to suit your needs.
Caution:
There might still be complications due to the way PHP calls shell
commands.
Remember that it's very risky to allow the web server to
run commands as root!
Another alternative:
Write a shell script with the suid bit to make it run as root no matter who calls it.
Probably a better alternative:
Write the commands to a queue and have cron pick them up, validate them (only allow known good requests), and run them, then mark that queue complete with the date and result.
Your end-user can then click/wait for update using ajax.
Hope it helps resolve your answer.
I have a pretty complicated bunch of sql calls that I have stored to a .sql file, that I can't call using sqlsrv_query because there are a bunch of GOs.
From the (windows) command line I can run the sql file using
"path\to\sqlcmd" -U name -P pass -S loc -i "path\to\stuff.sql"
I can also write system( [all that] ) in a php file that I run from the command line using php -f.
However, if I call the same system( [allthat] ) from a php file that I call using ajax on a website, I get no feedback, the sql just doesn't run. I've checked sqlcmd, and it has permissions to allow all users to execute.
Any ideas?
Permissions issue. If you're running it from the command line, it's running under YOUR permissions. When you invoke it via a webserver, it's running with the webserver's permisisons. The webserver will need execute rights (and permission to REACH the sqlcmd) as well as read rights on the .sql file (and permission to reach it).
For that, you may use the shell_exec.