Tuleap Docman Permission Denied - php

Earlier today I installed Tuleap like instructed on CentOS 6.7.
Most of it works, but when I try to add a document with the DocumentManager, I get the following error: Error while creating initial version.
I looked into the log files of httpd [Sun Jan 03 16:45:36 2016] [error] [client 192.168.99.6] PHP Warning: mkdir():$Permission denied in /usr/share/tuleap/plugins/docman/include/Docman_FileStorage.class.php on line 112, referer: (domain)/plugins/docman/?group_id=101$
I now know that it is a permission problem, but I do not know where these files are being stored and how to get the permissions right. Does anyone can give me a direction on where to look?
Thank you in advance!

Solved.
When closely observed inside the httpd error log, it stated that it wanted to put the file in the root directory. Of course this isn't permitted. Therefore, it was needed to change the filepath that is created automatically by Domcman.
I found the Docman_FileStorage.class.php file that is causing the automatic path creation inside /usr/share/tuleap/plugins/docman/include and edited the getPath function/variable $path to /var/lib/tuleap/docman, so it would have the correct path.
For the complete edited function, see below:
*/
function _getPath($name, $group_id, $item_id, $version_number) {
$name = preg_replace('`[^a-z0-9_-]`i', '_', $name);
$name = preg_replace('`_{2,}`', '_', $name);
$hash1 = $item_id % 10;
$hash2 = ( ($item_id - $hash1) / 10) % 10;
$path_elements = array($this->root, $this->_getGroupName($group_id), $hash2, $hash1, $item_id, $version_number);
$path = '/var/lib/tuleap/docman';
foreach($path_elements as $elem) {
$path .= $elem .'/';
if (!is_dir($path)) {
mkdir($path, 0700);
}
}
$path .= $name;
return $path;
}

Related

fopen creates files owned by root in php

I'm writing the code for converting disqus comments to HashOver system, and I have code like this:
// $threads is list of threads from disqus api that I cached on disk
foreach ($threads as $thread) {
$dir_name = getSafeThreadName(preg_replace("%^https?://[^/]+%", "", $thread['link']));
$dir = 'threads/' . $dir_name;
if (!is_dir($dir)) {
mkdir($dir);
chmod($dir, 0774);
}
// ...
// $thread_posts are $post that belong to $thread
foreach($thread_posts as $post) {
$xml = new SimpleXMLElement('<comment/>');
// ...
// $name_arr is array of numbers for HashOver comments
$fname = $dir . '/' . implode('-', $name_arr) . ".xml";
$f = fopen($fname, 'w');
fwrite($f, $xml->asXML());
fclose($f);
chmod($fname, 0664);
}
}
it created directory for each of my posts in threads that that is read/write with owner apache:apache and inside there are files like 1.xml with owner root:root
why root:root? How can I make it apache:apache?
EDIT:
This is no a duplicate, I don't want to change permission to apache:apache from root:root, which can be done using chown, but I want to make it so it don't change it to root:root in first place, I also want to know why it changed to root:root. This looks like a bug in php or apache for me or some wrong configuration in apache on my side. I don't think is the code since it just open, write and close file.
Don't know why and I would like to know, but this solve the issue:
I've use this:
chmod($dir, 0775);
instead of:
chmod($dir, 0774);
directory was not executable for others and it make files in that directory owned by root when created. Very weird.

fopen creates the file but fwrite doesn't write any data and returns 0

The below is part of the OpenX server code (Smarty Plugin).
When the fopen is called, the file is created successfully. But the fwrite doesn't write any data in the file and returns 0 (not FALSE).
The folder itself has the following permission:
drwxrwxrwx nobody nobody
The file is created with the following permissions:
-rw-r--r-- nobody nobody
Here's the code.
function smarty_core_write_file($params, &$smarty)
{
$_dirname = dirname($params['filename']);
if ($params['create_dirs']) {
$_params = array('dir' => $_dirname);
require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php');
smarty_core_create_dir_structure($_params, $smarty);
}
// write to tmp file, then rename it to avoid file locking race condition
$_tmp_file = tempnam($_dirname, 'wrt');
if (!($fd = fopen($_tmp_file, 'wb'))) {
$_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid('wrt');
if (!($fd = fopen($_tmp_file, 'wb'))) {
$smarty->trigger_error("problem writing temporary file '$_tmp_file'");
return false;
}
}
fwrite($fd, $params['contents']);
fclose($fd);
if (DIRECTORY_SEPARATOR == '\\' || !rename($_tmp_file, $params['filename'])) {
// On platforms and filesystems that cannot overwrite with rename()
// delete the file before renaming it -- because windows always suffers
// this, it is short-circuited to avoid the initial rename() attempt
unlink($params['filename']);
rename($_tmp_file, $params['filename']);
}
chmod($params['filename'], $smarty->_file_perms);
return true;
}
Below is the code I use to test this function:
$params = array('filename'=>'/usr/apache/www/templates_compiled/%%72^729^729250E1%%main.html.php', 'contents'=>'testString', 'create_dirs'=>TRUE);
smarty_core_write_file($params, NULL);
The problem was that the server was full. So after freeing some space, the code worked fine.

