Sudo

 view release on metacpan or  search on metacpan

lib/Sudo.pm  view on Meta::CPAN

use Term::ReadPassword;
use base qw(Class::Accessor);

use strict;
our $VERSION = '0.33';


sub sudo_run
    {
     # Ok, glue the bits together.  
     my $self = shift;
     my (%ret,$binary,$sudo,$program,$command,$sudo_args,$program_args);
     my ($final_cmd,$sudo_pipe_handle,@cmd,$in,$out,$err,$line);
     my ($username,$remote_machine,$remote_user);

     # <deep sigh>  Ok, IPC::Run is very (I mean very) sensitive to 
     # its @cmd processing.  Each option has to be its own entry
     # in the array.  This means that options that flow in, if they
     # are not of the form -\w but are -\w\s+\S+ (e.g. an option with
     # an option parameter, such as -u username), have to be broken up
     # into their own array elements in @cmd. 
     #
     # Hopefully IPC::Run will be fixed one day.  Until then, we write 
     # to the real API (not the documented one).
     # </deep sigh>

     # do we have a binary ...
     if ($self->{debug})
        {
	  $ENV{IPCRUNDEBUG}='basic';
	  if ($self->{debug} == 2) 
	     {
	       $ENV{IPCRUNDEBUG}='data';	       
	     } 
	  elsif ($self->{debug} >= 3) 
	     {
	       $ENV{IPCRUNDEBUG}='details';	       
	     } 
	}
     if (!defined($self->{sudo}))
        {
	  %ret = (
	          'error' => 'Error: you did not tell me where the sudo binary is was not set'
	         );
	  return \%ret;
	}
	
     $self->{sudo} =~ /^(\S+)$/;    # force binary to be a
     				    # single string with no
				    # spaces.  This may break
				    # some folks paths, but it
				    # should be safer than allowing
				    # any command string.
     $sudo = $1;
     
     # test for remote execution ... you need to have the ssh keys
     # setup before this ...     
     #$remote_machine=$self->{hostname}if (defined($self->{hostname}));
     if (defined($remote_machine))
        {
	  $remote_user	= getpwuid($<);  # default user name is the user running the script
	  if (defined($self->{username}))
	     {
	       $remote_user	= $self->{username};
	     }
	   push @cmd,"ssh";
	   push @cmd, (sprintf '%s@%s',$remote_user,$remote_machine);
	}
     if (!defined($remote_machine))
        {   		    
	 if (! -e $sudo )
            {
	      %ret = (
	              'error' => (sprintf 'Error: the sudo binary "%s" does not exist',$sudo)
	             );
	      return \%ret;
	    }

	 if (! -x $sudo )
            {
	      %ret = (
	              'error' => (sprintf 'Error: the sudo binary "%s" is not executable',$sudo)
	             );
	      return \%ret;
	    }
	}
     push @cmd,$sudo;

     # force the -S switch to take the password from 
     # STDIN
     push @cmd,'-S';
     
     if (!exists($self->{_timeout})) { $self->{_timeout} = 10; }
     
     $program_args	= "";     
     
     # ok, append the user information
     if (!defined($self->{username}))
        {
	  %ret = (
	          'error' => 'Error:  username was not set'
	         );
	  return \%ret;
	}
     
     if (exists	($self->{sudo_args}))
        {
	  # process the arguments, splitting on white space
	  $self->{sudo_args} =~ s/^\s+//;  # trim leading spaces
	  $self->{sudo_args} =~ s/\s+$//;  # trim trailing spaces
	  push @cmd,(split(/\s+/,$self->{sudo_args})); 	
	}
	
     push @cmd,"-u";
     push @cmd,$self->{username};

     if (!defined($self->{program}))
        {
	  %ret = (
	          'error' => 'Error: the program attribute was not set'
	         );



( run in 1.720 second using v1.01-cache-2.11-cpan-39bf76dae61 )