Execute a command as root in Cpanel plugin build with Perl - perl

I am new to Perl. I'm building a plugin for Cpanel to install SSL certificates when the user clicks an option.
I have to execute a command as root inside the Perl code. How can I do this?

So basically you need to run a system command as root user from within a Perl script.
You can use the system built-in function with a sudo inside it. This will fork a new process where the command will be executed while the parent process waits, and then return the exit status of that command.
For example, this basic command switches to root and prints the current user :
perl -e 'system("sudo su -c whoami")'
Obiously, it outputs this on the standard output :
root
Notes :
for this to work, you need you application user to be able to switch to root(without the need of typing a password) ; some could consider that a security breach (some attacker that would have taken over your application would be able to cause fatal damage to your system)
the actual command to switch to the root user might vary depending on your OS ; the one I used in the example you is for RedHat
I searched the CPAN for modules that provide the "switch to root" functionality and the only one I found is Sudo ; I didn't try it, but it that was not updated since 2013 and has few issues pendings since 3 to 9 years

Related

.sh script that executes command as "real" root

I want to write a .sh-script that sends a message to my ejabberd-account. (the script is "called" by the apache2 standard-user "www-data").
The script should execute the following command: ejabberdctl send_message chat admin#my-domain user#my-domain "title" "my message"
However, I can't run any ejabberdctl command without "being" root. So sudo ejabberdctl is not working (in terminal or any .sh-script). I can only do sudo -s followed by ejabberdctl my-command, which doesn't work in .sh-scripts (or am I wrong?).
(I've installed ejabberd 20.07 on ubuntu 20.04 with the help of this tutorial: Install Ejabberd...)
Is there a way to run a command in a .sh-script as "real root" or to create a root-session and run the command there (like I do manually with sudo -s ...)?
Is there any solution to my problem or should I install ejabberd the "normal way"?
When ejabberd is compiled and installed from source code, it's possible to prepare it with something like
./configure -–enable-group=ejagroup
Then, you can simply create the system group ejagroup, and add the www-data user to that ejagroup.
See https://docs.ejabberd.im/admin/installation/#options
In your case, that you use the Debian package from ProcessOne, I see the tutorial mentions that you create a system account called ejabberd. Maybe you can run ejabberdctl from that account, no need to be root?
I still don't know why I can only run ejabberdctl when I'm "logged-in" as root (sudo ejabberdctl is still not working)
Is my .bashrc file wrong? (last line: PATH=$PATH:/opt/ejabberd-20.07/bin/)
Anyway, at least I can run sudo /opt/ejabberd-20.07/bin/ejabberdctl my_command with any user, like they did here: Ejabberd sbin/ejabberdctl start (No such file or directory)
Has someone else experienced this weird behavior with sudo: any_command: not found ?
Let me know if you have a more "elegant" solution to my problem.

Continue/run commands after ssh into VM

I have to take quite a few steps before I get into the file I need to be, which is why I'm trying to set up an alias in my terminal, that gets me to the file by running that alias.
The following steps are needed to arrive where I have to be:
cd Sites
vagrant ssh
cd /var/www/miniportal.billetten.dk/logs/
sudo -s
cd /etc/apache2/sites-available/
nano 25-av_miniportal.conf
Edit line 33 in that file (I guess it's possible to jump to that line)
I tried setting up an alias like this, but the problem is that it stops running the rest of the command after I SSH'd into Vagrant. if I manually exit Vagrant, it continues the command (and of course returns an error, because there is no such folder).
The question is: How do I make sure that everything from step 3 is executed AFTER step 2 is done logging in through SSH?
My ultimate goal is to set up an Apple Automator program that lets me put in a value that gets entered on line 33, but I'm fine with just an alias for now.
I know I asked this question a long time ago, but in the meantime I found a solution and forgot I had posted this question.
My alias in my .zshrc-file looks like this:
alias changeCust='ssh -t root#192.168.56.101 "nano +32 /etc/apache2/sites-enabled/25-av_miniportal.conf && service apache2 reload"'
In other words, it SSHs into vagrant as root (it asks for my password), nanos into a file on line 32 (or whatever line you need), then, when the file is saved, it reloads apache2 and the changes are applied.
Just use the below one and change the values.
alias AliasName='ssh -t root#your.ip.addres.here "nano +lineNumber /path/to/file"'

Can I setuid a perl script?

I made a perl script to change owner of a file owned by some other user. Script is complete. My administrator save that in /sbin directory and set uid for it using chmod u+s name_of_script. But when I run this script it gives me error that chown operation is not permitted. I made a C program and it works by following same steps. So my question is if setuid is working for perl then I should not get that error because C code did not give me any error. So can i setuid for perl script or I should go with c code.
Don't tell me to ask administrator to change owner each time. Actually in server I have user name staging and I am hosting a joomla site in it. Now when I install some plugin then files related to that plugin are owned by www-data. So that's why I do not want to go to admin each time. Or you can give me some other solution also regarding my problem.
Many unix systems (probably most modern ones) ignore the suid bit on interpreter scripts, as it opens up too many security holes.
However, if you are using perl < 5.12.0, you can run perl scripts with setuid set, and they will run as root. How it works is that when the normal perl interpreter runs, and detects that the file you are trying to execute has the setuid bit set, and it then executes a program called suidperl. Suidperl takes care of elevating the user's privileges, and starting up the perl interpreter in a super-secure mode. suidperl is itself running with setuid root.
One of the consequences of this is that taint mode is turned on automatically. Other additional checks are also performed. You will probably see messages like:
Insecure $ENV{PATH} while running setuid at ./foobar.pl line 3.
perlsec provides some good information about securing such scripts.
suidperl is often not installed by default. You may have to install it via a separate package. If it is not installed then you get this message:
Can't do setuid (cannot exec sperl)
Having said all of that - you would be much better off using sudo to execute actions with elevated privileges. It is much more secure as you can specify exactly what is allowed to be executed via the sudoers file.
As of perl 5.12.0, suidperl was dropped. As a result, if you want to run a perl script on perl >= 5.12.0 with setuid set, you would have to write your own C wrapper. Again I recommend sudo as a better alternative.
No, you cannot use setuid aka chmod +s on scripts. The script's interpreter would be the thing that would actually need to be setuid, but doing that is a really bad idea. REALLY bad.
If you absolutely must have something written in Perl as setuid, the typical thing to do would be to make a small C wrapper that is setuid and executes the Perl script after starting. This gives you the best of both worlds in having a small and limited setuid script but still have a scripting language available to do the work.
If you have a sudo configuration that allows it (as most desktop linux distributions do for normal users), you can start your perl script with this line:
#!/usr/bin/env -S -i MYVAR=foo sudo --preserve-env perl -w -T
Then in your script before you use system() or backticks explicitly set your $ENV{PATH} (to de-taint it):
$ENV{PATH} = '/usr/bin';
Other environment variable that your script explicitly mentions or that get implicitly used by perl itself will have to be similarly de-tainted (see man perlsec).
This will probably (again depending on your exact sudo configuration) get you to the point where you only have to type in your root password once (per terminal) to run the script.
To avoid having to type your password at all you can add a line like this to the bottom of /etc/sudoers:
myusername ALL=(ALL) NOPASSWD:ALL
Of course you'd want to be careful with this on a multi-user system.
The -S options to env splits the string into separate arguments (making it possible to use options and combinations of programs like sudo/perl with the shebang mechanism). You can use -vS instead to see what it's doing.
The -i option to env clears the environment entirely.
MYVAR=foo introduces an environment variable definition.
The --preserve-env option to sudo will preserve MYVAR and others.
sudo sets up a minimal environment for you when it finds e.g. PATH to be missing.
The -i option to env and --preserve-env option to sudo may both be omitted and you'll probably end up with a slightly more extensive list of variables from your original environment including some X-related ones (presumably the ones the sudo configuration considers safe). --preserve-env without -i will end up passing along your entire unsanitized environment.
The -w and -T options to perl are generally advisable for scripts running as root.

install CPAN module

I have a problem when i want to install perl module
I make " cpan" to install cpan , but i get this "
Terminal does not support AddHistory.
Your configuration suggests that CPAN.pm should use a working
directory of
/home/cyrine/.cpan
Unfortunately we could not create the lock file
/home/cyrine/.cpan/.lock
due to permission problems.
Please make sure that the configuration variable
$CPAN::Config->{cpan_home}
points to a directory where you can write a .lock file. You can set
this variable in either a CPAN/MyConfig.pm or a CPAN/Config.pm in your
#INC path;
You don't seem to have a user configuration (MyConfig.pm) yet.
i make "y"
then i got this strange message :
mkdir /home/cyrine/.cpan/CPAN: Permission denied at /usr/share/perl/5.10/CPAN/Shell.pm >line 656
Any idea please?
Thank you
The immediate cause of this problem is that you don't have write permissions on /home/cyrine/.cpan. In my experience, this is most often the result of logging in as a normal user, then running cpan for the first time on that account in a su session, causing the CPAN configuration to be created in ~cyrine (because you have cyrine's environment), but owned by root (because su has given you root's permissions). Assuming that is the case, you should be able to resolve this my suing to root, running the command chown -R cyrine.cyrine /home/cyrine/.cpan and then running cpan as user cyrine.

How to open Perl file handle to write data via sudo (or as another user)

I'd like to write data to a file, but the file handle should be opened with access permissions for a specific user.
Thus, the following statement:
open (FH, "> $filename") or die "$#\n";
would allow writing to a file as that particular user.
Is there a way to do this within a Perl script, without the entire script being run with sudo -u $username?
There are two established ways. Stackers, you are invited to edit this answer to fill in the drawbacks for each.
Run the program with sudo. The first thing you do in the program is to open the files you need and keep the handles, and then immediately afterwards drop the root privileges. Any further processing must take place with low privileges. The Apache httpd works likes this, it opens the log files as root, but continues running as nobody or similar.
If you don't like that way, run the program normally, and when you need to elevate, create a new process and have it run with a user configured sudo, su -, kdesu/gksu or whatnot. The CPAN client works likes this, it fetches, unpacks, builds and tests a module as a normal user, but calls sudo make install etc. when it's time to install.
An alternative to daxim's suggestions is to have the script owned by the specific user and have the script permissions include the setuid and/or setgid bits.