trying to create a ftp user with permissions - php

So I'm trying to create a ftp user and give him permissions to a specific directory, but the user is not being created. When I echo the commands the directory is created and the permissions are given to the user but when i try to log with the credentials created it's not working. Please take a look. What am I doing wrong ?
$randomNum = substr(str_shuffle("0123456789abcdefghijklmnopqrstvwxyz"), 0, 8);
$randomPass = substr(str_shuffle("0123456789abcdefghijklmnopqrstvwxyz"), 0, 6);
$src = $request->path;
$dest = "/home/$randomNum";
echo $ssh->exec("mkdir $dest\n");
echo $ssh->exec("useradd -m -d $dest $randomNum\n");
echo $ssh->exec("passwd $randomNum\n");
echo $ssh->read('New password:');
echo $ssh->write($randomPass."\n");
echo $ssh->exec("nice -n 19 cp -Rf $src $dest && chown -Rf $randomNum:$randomNum $dest && exit\n");
$ssh->disconnect();

Assuming that randomNum is the username, randomPass the password and dest the home directory,
Change this:
echo $ssh->exec("mkdir $dest\n");
echo $ssh->exec("useradd -m -d $dest $randomNum\n");
echo $ssh->exec("passwd $randomNum\n");
echo $ssh->read('New password:');
echo $ssh->write($randomPass."\n");
echo $ssh->exec("nice -n 19 cp -Rf $src $dest && chown -Rf $randomNum:$randomNum $dest && exit\n");
To this:
$ssh->exec("useradd -M " . $randomNum. " -d " . $dest);
$ssh->exec("echo \"" . $randomNum . ":" . $randomPass . "\" | sudo chpasswd");
$ssh->exec("chown -R " . $randomNum . ":" . $randomNum . " " . $dest);

From your code:
echo $ssh->exec("passwd $randomNum\n");
echo $ssh->read('New password:');
echo $ssh->write($randomPass."\n");
For that command, in particular, you'd need to enable PTY mode for the reads / writes to work. You can do so by doing $ssh->enablePTY() before the command. It might not be a bad idea to do $ssh->disablePTY() after the command, however.
Also, echo $ssh->write($randomPass."\n");... that's not really gonna have the desired effect. $ssh->write just returns true or false depending on the success or failure of the write command.

Related

Running commands from PHP exec shows different result than from shell

The PHP exec command is not executing the same as the shell's interaction.
cd /var/www/myfolder
zip -r /var/www/myfolder/temp/newfile.zip ./*
generates just a zip of files in the temp directory. However (simplified version):
$zip_dir = '/var/www/myfolder';
$temp_dir = $zip_dir . '/temp/';
chdir($zip_dir);
exec('zip -r ' . $temp_dir . 'newfile.zip ./*', $return);
generates the same zip but with the full path's of var and www (which results in two copies of myfolder so my file is twice as large as needed). The $return however has the same output as the command line execution. Both state only 15 files directories/folders were zipped. There is no mention of var or www in the PHP output.
I believe the chdir() command will not have any bearing on how the commands in exec() are run. So this might fix it:
$zip_dir = '/var/www/myfolder';
$temp_dir = $zip_dir . '/temp/';
$cmd = 'cd ' . escapeshellarg($zip_dir) . ' && zip -r ' . escapeshellarg($temp_dir . 'newfile.zip') . ' ./*';
exec($cmd, $return);
Note we always escape variables being passed to the command line.
But why not just zip within PHP?
<?php
$zip_target = "/var/www/myfolder";
$zip_file = "/var/www/myfolder/temp/newfile.zip";
$zip_temp = tempnam(sys_get_temp_dir(), 'a458');
$zip_obj = new \ZipArchive();
if ($zip_obj->open($zip_temp, ZIPARCHIVE::OVERWRITE)) {
$zip_obj->addGlob("$zip_target/**/*.*");
}
$zip_obj->close();
rename($zip_temp, $zip_file);

Execute find command through ssh2_exec in php & get results

I am using php to execute a find command in linux for search a file in a directory and copy it into a other directory.
My php code is :-
<?php
include 'config.php';
$mxf = $_POST['year'];
$year = substr($mxf, 0, 4);
$ndrive = $_POST['ndrive'];
$command = 'find /var/www/html/collections/'.$year.'/ -name ' . $mxf . ' -exec cp {} ' . $ndrive . ' \;';
$stream = ssh2_exec($con, $command);
stream_set_blocking($stream, true);
$stream_out = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO);
echo stream_get_contents($stream_out);
ssh2_exec($con, 'logout');
?>
Now i want that script return false if requested file is not found in directory or file not available on server. So how can i handle this type of error with ssh2_exec command.