File upload / move temp not working on nginx

So, i've read this question about move_uploaded_file() problems. However, on my apache-powered localhost lamp stack, its working just fine. So i think it may be a filesystem / path thing, and not a code thing.
when uploading files to my site locally, it works.
but when I'm on the QA server (which is nginx powered), i get this error:
2012/09/08 15:34:21 [error] 11794#0: *5187 FastCGI sent in stderr: "files not empty
PHP Warning: move_uploaded_file(/var/www/qa.mysite.com/mysite/app/files/maps-aprilfools.tiff): failed to open stream: No such file or directory in /var/www/qa.mysite.com/mysite/app/models/files.php on line 516
PHP Warning: move_uploaded_file(): Unable to move '/tmp/phpvdtznP' to '/var/www/qa.mysite.com/mysite/app/files/maps-aprilfools.tiff' in /var/www/qa.mysite.com/mysite/app/models/files.php on line 516" while reading response header from upstream, client: 72.xxx.xxx.xxx, server: qa.mysite.com, request: "POST /projects/3/files HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "qa.mysite.com", referrer: "http://qa.mysite.com/projects/3/files"
and this is the code that I wrote to handle uploading a file:
public function fileUploadToProject( $project_id ) {
if ($_FILES["upload-file"]["error"] > 0) {
echo "Error: " . $_FILES["file"]["error"] . "<br />";
} else {
$dbSuccess = false;
$tmp_name = $_FILES["upload-file"]["tmp_name"];
$name = $_FILES["upload-file"]["name"]; // someFile.ext
$size = $_FILES['upload-file']['size']; //size in bytes
$mime = $_FILES['upload-file']['type']; //size in bytes
$destination = __FILES__.'/'.$name;
$uploaded = move_uploaded_file( $tmp_name, $destination );
// add entry to database.
/*
* null because there is no container yet.
* We're only uploading to local
*/
$user_container_name = null;
$uploaded_by = LoggedInUser::get_user_id();
/*
* Set this 1 when we're not dealing with our external fileserver
*/
$isLocal = 1;
/*
* Probably shouldn't do this forever for storage size reasons, but for now its useful.
*/
$localPath = $destination;
$task_id = null;
if( $uploaded ) {
$dbSuccess = $this->insertFileRefService( $task_id,
$project_id,
$user_container_name,
$name,
$mime,
$size,
$uploaded_by,
$isLocal,
$localPath
);
if($dbSuccess) {
return true;
} else {
// should I rollback / delete that file?
return false;
}
} else {
return false;
}
}
}
So, is there anything I should know about moving temp files to my filesystem with on nginx? or do you think it is simply a path problem? code problem?
Also, please note that line 516 is this: $uploaded = move_uploaded_file( $tmp_name, $destination );
The folder had problems with permissions, among other things.
the /files directory in that path actually doesn't exist. I somehow never realized that the folder simply wasn't there. Whoops.
then, i had to determine what user was used by nginx to execute php:
ps aux | grep "nginx"
then i had to chown the files directory:
chown -R root:userFromStep1 files
then i had to chmod the directory:
chmod g+w files
that worked like a charm.
Can please try with giving the exact path instead of using the __FILES__. Because it'll not be nginx problem. it will be path problem only

Write binary file in PHP

I have wrote a PHP file which will save a JPEG file in the server and part of the code is listed as follow:
//create folder if folder not exist
if (!is_dir($save_path)){
$old = umask(0);
$flag = #mkdir($save_path,0777);
umask($old);
if(isset($flag)){
$string = 'Folder Create Success!'."\n";
}else{
$string= 'Folder Create Fail!'."\n";
}
echo $string;
}else{
echo "Folder exist!!!!";
}
//write the content to the server
$base=$_REQUEST['image'];
$binary=base64_decode($base);
header('Content-Type: image/jpg; charset=utf-8');
if(!$file = fopen($path, 'wb')){
echo 'Image upload Fail!'."\n";
return;
}
else
{
fwrite($file, $binary);
fclose($file);
}
The problem is when I run the code, if the folder does not exist, it create the folder only but the content can't save in the folder. The error message is :
[Thu Jul 05 16:59:06 2012] [error] [client 10.95.61.220] PHP Warning: fopen(/mnt/csis/upload/newphoto/others/12346_test/12346_test_2012-07-05_others_abc.jpg): failed to open stream: Permission denied in /var/www/html/upload_image.php on line 57
However, if I run the code again, since the folder was created in the past, it work properly. The content can save in the folder......
Anything I get wrong? I try to find the answer on the web but still can't solve the problem.
Anyone can help, many thanks!
I would try changing the creation of the folder to use the recursive flag:
$flag = #mkdir($save_path . "/" . $file,0777,true);

