I have developed a perl script which provides a menu driven functionality to allow users to carry out some simple tasks.
I need the users to be able to carry out tasks such as copying files (keeping the current date and permissions), running other programs (such as less or vi) as a different user. The script uses alot of use of the system() function. I want the users to start the menu by calling:
sudo -u perluser /usr/bin/perl /data/perlscripts/scripta.pl
This should start the script as perl user, which it does, and then carry out different tasks depending on what the user selects. The problem is that whenever I use a system call such as
system("clear");
I get the following error
Can't exec "clear": Permission denied at /data/perlscripts/scripta.pl line 3
If I run the script by logging in as perluser then it all runs succesfully.
Is there any way to get this working? I do not want users to be able to log in as perluser as I need to control what they are able to run. I also do not want to run a command like
system("sudo -u perluser clear");
as I would then require a different team to set up all the sudo commands I wanted to run (which they will probably refuse to do) and this would not be scalable if I have to add extra commands at somepoint.
Thanks,
I think you probably need to add the -i
option ("simulate initial login") to sudo
:
sudo -i -u perluser /usr/bin/perl /data/perlscripts/scripta.pl
That will ensure that .profile
or .login
or whatnot is run properly, and therefore that $PATH
is set up properly and so on. It will really be, in almost all respects, as if perluser
were actually logging in and running /usr/bin/perl /data/perlscripts/scripta.pl
at the shell.
I know that this is a slightly different approach, but couldn't you set perluser
's shell to /data/perlscripts/scripta.pl
? This would avoid the headaches usually associated with sudo
configuration if you have multiple machines. The end user would simply use login perluser
instead of sudo
. When you script exits, the login session will go away. No need to provide any more of a jail than this right?
Alternate (and maybe correct) Answer
I think that the root of the problem is that Perl's exec
does not use a shell in most cases. This means that "clear"
is meaningless since the shell is what implements searching through $PATH
to find the command. Here is the relevant perldoc
from system
. Note the emphasis.
o system LIST
o system PROGRAM LIST
Does exactly the same thing as exec LIST, except that a fork is done first and the parent process waits for the child process to exit. Note that argument processing varies depending on the number of arguments. If there is more than one argument in LIST
, or if LIST
is an array with more than one value, starts the program given by the first element of the list with arguments given by the rest of the list. If there is only one scalar argument, the argument is checked for shell metacharacters, and if there are any, the entire argument is passed to the system's command shell for parsing (this is /bin/sh -c
on Unix platforms, but varies on other platforms). If there are no shell metacharacters in the argument, it is split into words and passed directly to execvp , which is more efficient.
Try changing system("clear")
to either system("/usr/bin/clear")
or system("clear;")
.