Calling fswebcam through apache / python script - python

I am running the following command in my python script:
res = subprocess.Popen(["fswebcam", "-r 640x480", "grab.jpeg"], shell=False, stdout=subprocess.PIPE, cwd="/var/www/pics");
output = res.communicate()[0];
which runs fine when calling the script manually.
But when running the script through apache, I get no error message but no image appears in the /var/www/pics directory. This directory as been assigned to www-data:www-data and has the write permissions.
I don't understand what I am missing to get this working.

Finally found the issue, the www-data user was not allowed to run fswebcam, so I added a coniguration file in the /etc/sudoers.d directory to allow access to fswebcam by user www-data.
Here is the content of my file:
Defaults:www-data !requiretty
%www-data ALL = NOPASSWD: /usr/bin/fswebcam
I also had to modify the call to fswebcam in my python script by adding "sudo" as begginning of the command.
res = subprocess.Popen(["sudo", "fswebcam", "-r 640x480", "grab.jpeg"], shell=False, stdout=subprocess.PIPE, cwd="/var/www/pics");

Related

How to run an exe file for silent install using Admin privileges

I am trying to write a python script which would install a printer software on my machine using silent install.
The script is something like this and I run the script in a command line run as Admin-
cmd = 'PDFCreator-5_0_3-Setup.exe /COMPONENTS="program" /VERYSILENT /NORESTART'
response = subprocess.call(cmd, shell=True)
print('response:', response)
However, I would like to run this as an admin inside the script itself(as my script runs automatically as part of my code), but could not find a way yet. Help is much appreciated.
I have tried using the runAs option with Powershell, but when I use the above command with the Start-Process, I m getting syntax errors:
cmd_to_install = "& { Start-Process "pathofthefile+\PDFCreator-5_0_3-Setup.exe" -ArgumentList #("/COMPONENTS="program" /VERYSILENT /NORESTART") -Verb RunAs}"

Calling Matlab scripts from Django with Python's Popen class

I'm developing a Django app which runs Matlab scripts with Python's Popen class. The python script that calls Matlab scripts lives in the main folder of my Django app (with views.py). When I call the script from command line, it runs like a charm but when I make a request from the client in order to run the corresponding python script, I receive the following warning:
"< M A T L A B (R) > Copyright 1984-2018 The MathWorks, Inc. R2018a (9.4.0.813654) 64-bit (glnxa64) February 23, 2018 To get started, type one of these: helpwin, helpdesk, or demo. For product information, visit www.mathworks.com. >> [Warning: Unable to create preferences folder in /var/www/.matlab/R2018a. Preferences folder location must be writable. Using a temporary preferences folder for this MATLAB session. See the preferences documentation for more details.] >>
My app uses a Python virtual environment and it is being deployed with Apache web server.
Here is my python script that calls Matlab scripts:
import os
import subprocess as sp
import pymat_config
def pymat_run():
pwd = pymat_config.pwd_config['pwd']
cmd1 = "-r \"Arg_in = '/path/to/my/main/folder/input.txt'; Arg_out = '/path/to/my/main/folder/file.txt'; matlab_script1\""
baseCmd1 = ['/usr/local/MATLAB/R2018a/bin/matlab', '-nodesktop', '-nosplash', '-nodisplay', 'nojvm', cmd1]
os.chdir('/path/to/matlab_script1')
sudo_cmd = sp.Popen(['echo', pwd], stdout=sp.PIPE)
exec1 = sp.Popen(['sudo', '-S'] + baseCmd1, stdin=sudo_cmd.stdout, stdout=sp.PIPE, stderr=sp.PIPE)
out, err = exec1.communicate()
return out
Any suggestions ?
Finally I managed to find the solution of that issue by myself. The problem came from the kind of user who called the Matlab's script. When I was running the above script from a Python interpreter or from the shell, it was the user (with the user password) who was running the script while when I was calling the script from the client the user was the web server's user: www-data.
So at first to avoid the above warning I gave permissions to www-data user to the /var/www folder with the following command:
sudo chown -R www-data /var/www/
After that, the "Warning" disappeared but the script still didn't run because it was asking for www-data's password internally and taking user's password from pymat_config file.
To solve this, I edited /etc/sudoers file in order for www-data to be able to call Matlab scripts without asking password. So I added the following line:
www-data ALL=(ALL) NOPASSWD: /usr/local/MATLAB/R2018a/bin/matlab
and now it runs like a charm !

Python Popen: pass environment variable to command running as another user with sudo

