webserver zugriff auf Ordner überhalb von /httpdocs erlauben!??

faceless

New Member
Ich würde gerne einem PHP-Script (Gallery2) den Zugriff auf einen Ordner (mit Bildern) erlauben, der sich im übergeordneten Verzeichnis von /httpdocs befindet. Ich habe einen Strato V-Server mit Suse und Plesk. In dem Verzeichnis gibt es bereits folgende Ordner: anon_ftp, bin, cgi-bin, conf, error_docs, httpdocs, httpsdocs, pd, private, statistics, subdomains und web_users

Meine Idee war, in dem Verzeichnis nun noch einen Ordner "g2data" zu erstellen, ihm den gleichen owner geben, wie httpdocs und ihn auf chmod 777 zu setzen.

Leider sagt mir das PHP-Script immer, dass der angegebene Ordner nicht existiert. Was mache ich falsch?

PS: Kann ich über Plesk noch neue FTP Accounts anlegen? So, dass ich z.B. einen FTP-User habe, der nur Zugriff auf ein bestimmtes Verzeichnis innerhalb httpdocs hat?

Vielen dank für eure Hilfe!
 
Leider sagt mir das PHP-Script immer, dass der angegebene Ordner nicht existiert.
Bitte exakte Fehlermeldung. Evtl. auch mit Auszügen aus Deinem Script.

Kann ich über Plesk noch neue FTP Accounts anlegen?
Ja, aber...
der nur Zugriff auf ein bestimmtes Verzeichnis innerhalb httpdocs hat?
...nein.
Du kannst aber die web_user ins httpdocs verlinken. Das wäre ein Workaround.

huschi.
 
Naja, die Fehlermeldung des Installers lautet: Folder doesn't exist :)

Code:
<?php
/*
 * Gallery - a web based photo album viewer and editor
 * Copyright (C) 2000-2007 Bharat Mediratta
 *
 * 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
 * the Free Software Foundation; either version 2 of the License, or (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
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA  02110-1301, USA.
 */

/**
 * Setup filesytem storage directory
 * @package Install
 */
class StorageSetupStep extends InstallStep {
    function stepName() {
	return _('Storage Setup');
    }

    function loadTemplateData(&$templateData) {
	global $galleryStub;

	if (empty($this->_dir)) {
	    $this->_dir = $galleryStub->getConfig('data.gallery.base');
	    if (empty($this->_dir)) {
		$this->_dir = $_SESSION['configPath'] . DIRECTORY_SEPARATOR . 'g2data';
	    }
	}
	/*
	 * An example for a slightly obfuscated g2data folder name such that the location
	 * of the storage folder can't be guessed too easily.
	 */
	$templateData['suggested_obfuscated_g2data_name'] = 'g2data_' . substr(md5(rand()),0 , 10);

	$templateData['isMultisite'] = $galleryStub->getConfig('isMultisite');

	if (!empty($_POST['action']) && $_POST['action'] == 'save') {
	    if (empty($_POST['dir'])) {
		$templateData['error']['missing_value'] = 1;
	    } else {
		$dir = rtrim($this->sanitize($_POST['dir']));
		/* Normalize the path, add a traling slash if necessary */
		if (substr($dir, -1) != DIRECTORY_SEPARATOR) {
		    $dir .= DIRECTORY_SEPARATOR;
		}
		/*
		 * Make the path absolute since relative to the install/ folder isn't the same as
		 * relative to the main.php entry file. And also check if it exists.
		 */
		$realPath = @realpath($dir);
		if (empty($realPath)) {
		    /*
		     * The folder does not exist yet. If we have already write permission on the
		     * parent folder, create the storage folder.
		     */
		    $parentDir = realpath(dirname($dir));
		    if (!empty($parentDir) && is_dir($parentDir)
			    && is_readable($parentDir) && is_writeable($parentDir)) {
			$dir = $parentDir . DIRECTORY_SEPARATOR
			     . basename($dir) . DIRECTORY_SEPARATOR;
			/* Create the storage folder with restrictive permissions */
			if (@mkdir($dir)) {
			    chmod($dir, 0700);
			}
		    }
		}
		/* Check if the (newly created) dir exists, is writeable etc. */
		if (!is_dir($dir)) {
		    $templateData['error']['missing_dir'] = 1;
		} else if (!is_readable($dir)) {
		    $templateData['error']['inaccessible_dir'] = 1;
		} else if (!is_writeable($dir)) {
		    $templateData['error']['readonly_dir'] = 1;
		} else {
		    /*
		     * Security check:
		     * If the user ticks the checkbox and thereby acknowledges that the storage
		     * folder might be accessible from the web, we proceed with the installation.
		     */
		    list ($checkExecuted, $webAccessible) =
			$this->_isStoragePathWebAccessible($dir);
		    if (empty($_POST['i_acknowledge_the_risk'])
			    && (!$checkExecuted || $webAccessible)) {
			if (!$checkExecuted) {
			    /* Show a warning suggesting an obfuscated path. */
			    $templateData['error']['possibly_web_accessible_dir'] = 1;
			} else if ($webAccessible) {
			    $templateData['error']['web_accessible_dir'] = 1;
			}
		    } else {
			/*
			 * Populate the dir.
			 */
			if (!populateDataDirectory($dir)) {
			    $templateData['error']['creation_error'] = 1;
			} else {
			    $this->_dir = $dir;
			    $this->setComplete(true);
			}
		    }
		}
	    }
	    $templateData['dir'] = $dir;
	} else {
	    $templateData['dir'] = $this->_dir;
	}

	if ($this->isComplete()) {
	    $galleryStub->setConfig('data.gallery.base', $this->_dir);
	    $templateData['bodyFile'] = 'StorageSetupSuccess.html';
	} else {
	    $templateData['bodyFile'] = 'StorageSetupRequest.html';
	}

	if (!strncasecmp(PHP_OS, 'win', 3)) {
	    $templateData['OS'] = 'winnt';
	} else {
	    $templateData['OS'] = 'unix';
	}
    }

