Доступ к файлу в PHP через символическую ссылку от пользователя, у которого обычно нет прав

Доступ к файлу в PHP через символическую ссылку от пользователя, у которого обычно нет прав

У меня есть этот веб-сайт, где если пользователь отправляет форму, скрипт python выполняется через страницу php, а скрипт python создает zip-файл и должен предложить его пользователю для загрузки по ссылке. Файл может быть огромным (несколько ГБ).

Поскольку я работаю на университетском сервере, я строго привязан к их серверным правилам и возможностям. Вот в чем проблема:

Веб-сайт хранится в /data/mywebsite, который имеет ограниченное дисковое пространство. Конечно, он принадлежит , www-dataпоскольку в основном он доступен через мой сервер Apache.

Мне предлагают 1 ТБ хранилища в /experimentdata/, которое ДОСТУПНО ТОЛЬКО одному конкретному пользователю, скажем theuser. Это потому, что эта папка является монтированием samba, к которому может получить доступ один и конкретный идентификатор пользователя.

Чтобы создать файл в /experimentdata, я использую sudo -u theuserкоманду, которая создаст файл /experimentdata/downloadme.zipкак пользователь theuser. Теперь моя проблема: как я могу предложить этот файл по ссылке для загрузки через Apache?

Я думал об использовании символической ссылки, которую я вставляю, например, /data/mywebsite/download/downloadme.zip. Проблема в том, что у пользователя www-dataнет абсолютно никаких прав на чтение файла!

Как я могу разрешить пользователю загружать файл /experimentdata/downloadme.zipс помощью пользователя www-dataчерез пользователя theuser?

Я хотел бы прямо сказать, что вовлечение sudo -u theuserабсолютно нормально. Но я не знаю, как сделать ссылку из этого куда-то за пределами папки моего веб-сайта.

PS: Если вам нужна дополнительная информация, пожалуйста, спрашивайте.

решение1

Я думаю, что нужно сделать так, чтобы ваш php/ pythonвозвращал данные напрямую вместо apache. Ваш код может делать то же самое, что apacheи . По моему опыту, это намного лучше, чем открывать другой каталог и/или использовать sudo, или менять права доступа к файлам для apacheи т. д.

Если программа создает большой файл быстрее, чем интернет-соединение, то вы можете передавать данные напрямую из своей программы, что устраняет необходимость в дополнительном файле данных, коде для управления им и механизмах его запоминания.

Этот ответ на Stack Overflow показывает, как работает код в php.https://stackoverflow.com/a/4357904/5484716.

Для программ, которые будут вызываться таким образом, исключите весь stderrпотоковый вывод и убедитесь, что код возврата из вашего процесса Python точно отражает успешность или неудачу процесса.

В примерах ниже показаны popen()вызовы, которые вы могли бы использовать в приведенном выше примере сценария из stackoverflow. Я добавил exec 2>/dev/null;к команде shell. Это гарантирует, что никакой вывод не попадет в stdandard error, даже из самой оболочки, поскольку наличие данных, поступающих как на , так и на , stderrможет stdoutстать источником взаимоблокировок с popen().

Если вы хотите загрузить файл диска своему пользователю:

$fp = popen('exec 2>/dev/null; sudo -u theuser cat yourfile.zip', 'r');

Если вы хотите загрузить данные из активного процесса:

$fp = popen('exec 2>/dev/null; sudo yourpythonscript arg argN', 'r');

Эти командные строкиявляютсяКоманды оболочки и метасимволы оболочки должны быть заключены в кавычки соответствующим образом.

Во втором методе сервер начнет отправлять данные немедленно. Когда пользователь успешно отправит форму, он немедленно увидит диалоговое окно «сохранить как» в своем браузере. Как только пользователь выберет выходной файл, ваш phpскрипт передаст данные напрямую по проводам в удаленный файл.

Скрипт pythonдолжен вывеститолькоданные zip на стандартном выводе и возвращают код выхода, который точно отражает успех или неудачу процесса zip. В pythonскрипте следует записать вывод на sys.stdout, например zf = ZipFile(sys.stdout, ....

Крайне важно вызвать pclose()и проверить возвращаемое значение., потому что это будет единственный способ узнать, был ли zip успешным или нет. Если pclose()возвращается что-то, кроме 0, что-то не так.

То, как файл обрабатывается клиентом, зависит от настроек этих response headersи других параметров: content-type:, content-encoding:, и content-disposition: См.:http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html, посмотрите на response-headerи entity-headerинформацию.

Связанный контент