2010-03-14 4 views
4

root로 실행해야하는 perl 스크립트가 있지만 스크립트를 실행하는 사용자가 스크립트 중에 제거되므로 'foo'사용자로 로그인하지 않았는지 확인해야합니다.프로세스가 시작된 원래 사용자 이름을 어떻게 알 수 있습니까?

로그인 한 후 수 차례에 걸쳐 su-ed를했을 가능성이있는 사용자가 해당 체인의 'foo'를 가장 한 적이 없는지 어떻게 알 수 있습니까?

다음 두 쉘 스크립트를 호출하는 재미있는 perl 스크립트를 찾았지만 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}\'`; 

이 리눅스와 솔라리스 모두에서 작동 할 필요가 나는 오히려 그에게 호출을 반복 껍질을 제거하고 Perl로 모든 일을 계속 것입니다.

+0

프로세스 테이블 물건이 무섭게 인자를 취하지하고 밖으로 그것을 껍질을 수행하는 CPAN 물건의 대부분이 '어쨌든 ps' 오신 것을 환영합니다 :-)에게 있습니다. 리눅스에서 포격하지 않고 코드를 작성할 수는 있지만 솔라리스 (또는 솔라리스 상자)에서 똑같이 할 수있는 지식이 없습니다. – hobbs

+0

Blarg, Solaris는 멋지고 깔끔하고 발견 가능한'/ proc' 인터페이스는 시스템 헤더 파일에 정의 된 모든 이진 구조입니다. – hobbs

+1

@hobbs : http : //search.cpan.org/~ durist/Proc-ProcessTable-0.45/견고한 것 같습니다. – Hasturkun

답변

0

여기에 직접 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()); 

그러나 당신은 setuid를 변경하기 전에 언제 발생했을 수 있음을 언급 한 이후, 당신은 아마 ps의 출력을 구문 분석 할 수있다 : 나는 그것을 할 것 다음 명령을 사용하십시오. 이 명령은 POSIX에 정의 된 기능을 사용하기 때문에 나는 그것이 시스템의 모든 종류의 휴대용 희망 :

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

어쩌면 다음은 당신이 원하는 것입니다. 함수 hasBeenUser은 프로세스 테이블을 읽은 다음 현재 프로세스의 프로세스 체인을 따라 상위 프로세스까지 진행합니다. 도중에 어떤 프로세스가 user 또는 real user 필드가 해당 사용자 이름과 같은 경우이 함수는 0이 아닌 값을 반환합니다.

 
#! /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

같은 자바 상당 있나요? – Pintu

+0

예, 하위 프로세스를 생성하고 해당 출력을 읽는 작업은 Java에서도 수행 할 수 있습니다. –

+0

같은 예를 들어 주시겠습니까? – Pintu

1

신속하고 더러운 (UNIX 만 해당).

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

who am i 명령은 TTY의 소유자 반환 - 당신이 로그인 할 때이 있었다 즉

당신이 원하는 경우 순수한 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 

이렇게하면 올바른 사용자를 반환합니다. 스와. 이것은 일반적으로 당신의 (경험이 부족한) 시스템 관리자를 놀라게합니다.

0

who am i이 아무 것도 출력하지 않는 mc (적어도 RHEL의 경우)에서 스크립트를 호출 할 때 대소 문자가 구별됩니다.

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}') 

는 기본적으로이 ps -u $USER fh의 트리 출력에 뒤로 산책 한 다음 맨 위의 이름 열에 작물 : 그 회피하기 위해, 나는 떠들썩한 파티에 다음 한 줄을 생산했다.

생각은, 더 나은 솔루션은

관련 문제