2004-10-20 23:06:45 +02:00
< ? php
2007-04-13 14:55:55 +02:00
/* Copyright ( C ) 2004 - 2007 Rodolphe Quiedeville < rodolphe @ quiedeville . org >
2013-06-04 19:36:41 +02:00
* Copyright ( C ) 2004 - 2013 Laurent Destailleur < eldy @ users . sourceforge . net >
2005-11-01 16:58:51 +01:00
* Copyright ( C ) 2005 Simon Tosser < simon @ kornog - computing . com >
2018-10-27 14:43:12 +02:00
* Copyright ( C ) 2005 - 2012 Regis Houssin < regis . houssin @ inodbox . com >
2010-04-21 10:47:58 +02:00
* Copyright ( C ) 2010 Pierre Morin < pierre . morin @ auguria . net >
2010-10-08 18:56:14 +02:00
* Copyright ( C ) 2010 Juanjo Menent < jmenent @ 2 byte . es >
2004-07-12 11:46:13 +02:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2013-01-16 15:36:08 +01:00
* the Free Software Foundation ; either version 3 of the License , or
2004-07-12 11:46:13 +02:00
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2011-08-01 01:19:04 +02:00
* along with this program . If not , see < http :// www . gnu . org / licenses />.
2004-07-12 11:46:13 +02:00
* or see http :// www . gnu . org /
*/
2007-04-13 14:55:55 +02:00
/**
2008-11-24 21:09:23 +01:00
* \file htdocs / document . php
* \brief Wrapper to download data files
2010-02-28 15:16:46 +01:00
* \remarks Call of this wrapper is made with URL :
2018-02-13 13:55:36 +01:00
* DOL_URL_ROOT . '/document.php?modulepart=repfichierconcerne&file=relativepathoffile'
* DOL_URL_ROOT . '/document.php?modulepart=logs&file=dolibarr.log'
* DOL_URL_ROOT . '/document.php?hashp=sharekey'
2008-11-24 21:09:23 +01:00
*/
2004-12-28 16:02:48 +01:00
2018-01-02 22:58:37 +01:00
//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled cause need to load personalized language
//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); // Not disabled cause need to load personalized language
2019-01-27 11:55:16 +01:00
if ( ! defined ( 'NOTOKENRENEWAL' )) define ( 'NOTOKENRENEWAL' , '1' );
if ( ! defined ( 'NOREQUIREMENU' )) define ( 'NOREQUIREMENU' , '1' );
if ( ! defined ( 'NOREQUIREHTML' )) define ( 'NOREQUIREHTML' , '1' );
if ( ! defined ( 'NOREQUIREAJAX' )) define ( 'NOREQUIREAJAX' , '1' );
2018-04-21 12:00:55 +02:00
2017-10-30 00:45:47 +01:00
// For direct external download link, we don't need to load/check we are into a login session
2018-12-17 15:35:20 +01:00
if ( isset ( $_GET [ " hashp " ]) && ! defined ( " NOLOGIN " ))
2017-10-30 00:45:47 +01:00
{
2019-01-27 11:55:16 +01:00
if ( ! defined ( " NOLOGIN " )) define ( " NOLOGIN " , 1 );
if ( ! defined ( " NOCSRFCHECK " )) define ( " NOCSRFCHECK " , 1 ); // We accept to go on this page from external web site.
if ( ! defined ( " NOIPCHECK " )) define ( " NOIPCHECK " , 1 ); // Do not check IP defined into conf $dolibarr_main_restrict_ip
2018-01-02 22:58:37 +01:00
}
// Some value of modulepart can be used to get resources that are public so no login are required.
2018-04-24 10:17:57 +02:00
if (( isset ( $_GET [ " modulepart " ]) && $_GET [ " modulepart " ] == 'medias' ))
2018-01-02 22:58:37 +01:00
{
2019-01-27 11:55:16 +01:00
if ( ! defined ( " NOLOGIN " )) define ( " NOLOGIN " , 1 );
if ( ! defined ( " NOCSRFCHECK " )) define ( " NOCSRFCHECK " , 1 ); // We accept to go on this page from external web site.
if ( ! defined ( " NOIPCHECK " )) define ( " NOIPCHECK " , 1 ); // Do not check IP defined into conf $dolibarr_main_restrict_ip
2017-10-30 00:45:47 +01:00
}
2009-02-18 18:04:00 +01:00
2011-07-09 02:15:16 +02:00
/**
2013-04-15 15:43:25 +02:00
* Header empty
2011-07-09 02:15:16 +02:00
*
2013-04-15 15:43:25 +02:00
* @ return void
2011-07-09 02:15:16 +02:00
*/
2018-08-15 18:14:02 +02:00
function llxHeader ()
{
}
2013-04-15 15:43:25 +02:00
/**
* Footer empty
*
* @ return void
*/
2018-08-15 18:14:02 +02:00
function llxFooter ()
{
}
2007-11-19 19:34:53 +01:00
2012-08-23 01:43:44 +02:00
require 'main.inc.php' ; // Load $user and permissions
2012-08-22 23:11:24 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2011-04-27 19:10:29 +02:00
$encoding = '' ;
2019-01-27 11:55:16 +01:00
$action = GETPOST ( 'action' , 'alpha' );
2019-01-31 18:27:27 +01:00
$original_file = GETPOST ( 'file' , 'alphanohtml' ); // Do not use urldecode here ($_GET are already decoded by PHP).
2019-01-27 11:55:16 +01:00
$hashp = GETPOST ( 'hashp' , 'aZ09' );
$modulepart = GETPOST ( 'modulepart' , 'alpha' );
$urlsource = GETPOST ( 'urlsource' , 'alpha' );
$entity = GETPOST ( 'entity' , 'int' ) ? GETPOST ( 'entity' , 'int' ) : $conf -> entity ;
2011-04-27 19:10:29 +02:00
2011-06-15 13:35:33 +02:00
// Security check
2019-01-27 11:55:16 +01:00
if ( empty ( $modulepart ) && empty ( $hashp )) accessforbidden ( 'Bad link. Bad value for parameter modulepart' , 0 , 0 , 1 );
if ( empty ( $original_file ) && empty ( $hashp )) accessforbidden ( 'Bad link. Missing identification to find file (original_file or hashp)' , 0 , 0 , 1 );
2016-05-01 16:34:50 +02:00
if ( $modulepart == 'fckeditor' ) $modulepart = 'medias' ; // For backward compatibility
2011-06-15 13:35:33 +02:00
2014-01-30 11:44:31 +01:00
$socid = 0 ;
if ( $user -> societe_id > 0 ) $socid = $user -> societe_id ;
// For some module part, dir may be privates
2017-09-21 12:48:07 +02:00
if ( in_array ( $modulepart , array ( 'facture_paiement' , 'unpaid' )))
2014-01-30 11:44:31 +01:00
{
if ( ! $user -> rights -> societe -> client -> voir || $socid ) $original_file = 'private/' . $user -> id . '/' . $original_file ; // If user has no permission to see all, output dir is specific to user
}
2010-12-18 04:27:01 +01:00
2017-09-21 12:48:07 +02:00
2010-12-18 04:27:01 +01:00
/*
2018-02-13 13:55:36 +01:00
* Actions
2010-12-18 04:27:01 +01:00
*/
2011-04-27 19:10:29 +02:00
// None
2008-08-04 00:50:32 +02:00
2011-04-27 19:10:29 +02:00
2018-02-13 13:55:36 +01:00
2011-04-27 19:10:29 +02:00
/*
* View
*/
2011-04-26 23:06:45 +02:00
2017-09-21 14:02:42 +02:00
// If we have a hash public (hashp), we guess the original_file.
if ( ! empty ( $hashp ))
2017-09-21 12:48:07 +02:00
{
include_once DOL_DOCUMENT_ROOT . '/ecm/class/ecmfiles.class.php' ;
$ecmfile = new EcmFiles ( $db );
2017-09-21 14:02:42 +02:00
$result = $ecmfile -> fetch ( 0 , '' , '' , '' , $hashp );
2017-09-21 12:48:07 +02:00
if ( $result > 0 )
{
2017-10-30 00:45:47 +01:00
$tmp = explode ( '/' , $ecmfile -> filepath , 2 ); // $ecmfile->filepath is relative to document directory
2018-12-17 15:35:20 +01:00
// filepath can be 'users/X' or 'X/propale/PR11111'
if ( is_numeric ( $tmp [ 0 ])) // If first tmp is numeric, it is subdir of company for multicompany, we take next part.
{
$tmp = explode ( '/' , $tmp [ 1 ], 2 );
}
$moduleparttocheck = $tmp [ 0 ]; // moduleparttocheck is first part of path
if ( $modulepart ) // Not required, so often not defined, for link using public hashp parameter.
2017-09-21 12:48:07 +02:00
{
2017-11-19 20:44:57 +01:00
if ( $moduleparttocheck == $modulepart )
{
// We remove first level of directory
$original_file = (( $tmp [ 1 ] ? $tmp [ 1 ] . '/' : '' ) . $ecmfile -> filename ); // this is relative to module dir
//var_dump($original_file); exit;
}
else
{
2019-01-27 11:55:16 +01:00
accessforbidden ( 'Bad link. File is from another module part.' , 0 , 0 , 1 );
2017-11-19 20:44:57 +01:00
}
2017-09-21 12:48:07 +02:00
}
else
{
2017-11-19 20:44:57 +01:00
$modulepart = $moduleparttocheck ;
$original_file = (( $tmp [ 1 ] ? $tmp [ 1 ] . '/' : '' ) . $ecmfile -> filename ); // this is relative to module dir
2017-09-21 12:48:07 +02:00
}
}
else
{
2017-10-30 00:45:47 +01:00
$langs -> load ( " errors " );
2019-01-27 11:55:16 +01:00
accessforbidden ( $langs -> trans ( " ErrorFileNotFoundWithSharedLink " ), 0 , 0 , 1 );
2017-09-21 12:48:07 +02:00
}
}
2018-12-17 18:48:41 +01:00
// Define attachment (attachment=true to force choice popup 'open'/'save as')
$attachment = true ;
2019-01-27 11:55:16 +01:00
if ( preg_match ( '/\.(html|htm)$/i' , $original_file )) $attachment = false ;
if ( isset ( $_GET [ " attachment " ])) $attachment = GETPOST ( " attachment " , 'alpha' ) ? true : false ;
2018-12-17 18:48:41 +01:00
if ( ! empty ( $conf -> global -> MAIN_DISABLE_FORCE_SAVEAS )) $attachment = false ;
2018-02-13 13:55:36 +01:00
// Define mime type
$type = 'application/octet-stream' ;
2019-01-27 11:55:16 +01:00
if ( GETPOST ( 'type' , 'alpha' )) $type = GETPOST ( 'type' , 'alpha' );
2018-02-13 13:55:36 +01:00
else $type = dol_mimetype ( $original_file );
2017-09-21 12:48:07 +02:00
2016-05-01 16:34:50 +02:00
// Security: Delete string ../ into $original_file
2019-01-27 11:55:16 +01:00
$original_file = str_replace ( " ../ " , " / " , $original_file );
2012-09-07 17:23:16 +02:00
// Find the subdirectory name as the reference
2007-01-31 18:52:54 +01:00
$refname = basename ( dirname ( $original_file ) . " / " );
2005-08-25 12:20:13 +02:00
2010-11-07 13:33:32 +01:00
// Security check
2013-04-25 10:06:54 +02:00
if ( empty ( $modulepart )) accessforbidden ( 'Bad value for parameter modulepart' );
2017-10-30 00:45:47 +01:00
2019-04-21 19:54:30 +02:00
// Check security and set return info with full path of file
2017-06-20 16:54:37 +02:00
$check_access = dol_check_secure_access_document ( $modulepart , $original_file , $entity , $refname );
2013-04-25 10:06:54 +02:00
$accessallowed = $check_access [ 'accessallowed' ];
2013-04-22 15:00:29 +02:00
$sqlprotectagainstexternals = $check_access [ 'sqlprotectagainstexternals' ];
2017-09-06 11:39:30 +02:00
$fullpath_original_file = $check_access [ 'original_file' ]; // $fullpath_original_file is now a full path name
2012-04-18 01:01:46 +02:00
2017-10-30 00:45:47 +01:00
if ( ! empty ( $hashp ))
{
2017-11-19 20:44:57 +01:00
$accessallowed = 1 ; // When using hashp, link is public so we force $accessallowed
$sqlprotectagainstexternals = '' ;
2017-10-30 00:45:47 +01:00
}
else
2007-01-31 18:52:54 +01:00
{
2017-10-30 00:45:47 +01:00
// Basic protection (against external users only)
if ( $user -> societe_id > 0 )
2007-01-31 18:52:54 +01:00
{
2017-10-30 00:45:47 +01:00
if ( $sqlprotectagainstexternals )
2007-01-31 18:52:54 +01:00
{
2017-10-30 00:45:47 +01:00
$resql = $db -> query ( $sqlprotectagainstexternals );
if ( $resql )
2010-04-21 20:35:40 +02:00
{
2017-10-30 00:45:47 +01:00
$num = $db -> num_rows ( $resql );
$i = 0 ;
while ( $i < $num )
2010-04-21 20:35:40 +02:00
{
2017-10-30 00:45:47 +01:00
$obj = $db -> fetch_object ( $resql );
if ( $user -> societe_id != $obj -> fk_soc )
{
$accessallowed = 0 ;
break ;
}
$i ++ ;
2010-04-21 20:35:40 +02:00
}
}
2007-01-31 18:52:54 +01:00
}
}
}
2007-04-12 21:47:50 +02:00
// Security:
2017-09-06 11:39:30 +02:00
// Limit access if permissions are wrong
2005-02-08 13:03:12 +01:00
if ( ! $accessallowed )
{
2009-04-29 22:16:13 +02:00
accessforbidden ();
2005-02-08 13:03:12 +01:00
}
2004-12-28 16:02:48 +01:00
2007-04-12 21:47:50 +02:00
// Security:
2017-09-06 11:39:30 +02:00
// On interdit les remontees de repertoire ainsi que les pipe dans les noms de fichiers.
2019-01-27 11:55:16 +01:00
if ( preg_match ( '/\.\./' , $fullpath_original_file ) || preg_match ( '/[<>|]/' , $fullpath_original_file ))
2007-04-12 21:47:50 +02:00
{
2017-09-06 11:39:30 +02:00
dol_syslog ( " Refused to deliver file " . $fullpath_original_file );
print " ErrorFileNameInvalid: " . $original_file ;
2007-04-12 21:47:50 +02:00
exit ;
}
2009-02-18 18:04:00 +01:00
2012-09-03 17:01:03 +02:00
clearstatcache ();
2006-06-10 20:43:11 +02:00
2017-09-06 11:39:30 +02:00
$filename = basename ( $fullpath_original_file );
2006-04-27 23:25:56 +02:00
2012-09-03 17:01:03 +02:00
// Output file on browser
2017-09-06 11:39:30 +02:00
dol_syslog ( " document.php download $fullpath_original_file filename= $filename content-type= $type " );
$fullpath_original_file_osencoded = dol_osencode ( $fullpath_original_file ); // New file name encoded in OS encoding charset
2007-01-31 18:52:54 +01:00
2012-09-03 17:01:03 +02:00
// This test if file exists should be useless. We keep it to find bug more easily
2017-09-06 11:39:30 +02:00
if ( ! file_exists ( $fullpath_original_file_osencoded ))
2012-05-30 04:11:00 +02:00
{
2017-09-06 11:39:30 +02:00
dol_syslog ( " ErrorFileDoesNotExists: " . $fullpath_original_file );
print " ErrorFileDoesNotExists: " . $original_file ;
2012-09-03 17:01:03 +02:00
exit ;
}
2009-02-18 18:04:00 +01:00
2014-02-08 02:02:01 +01:00
// Permissions are ok and file found, so we return it
2017-05-09 21:01:37 +02:00
top_httphead ( $type );
2012-09-03 17:01:03 +02:00
header ( 'Content-Description: File Transfer' );
if ( $encoding ) header ( 'Content-Encoding: ' . $encoding );
2017-11-19 20:44:57 +01:00
// Add MIME Content-Disposition from RFC 2183 (inline=automatically displayed, attachment=need user action to open)
2012-09-03 17:01:03 +02:00
if ( $attachment ) header ( 'Content-Disposition: attachment; filename="' . $filename . '"' );
else header ( 'Content-Disposition: inline; filename="' . $filename . '"' );
2017-09-06 11:39:30 +02:00
header ( 'Content-Length: ' . dol_filesize ( $fullpath_original_file ));
2012-09-03 17:01:03 +02:00
// Ajout directives pour resoudre bug IE
header ( 'Cache-Control: Public, must-revalidate' );
header ( 'Pragma: public' );
2009-02-18 18:04:00 +01:00
2017-09-06 11:39:30 +02:00
readfile ( $fullpath_original_file_osencoded );
2004-12-28 16:02:48 +01:00
2013-06-26 16:45:42 +02:00
if ( is_object ( $db )) $db -> close ();