How do I know the original username from which the process started?

There is a perl script that should run as root, but we need to make sure that the user who runs the script does not log in as the user 'foo', as it will be deleted during the script.

So, how can I find out if a user who, perhaps several times since he logged in, can not impersonate "foo" at any time in this chain?

I found an interesting perl script that called the following two shell scripts, but I think this will only work on Solaris.

my $shell_parent = `ps -ef | grep -v grep | awk \'{print \$2\" \"\$3}\' | egrep \"^@_\" | awk \'{print \$2}'`; my $parent_owner = `ps -ef | grep -v grep | awk \'{print \$1\" \"\$2}\' | grep @_ | awk \'{print \$1}\'`; 

This should work on both Linux and Solaris, and I would prefer to exclude repeated calls to it in the shell and save all this in Perl.

+4
source share
4 answers

Quick and dirty and (UNIX only):

 my $user = (split /\s/,`who am i`)[0]; 

The who am i command returns the owner of the TTY — that is, who you were when you logged in.

If you want to do this in pure perl:

 use POSIX; my $tty = POSIX::ttyname(1); # The tty we are running in my $uid = (stat $tty)[4]; # The owner uid of that tty my $user = getpwuid($uid); # The user with that uid 

This will return the correct user, even after a few su. This usually exhausts your (less experienced) system administrators.

+1
source

Here's a Perl program that checks for changes to the direct setuid:

  #!  / usr / bin / perl

 sub callingUser () {
     my ($ login, $ pass, $ uid, $ gid) = getpwuid ($ <);
     return $ login;
 }

 sub effectiveUser () {
     my ($ login, $ pass, $ uid, $ gid) = getpwuid ($>);
     return $ login;
 }

 printf ("Real user name:% s \ n", effectiveUser ());
 printf ("Calling user name:% s \ n", callingUser ());

But since you mentioned that a change to setuid could happen anytime sooner, you probably have to parse the output of ps : I would do this using the following command. This command uses only the functions defined in POSIX , so I hope that it is portable for all kinds of systems:

  ps -e -o pid, ppid, user, ruser
0
source

Perhaps the next thing you want. The hasBeenUser function reads the process table and then follows the process chain from the current process down the parent process. If any of the processes on the path has a user or real user field equal to the specified user name, the function returns a nonzero value.

  #!  / usr / bin / perl

 sub hasBeenUser ($) {
         my ($ username) = @_;

         my $ procs = {};
         open (PS, "ps -e -o pid, ppid, user, ruser |") or die;
         while (defined (my $ line = <PS>)) {
                 next unless $ line = ~ m "^ (\ d +) \ s + (\ d +) \ s + (\ S +) \ s + (\ S +) \ s + $";
                 my ($ pid, $ ppid, $ user, $ ruser) = (int ($ 1), int ($ 2), $ 3, $ 4);
                 $ procs -> {$ pid} = [$ pid, $ ppid, $ user, $ ruser];
         }
         close (PS) or die;

         my $ pid = $$;
         while (exists ($ procs -> {$ pid})) {
                 my $ proc = $ procs -> {$ pid};
                 delete $ procs -> {$ pid};  # don't risk ending in an endless loop.
                 warn "D: checking process $ pid \ n";
                 if ($ proc -> [2] eq $ username || $ proc [3] eq $ username) {
                         warn "E: process $ pid was called by $ username. \ n";
                         return 1;
                 }
                 last if $ pid <2;
                 $ pid = $ proc -> [1];
         }
         return 0;
 }

 hasBeenUser ("del");  # should return 0
 hasBeenUser ("root");  # should return nonzero
0
source

I recognized a corner case when calling scripts from mc (at least in our RHEL), which leads to the fact that who am i does not output anything. To get around this, I created the following single-layer layer in bash:

 REALUSERNAME=$(ps uhp `ps -AjH | grep \`ps -u $USER fh | awk '{ print $0; if(index($0, "ps -u $USER fh")) exit 0;}' | tac | awk '{if(!index($0, "\\\\\_")){print $1; exit 0;}}'\` | awk '{print $3}'` | awk '{print $1}') 

Essentially, this goes back to the output of the ps -u $USER fh tree, and then visits the top column of the username.

Thoughts, the best solutions are welcome :-)

0
source

Source: https://habr.com/ru/post/1304058/


All Articles