uploading multiple pictures causeing 500 error

I modified a script i found on here to do process multiple pictures being uploaded at once. However when I try to run the script it throws an error. I use to have the script only allow one picture upload at time and that worked fine without any issue.
Here is my code.
Function uploadMultiple(){
$config = array(
'allowed_types' => 'jpg|png|jpeg|gif',
'upload_path' => $this->board_path,
'overwrite' => false,
//'file_name' => $fileName
);
//print_r($config);
$this->load->library('upload');
$errorCount = 0;
$results = array(
'errorsPresent' => false,
);
$successCount = 0;
//for each image...try to upload. if it fails, add it to the error list.
//keep a list of successful uploads.
print_r($_FILES);
for ($i = 0; $i<count($_FILES); $i++){
echo 'here';
$_FILES['userfile']['name'] = $_FILES['userfile' . $i]['name'];
$_FILES['userfile']['type'] = $_FILES['userfile' . $i]['type'];
$_FILES['userfile']['tmp_name'] = $_FILES['userfile' . $i]['tmp_name'];
$_FILES['userfile']['error'] = $_FILES['userfile' . $i]['error'];
$_FILES['userfile']['size'] = $_FILES['userfile' . $i]['size'];
$config['file_name'] = 'img_' . time() . '.png'; //inserts the unix time into the file name.
$config['upload_path'] = $this->board_path;
$config['allowed_types'] = 'jpg|jpeg|gif|png';
$config['max_size'] = '0';
$config['overwrite'] = FALSE;
$this->upload->initialize($config);
if ( ! $this->upload->do_upload()){
$results['errorsPresent'] = true;
$results['error'][$errorCount] = $this->upload->display_errors();
$errorCount ++;
} else {
$data = array('upload_data' => $this->upload->data());
$pictureData = $this->upload->data();
$file_location = $pictureData['full_path'];
$file_location = substr($file_location, 18);//this should probably be dynamic...
$file_location = $this->db->escape($file_location);
$results['success'][$successCount] = $file_location;
chmod($pictureData['full_path'], 777); //don't need to give it execute permissions but oh well.
$successCount ++;
}
}
return $results;
}
Here is the 500 error.
Internal Server Error
The server encountered an internal
error or misconfiguration and was
unable to complete your request.
Please contact the server
administrator, webmaster#localhost and
inform them of the time the error
occurred, and anything you might have
done that may have caused the error.
More information about this error may
be available in the server error log.
Additionally, a 500 Internal Server
Error error was encountered while
trying to use an ErrorDocument to
handle the request.
This is what the apache log file says:
[Wed Mar 23 02:29:41 2011] [error] [client 129.21.129.32] ModSecurity: Access denied with code 500 (phase 4). Pattern match "(?:\b(?:(?:s(?:elect list because it is not contained in (?:an aggregate function and there is no|either an aggregate function or the) GROUP BY clause|upplied argument is not a valid (?:(?:M(?:S |y)|Postgre)SQL|O(?:racle|DBC)))|S(?:yntax error converti ..." at RESPONSE_BODY. [file "/etc/apache2/conf.d/modsecurity/modsecurity_crs_50_outbound.conf"] [line "23"] [id "970003"] [msg "SQL Information Leakage"] [severity "WARNING"] [tag "LEAKAGE/ERRORS"] [hostname "hostname.com"] [uri "/longboard/index.php/board/add"] [unique_id "TYmTVYEVgWYAAASKoIcAAAAJ"]
Based on the error message I think modsecurity is blocking the script for some reason but i'm not sure why. Any insight would be greatly appreciated.
Thanks
try disabling mod_security ,
in .htaccess add this
SecFilterEngine Off
It ended up being a database error. Mod_security was blocking the error message. I went into the mod_security log file and found which rule was causing it to throw the 500 error. I then went into the file with that rule and commented it out. I restarted apache and retested and then the database error showed. I'm thinking of leaving this rule commented out since this is a development server. (It does broadcast to the whole world though, and the reason I have Mod_security installed.)

Categories