Home > Software engineering >  How to jump between users, including root, in a perlscript?
How to jump between users, including root, in a perlscript?

Time:11-12

This question has been asked here in multiple forms. I am asking it again because all these questions had too many details. Hence the answers all boiled down to how to solve those specific problems without jumping between users.
This I why am posting this as a new question (and immediately answering it below) for others that have this problem.

Suppose you have a perl script that you run as root where you first want to run things as root, then things as a regular user and then as root again.

For example:

#!/usr/bin/perl
#Problem 1: Make sure to start as root
system("whoami");
#Problem 2: Become your regular user
system("whoami");
#Problem 3: Become root again
system("whoami);

should be changed to show:

root
your_username
root

CodePudding user response:

This the best solution I can think of.

If you want to start as root, become a regular user and become root again:

#!/usr/bin/perl
use POSIX qw/setuid waitpid/;
exec("sudo", $0, @ARGV) unless($< == 0);  #Restart the program as root if you are a regular user
system("whoami");
my $pid = fork;  #create a extra copy of the program
if($pid == 0) {
  #This block will contain code that should run as a regular user
  setuid(1000);  #So switch to that user (e.g. the one with UID 1000)
  system("whoami");
  exit;  #make sure the child stops running once the task for the regular user are done
}
#Everything after this will run in the parent where we are still root
waitpid($pid, 0); #wait until the code of the child has finished
system("whoami");

When starting as a regular user it's best to make sure that the parent stays a regular user and the child becomes root. You can do this like this:

#!/usr/bin/perl
use POSIX qw/setuid waitpid/;
unless($< == 0) {
  #regular user code, this is the first code that will run
  system("whoami");
  #now fork, let the child become root and let the parent wait for the child
  my $pid = fork;
  exec("sudo", $0, @ARGV) if($pid == 0);
  waitpid($pid, 0);
  #continue with regular user code, this is the 3th part that will run
  system("whoami");
  exit; #the end of the program has been reached, exit or we would continue with code meant for root
}
#code for root, this is the 2nd part that will run
system("whoami");
  
  
  • Related