The subprocess.Popen() function has a "env" parameter. But it doesn't seem to have the desired effect with sudo. This is what I get when I do this in the interactive Python shell:
import subprocess
env={"CVS_RSH":"ssh"}
command = "sudo -u user cvs -d user#1.8.7.2:/usr/local/ncvs co file.py"
p = subprocess.Popen(command, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,env=env,shell=True)
(command_output, error_output) = p.communicate()
p.wait()
1
>>> error_output
b'cvs [checkout aborted]: cannot exec rsh: No such file or
directory\ncvs [checkout aborted]: end of file from server (consult
above messages if any)\n'
The message is distracting, so let me explain. I'm forced to use ancient CVS and the environment variable tells it to use ssh to connect to the server, rather than the default which sadly is rsh. It also needs an environment variable called CVS_ROOT, but fortunately there's a "-d" option for that, but none for the CVS_RSH that I know of.
Interestingly enough, if I do:
command = "sudo -u user echo $CVS_RSH"
env={"CVS_RSH":"something_else"}
p = subprocess.Popen(command, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,env=env,shell=True)
(command_output, error_output) = p.communicate()
p.wait()
0
>>> command_output
b'something_else\n'
Maybe this worked because echo wasn't actually started as a child process? Is it possible to pass an environment to a process executed as another user with sudo?
This doesn't seem possible using the env parameter. The solution seems to be to just pass the environment as I was doing on the shell, for example:
command = "sudo -u user CVS_RSH=ssh
CVSROOT=:ext:user#2.8.7.2:/usr/local/ncvs cvs co dir/file.py"
p = subprocess.Popen(command, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,env=env,shell=True)
The weird thing is, if I do this in a Python CGI script, I can see:
cvs [checkout aborted]: cannot exec ssh: Permission denied
cvs [checkout aborted]: end of file from server (consult above messages if
any)
But if I try on the interactive Python shell, it goes past this, so it must be another weird (because the user has permission to ssh) issue, unrelated to this question.

Python subprocess sudo returns error: ERROR: ['sudo: sorry, you must have a tty to run sudo\n']

Here is my code:
import subprocess
HOST = 'host_name'
PORT = '111'
USER = 'user_name'
CMD = 'sudo su - ec2-user; ls'
process = subprocess.Popen(['ssh','{}#{}'.format(USER, HOST),
'-p', PORT, CMD],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result = process.stdout.readlines()
if not result:
print "Im an error"
err = process.stderr.readlines()
print('ERROR: {}'.format(err))
else:
print "I'm a success"
print(result)
When I run this I receive the following output in my terminal:
dredbounds-computer: documents$ python terminal_test.py
Im an error
ERROR: ['sudo: sorry, you must have a tty to run sudo\n']
I've tried multiple things but I keep getting that error "sudo: sorry, you must have a tty to run sudo". It works fine if I just do it through the terminal manually, but I need to automate this. I read that a workaround might be to use '-t' or '-tt' in my ssh call, but I haven't been able to implement this successfully in subprocess yet (terminal just hangs for me). Anyone know how I can fix my code, or work around this issue? Ideally I'd like to ssh, then switch to the sudo user, and then run a file from there (I just put ls for testing purposes).
sudo is prompting you for a password, but it needs a terminal to do that. Passing -t or -tt provides a terminal for the remote command to run in, but now it is waiting for you to enter a password.
process = subprocess.Popen(['ssh','-tt', '{}#{}'.format(USER, HOST),
'-p', PORT, CMD],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
process.stdin.write("password\r\n")
Keep in mind, though, that the ls doesn't run until after the shell started by su exits. You should either log into the machine as ec2-user directly (if possible), or just use sudo to run whatever command you want without going through su first.
You can tell sudo to work without requiring a password. Just add this to /etc/sudoers on the remote server host_name.
user ALL = (ec2-user) NOPASSWD: ls
This allows the user named user to execute the command ls as ec2-user without entering a password.
This assumes you change your command to look like this, which seems more reasonable to me:
CMD = 'sudo -u ec2-user ls'

Running sudo command via CGI (Python)

I am writing a test suite for a web application using Selenium.
In the course of which I need to test behaviour of the app in case a certain service is running or not.
I wanted to create a cgi call to a Python script turning that service on and off.
I know that the cgi call is in the context of the webserver (Apache) however thought that issuing sudo calls like so:
import subprocess
import os
command = 'sudo -S launchctl unload /Library/LaunchAgents/com.my.daemon.plist'
pwd = 'pwd123'
test1 = subprocess.Popen( command, shell=True, stdin=subprocess.PIPE)
test1.communicate(input=pwd)
test2 = os.system( 'echo %s|%s' % (pwd,command) )
would do the trick, well they don't I get return code 256.
What can I do to have this call be executed w/o touching the context in which Apache runs?
As for security: this will only run on a test machine.
The user that Apache runs as needs to be in the /etc/sudoers file, or belong to the sudo group, which I guess it usually doesn't. You also need to make it not ask for a password, which is configured in /etc/sudoers
For Ubuntu, check these out: https://askubuntu.com/questions/7477/how-can-i-add-a-new-user-as-sudoer-using-the-command-line
https://askubuntu.com/questions/147241/execute-sudo-without-password
It could potentially be a pathing issue..
Have you tried writing out the full path like this:
command = '/usr/bin/sudo -S launchctl unload /Library/LaunchAgents/com.my.daemon.plist'
command should be a list, not a string. Try with:
command = ['sudo', '-S', 'launchctl', 'unload', '/Library/LaunchAgents/com.my.daemon.plist']
Cant run sudo this way -- sudo needs a controlling terminal to run.

Categories

Resources