    function processRequest() {
	if (!empty($_GET['doAutoComplete'])) {
	    processAutoCompleteRequest();
	    return false;
	}

	return true;
    }

    function isRedoable() {
	return true;
    }

    /**
     * Try to protect the given folder with a .htaccess file from direct web-access.
     * And then check if the given folder is web-accessible either way.
     * Precondition: gallery and g2data folders exist.
     *
     * @return array(boolean false if check procedure failed due to platform issues,
     *               boolean true if the folder is accessible from the web (=insecure))
     */
    function _isStoragePathWebAccessible($dir) {
	/* Check if we can use fsockopen. Else we can't test it at all. */
	if (!function_exists('fsockopen')
		|| in_array('fsockopen', split(',\s*', ini_get('disable_functions')))) {
	    return array(false, false);
	}

	/* Add a .htaccess file. */
	if (!secureStorageFolder($dir)) {
	    return array(false, false);
	}
	/* Add a probe file. */
	$probeFileName = 'probe_' . substr(md5(uniqid(rand())), 0, 10) . '.html';
	$probeFilePath = $dir . $probeFileName;
	$checkString = md5(rand());
	$fh = @fopen($probeFilePath, 'w');
	if ($fh) {
	    $contents = "<html><head><title>Probe</title><body>$checkString</body></html>";
	    fwrite($fh, $contents);
	    fclose($fh);
	}

	if (!file_exists($probeFilePath)) {
	    return array(false, false);
	}

	/* Try to guess the URL to the g2data folder. */
	$storageUrlCandidates = array();
	/* Get the URL of the G2 folder. */
	$galleryUrl = getGalleryDirUrl();
	/* Get the relative path of the g2data folder to the gallery dir. */
	$storagePath = realpath($dir);
	$galleryPath = realpath(dirname(dirname(dirname(__FILE__))));
	if (strpos($storagePath, $galleryPath) === 0) {
	    /* The g2data folder is within the gallery folder. */
	    $relativeStoragePath = substr($storagePath, strlen($galleryPath) + 1);
	    $relativeStoragePath = str_replace("\\", '/', $relativeStoragePath);
	    $storageUrlCandidates[] = $galleryUrl . $relativeStoragePath . '/';
	} else {
	    /*
	     * The g2data folder is in another directory tree.
	     * Try to remove the common part of the paths and then construct a URL.
	     */
	    $galleryPathElements = explode(DIRECTORY_SEPARATOR, $galleryPath);
	    $storagePathElements = explode(DIRECTORY_SEPARATOR, $storagePath);
	    $max = 30;
	    /* Before: e.g. /foo/bar/gallery2/ and /foo/bar/g2data/. */
	    while (!empty($galleryPathElements) && !empty($storagePathElements) && $max-- > 0
		    && $galleryPathElements[0] == $storagePathElements[0]) {
		array_shift($storagePathElements);
		array_shift($galleryPathElements);
	    }
	    /* After, e.g. /g2data/ (common part removed). */
	    $relativeStoragePath = implode('/', $storagePathElements);

	    $storageUrlCandidates[] = getBaseUrl() . '/' . $relativeStoragePath . '/';
	    if (preg_match('!^.*?://.*?/[^/]+!', $galleryUrl, $matches)) {
		$storageUrlCandidates[] = $matches[0] . '/' . $relativeStoragePath . '/';
	    }
	}

	/* Also try the default path and other common paths. */
	$storageUrlCandidates[] = $galleryUrl . basename($dir) . '/';
	$storageUrlCandidates[] = getBaseUrl() . '/' . basename($dir) . '/';

	/* Try to fetch the probe file. */
	$isAccessible = false;
	foreach ($storageUrlCandidates as $storageFolderUrl) {
	    $url = $storageFolderUrl . $probeFileName;
	    list ($urlFetched, $isAccessible) = $this->_isUrlAccessible($url, $checkString);
	    if ($urlFetched && $isAccessible) {
		$isAccessible = true;
		break;
	    }
	}

	/* Cleanup: Delete the probe file. */
	unlink($probeFilePath);

	return array(true, $isAccessible);
    }

