3
votes

I'm trying to execute a python script using the exec() function of PHP.

The .php page is loaded over a browser:

<?php
 echo exec("whoami");

echo(exec("/bin/python2.7 /var/www/cgi-bin/api/download.py"));
?>

Here is the python script :

# -*- encoding: UTF-8 -*-

import os
import httplib2
import io
import sys
from httplib2 import Http
from oauth2client import client
from oauth2client import tools
from apiclient import discovery
from oauth2client.file import Storage
from apiclient.discovery import build
from oauth2client.client import OAuth2WebServerFlow
from apiclient.http import MediaIoBaseDownload
from oauth2client.service_account import ServiceAccountCredentials

scopes = ['https://www.googleapis.com/auth/drive']

credentials = ServiceAccountCredentials.from_json_keyfile_name('/opt/scripts/full-patator-preprod.json', scopes)

delegated_credentials = credentials.create_delegated('#############')
http_auth = delegated_credentials.authorize(Http())

drive_service = build('drive', 'v2', http=http_auth)


def get_file(service,fileId):
    file = service.files().get(fileId=fileId).execute(http=http_auth);
    return file




item = get_file(drive_service,"#############")

print(item.get('title'))
delegated_credentials = credentials.create_delegated("#############")
http_auth = delegated_credentials.authorize(Http())


request = drive_service.files().export_media(fileId="#############", mimeType='application/pdf')

fh = io.FileIO("api/test.pdf","wb")
downloader = MediaIoBaseDownload(fh, request)
done = False

counter=0;
while done is False:
    status, done = downloader.next_chunk()
    print "Download %d%%." % int(status.progress() * 100)
    counter+=1
    if counter > 10:
        done=True
with open("test.pdf") as f: ## PDF File
    print(type(f))           ## Open file is TextIOWrapper
    bw=io.TextIOWrapper(fh)   ## Conversion to TextIOWrapper
    print(type(bw))          ## Just to confirm

Everything works if execute the .py or the .php as Apache user. But using my browser, when it comes to write file:

fh = io.FileIO("api/test.pdf","wb")

I have this output in my apache error_log:

Traceback (most recent call last): File "/var/www/cgi-bin/api/download.py", line 46, in fh = io.FileIO("test.pdf","wb") IOError: [Errno 13] Permission denied: 'test.pdf'

Well, i was pretty sure that it was due to the permission of the parent folder, then the permission of the parent of the parent. But i set a 777 permission to these folders and it did nothing.

My php script is in /var/www/html/manager/execute.php My .py script is in /var/www/cgi-bin/api/download.py

folders /www/, /cgi-bin/, /api/ has 777 rights.

I know it's not a good practice but i would like to solve the issue before doing something cleaner.

Thanks in advance

1
If you call a php-file over an browser you will be the user www-data. And normaly www-data has/shouldnot have much rights on command line. - JustOnUnderMillions
Who does the PHP script run as? Does that user/group have permissions to run the Python script? - Jay Blanchard
Hello, i can assume that php runs as apache user because when i execute : shell_exec("whoami"); it returns me "apache" And of course, apache is the owner of the .py file - Adrien QUINT
Get file and open file methods, i am confused cos which server allow change opening methods, got large combinations. Read chunk from source but how to declare system and network limits ? Download file to ram and reserving it. Permission on reading source not same target file permission. - dsgdfg
dsgdfg, The get file method is declared just above, and is using Google Python SDK to get files from Google Drive. As i said, the script works well when ran as root or apache in cli. But blocked when calling the .php with the browser. The only target is test.pdf - Adrien QUINT

1 Answers