PHP shell execution create dynamic command

Following Command search a file in a directory and zip it,it works well
$command = "cd {$root}/files && mkdir -p {$identifier} && zip -jFS -0 {$root}{$zipname} 2491/'test&.txt'";
exec($command);
But changing files as variable is not allowing shell to execute,the below code does not work
$container_name = "2491";
$files = Array ( '0' => 'test&.txt' ,'1' => 'test5.txt','2' => 'test6.txt');
$files = " " . $container_name . "/'" . implode("' " . $container_name . "/'", $files) . "'";
$files = str_replace('$', '\$', $files);
$command = "cd {$root}/files && mkdir -p {$identifier} && zip -jFS -0 {$root}{$zipname} {$files}";
exec($command);
$root,$identifier,$zipname not causing the problem,its $files What can be the issue?
Update
var_dump for $command before execution:
string(128) "cd /var/www/files && mkdir -p zip--1 && zip -jFS -0 /var/www/files/zip--1/1002_22-06022-06022-_content.zip 2491/'test&.txt'"
which if I execute as
exec("cd /var/www/files && mkdir -p zip--1 && zip -jFS -0 /var/www/files/zip--1/1002_22-06022-06022-_content.zip 2491/'test&.txt'");
runs perfectly
Error Reponse:
zip error: Nothing to do! (/var/www/files/zip--1/1002_22-06022-06022-_content.zip)
I got it fix, issue was with file name having '&' which was chanding to '&', thus breaking the command. To get it I passed through the file name with [htmlspecialchars_decode].1

PHP can't execute command from apache, but can from CLI (MaxOS X, PHP 5.3)

I want to execute shell command from PHP, running under apache. I make script, that shows all info about enviroment.
PHP Script:
<?php
$root = dirname(__FILE__);
$coffeeFile = $root . DIRECTORY_SEPARATOR . 'Script.coffee';
$jsFile = $root . DIRECTORY_SEPARATOR . 'Script.js';
echo "User: " . exec('whoami') . "\n";
echo "Which: " . exec('which coffee') . "\n";
echo "Coffee file perms: " . substr(sprintf('%o', fileperms($coffeeFile)), -4) . "\n";
echo "Js file perms: " . substr(sprintf('%o', fileperms($jsFile)), -4) . "\n";
echo "Dir perms: " . substr(sprintf('%o', fileperms($root)), -4) . "\n";
$command = "coffee -bo $root -c $coffeeFile";
exec($command, $output);
if (filemtime($coffeeFile) > filemtime($jsFile)) {
echo 'compile failed. command: ' . $command . PHP_EOL;
echo "Output: " . implode("\n", $output) . PHP_EOL;
} else {
echo 'compile success. command: ' . $command . PHP_EOL;
}
It I'll execute it from command line from _www user, it will work:
Command:
sudo -u _www php index.php
Output from CLI:
User: _www
Which: /usr/bin/coffee
Coffee file perms: 0777
Js file perms: 0777
Dir perms: 0777
compile success command: coffee -bo /Users/username/htdocs/testcase -c /Users/username/htdocs/testcase/Script.coffee
But if run it from browser, compile fails, but not errors or output is there.
Output in browser:
User: _www
Which: /usr/bin/coffee
Coffee file perms: 0777
Js file perms: 0777
Dir perms: 0777
compile failed. command: coffee -bo /Users/username/htdocs/testcase -c /Users/username/htdocs/testcase/Script.coffee
Output: /* empty array in output */
How it can be? I change my file before every execution, it need to be compiled every time. Users are the same, "which" command works, dir and files have permissions, coffee file is valid. Maybe there are some apache or php.ini settings, that locks execution of some shell commands?
Kindly check does PHP have shell_exec access given or not. Default setting shell_exec is blocked and you have edit php.ini to unblock it and restart service and do things.
Note: Providing shell access can be dangerous as it is the open invitation to the hackers to hack your machine.

PHP LFTP data mirror output