    /**
     * Try to fetch a a probe file from the storage folder and check if the returned page contains
     * the probe string. If so, the storage folder is web-accessible (read: not secure).
     *
     * @param string $url the URL that should be fetched
     * @param string $probeString expected string from the fetched file
     * @return array(boolean false if check procedure failed due to platform issues,
     *               boolean true if the folder is accessible from the web (=insecure))
     */
    function _isUrlAccessible($url, $probeString) {
	$components = @parse_url($url);
	if (!$components) {
	    return array(false, false);
	}
	$port = empty($components['port']) ? 80 : $components['port'];
	if (empty($components['path'])) {
	    $components['path'] = '/';
	}

	$fd = @fsockopen($components['host'], $port, $errno, $errstr, 1);
	if (empty($fd)) {
	    return array(false, false);
	}

	$get = $components['path'];

	/* Read the web page into a buffer */
	$ok = fwrite($fd, sprintf("GET %s HTTP/1.0\r\n" .
				  "Host: %s\r\n" .
				  "\r\n",
				  $get,
				  $components['host']));

	if (!$ok) {
	    /* Zero bytes written or false was returned */
	    return array(false, false);
	}
	fflush($fd);

	/*
	 * Read the response code. fgets stops after newlines.
	 * The first line contains only the status code (200, 404, etc.).
	 */
	$headers = array();
	$response = trim(fgets($fd, 4096));
	/*
	 * Ignore the status code.
	 * We expect either a 2xx code which would mean that the file has been fetched successfully
	 * (or there's a 404 -> redirect that suppresses the 404) and we check that later
	 * with the probe text.
	 * Or we expect an internal server 500 because mod_access is not installed.
	 * Or a 403 Forbidden since the .htaccess rule works correctly.
	 * Or a 404 because the URL is just plain wrong.
	 *
	 * Let's interpret everything but a successfully detected probe page as "secure".
	 */

	/* Ignore the headers. */
	while (!feof($fd)) {
	    $line = trim(fgets($fd, 4096));
	    if (empty($line)) {
		break;
	    }
	}
	/* Read the body */
	$fetchedPage = '';
	while (!feof($fd)) {
	    $fetchedPage .= fread($fd, 4096);
	}
	fclose($fd);

	/* Check if the expected string is present. */
	return array(true, strpos($fetchedPage, $probeString) !== false);
    }
}
?>
 
Ich denke, dann wird es ein Rechte-Problem sein.
Allerdings glaub ich, daß Du mit dieser Software die Daten nicht ausserhalb des DocRoot's lagern kannst. (Außer sie wurde in letzter Zeit entsprechend erweitert.)

huschi.
 
Welche Software meinst du? Plesk oder Gallery2? Wenn du Gallery2 meinst, dann denke ich schon, dass das geht. Genau das ist es nämlich, was mir das Skript empfiehlt. Um die Image-Firewall der Galerie nicht umgehen zu können, soll man das data Verzeichnis in einen Ordner packen, der nicht übers Web zu erreichen ist. Eben ein Ordner, der dem httpdocs-Ordner übergeordnet ist.
 
Ich hab zwar keine Ahnung, was das ist. Aber ja, vielleicht tue ich das!

Was ist denn das bitte und wie kann mir das helfen?
 
Ganz einfach erklärt: open_basedir sagt PHP in welchen Verzeichnissen es arbeiten darf.

Wie du das in Plesk am einfachsten machst, kann ich dir leider nicht genau sagen, aber AFAIK hat jeder Host von Plesk eine eigene vhost.conf und dort kannst du open_basedir eintragen. Bemühe Google einmal ein wenig.
 
Back
Top