I'm using a Linux local computer and need to backup/mirror some very large file structures regularly. I only have access to SFTP.
I was after a simple one click solution. I originally tried to write the little script in BASH but I've never used it before and am not up to scratch with the syntax so I resorted to PHP. (I do understand PHP is not designed for this kind of work, but I'm on a tight time scale and don't have the time to get into BASH atm)
<?php
//init
parse_str(implode('&', array_slice($argv, 1)), $_GET);
$error = array();
$lPrefix = '/home/hozza/Sites/';
$archiveLocation = '/home/hozza/Backups/';
$lDir = isset($_GET['l']) ? $_GET['l'] : $error[] = 'Local Directory Required';
$rDir = isset($_GET['r']) ? $_GET['r'] : $error[] = 'Remote Directory Required';
$bookmark = isset($_GET['b']) ? $_GET['b'] : $error[] = 'lftp Bookmark Required';
//Check for args
if(count($error) == 0) {
$archiveName = end(explode('/', $lDir)) . '_' . date('Y-m-d_H-i');
//Validate local dir
if(is_dir($lPrefix . $lDir)) {
//preserve Sublime Text 2 config SFTP files
$ST2_SFTP_conf = false;
if(file_exists($lPrefix . $lDir . '/sftp-config.json')) {
$ST2_SFTP_conf = file_get_contents($lPrefix . $lDir . '/sftp-config.json');
unlink($lPrefix . $lDir . '/sftp-config.json');
}
//Start mirror
$lftOutput = explode("\n", shell_exec('lftp -e "mirror -e -p --parallel=10 --log=' . $archiveLocation . 'logs/' . $archiveName . '.txt ' . $rDir . '/ ' . $lPrefix . $lDir . '/; exit top" ' . $bookmark));
//Tar regardless of lftp error or success
$tarOutput = shell_exec('cd ' . $lPrefix . ' && tar -czf ' . $archiveLocation . $archiveName . '.tar.gz ' . $lDir);
//Output completion or errors
shell_exec('notify-send -i gnome-network-properties -t 0 "Mirror & Archive Complete" "' . $archiveName . '\n\n' . implode('\n', $lftOutput) . $tarOutput . '"');
//put back ST2 SFTP conf
if($ST2_SFTP_conf != false) file_put_contents($lPrefix . $lDir . '/sftp-config.json', $ST2_SFTP_conf);
exit;
}
else shell_exec('notify-send -i error -t 0 "Mirror & Archive Error" "' . date('Y-m-d') . ' ' . date('H-i') . '\n' . $lDir . ' \n Does not exist! D:"');
}
else shell_exec('notify-send -i error -t 0 "Mirror & Archive Error" "' . date('Y-m-d') . ' ' . date('H-i') . '\n' . implode('\n', $error) . '"');
?>
It can be run for many sites via a short-cut like so...
terminator -T "Mirror & Archive" -e "php ~/Programs/mirror.php l=local-dir_path r=./ b=lftp-bookmark-name"
If no password is in the LFTP bookmark (there shouldn’t be as it's stored in plain text) the terminal prompts for a password, after the script has run, a nice notification is given with some info about files/folders/speed etc.
However, when the script is running in a terminal, only the "input password" bit is output to the terminal, I would like all the output displayed in the terminal (normally that would display what file/folder is currently working with etc.)
Anyone know how to do that?
IIRC the reason that you see the password prompt output to the terminal is that it is using stderr. You could try redirecting stdout to stderr for your commands which should show you the 'real-time' progress. Tack this on to the end of the shell_exec() command: 1>&2
ie:
shell_exec('lftp -e "mirror -e -p --parallel=10 --log=' . $archiveLocation . 'logs/' . $archiveName . '.txt ' . $rDir . '/ ' . $lPrefix . $lDir . '/; exit top" ' . $bookmark . ' 1>&2')
However, this will preclude you from having anything returned by shell_exec for logging purposes. What I would suggest is something like:
$log_stem = '/tmp/' . time() . '_'; // ie: /tmp/1357581737_
$lfOutfile = $log_stem . 'lftp.log';
$tarOutfile = $log_stem . 'tar.log';
shell_exec('lftp -blah | tee ' . $lfOutfile ' 1>&2' );
shell_exec('tar -blah | tee ' . $tarOutfile ' 1>&2' );
$lfOut = file_get_contents($lfOutfile);
$tarOut = file_get_contetns(tarOutfile);
// remove tmp files
unlink($lfOutfile);
unlink($tarOutfile);
Which will capture a copy of the output to a file before redirecting the output to stderr so you can watch it live.
However, if you want to run this via cron I would recommend against writing anything to stderr that is not an error, otherwise cron will send a warning email every time it is run.
I think the last answer was close:
Either this:
shell_exec('lftp -blah |& tee ' . $lfOutfile );
shell_exec('tar -blah |& tee ' . $tarOutfile );
Or if that still doesn't work try this:
shell_exec('lftp -blah 2>&1 | tee ' . $lfOutfile );
shell_exec('tar -blah 2>&1 | tee ' . $tarOutfile );

Categories