#!${PERLPATH} #$Id: sudoshell-in,v 1.9 2004/11/22 16:09:05 hbo Exp $ use Fcntl qw(O_RDWR O_WRONLY); use POSIX qw(pause); use strict; use warnings; use Getopt::Long; use lib ${SSLIBDIR}; use Sudoscript; my $ss=Sudoscript->new(); exit if (! defined $ss); my ($user,$newenv); GetOptions( "user:s" => \$user, "" => \$newenv, ); my $GREP = $ss->GREP(); my $SUDO=$ss->SUDO(); my $PS=$ss->PS(); my $SCRIPT=$ss->SCRIPT(); my $INITSCR=$ss->INITSCR(); # Check to see if sudoscriptd is running. Offer to start it if not $ss->check_ssd(); # Get our current ID's pwent my ($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell,$expire) =getpwuid($>) or die "no passwd entry for current user: $>\n"; # Check our -u parameter. if ($user){ # Get the UID of the -u user and compare it to ours. ($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell,$expire) =getpwnam($user) or die "no passwd entry for user: $user\n"; if ($uid != $>){ # We have not become the requested user yet # Call sudo to give us the right identity. my $reexec="$SUDO -u $user $0 -u $user"; $reexec .= " -" if ($newenv); exec $reexec; } # Otherwise, check if we are root. } elsif ($>){ # No -u and not run as root. Try sudo my $reexec= "$SUDO $0"; $reexec .= " -" if ($newenv); exec $reexec; } # We are either root or the -u user here forward # Check the user's shell $shell=$ENV{SHELL} if ($ENV{SHELL}); # Environment overrides pwent (obtained above) # Don't take their word for it. # Get the list of shells in /etc/shells and turn them into a single regular expression open SHELLS, "/etc/shells" or die "Can't open /etc/shells $!\n"; my $shellsre=join "|", map {chomp;s~/~\\\/~g;$_} (); close SHELLS; if ($shell!~/$shellsre/){ print "Your shell ($shell) isn't in /etc/shells! Exiting.\n"; exit; } # Get the name we came from, if available. # (SUDO_UID could be blank, if root ran us to start with. In that # case we get the name from the first getpwuid above.) ($name) = getpwuid $ENV{SUDO_UID} if ($ENV{SUDO_UID}); # Implement the "-" parameter. if ($newenv){ my ($n,$p,$u,$g,$q,$c,$gc,$home,$sh) = getpwuid $>; $ENV{HOME} = $home if ($home); $ENV{SHELL}= $sh if ($sh and $sh =~ /$shellsre/); } # Open the master daemon's front-end FIFO if it exists # (This is why we need rwx perms for group to $fifodir.) my $rundir="/var/run/sudoscript"; my $fifo="$rundir/rendezvous"; if (-p $fifo){ sysopen (FIFO,$fifo,O_WRONLY) or die $!; # Unbuffer it my $stdout=select FIFO; $|=1; select $stdout; $SIG{WINCH}=sub{return}; # Logger will signal us # Our handshake with sudoscriptd will differ based on whether we are running as # root or an unprivileged user. my $handshake; if ($user){ $handshake="$name $$ $user\n"; # $name is SUDO_USER or root. $user is non-root user we have become } else { $handshake="$name $$\n"; } # Say HELO to sudoscriptd print FIFO "HELO $handshake\n"; # Wait for the logger to be ready pause; # We have been awakened, prepare to script(1) to the new FIFO # close te old FIFO first close FIFO; # Session FIFO name differs based on whether we are running as # root or an unprivileged user. my $fifo2; if ($user){ $fifo2=$rundir."/ssd.${name}_${user}_$$/$name$$.fifo"; } else { $fifo2=$rundir."/ssd.${name}_root_$$/$name$$.fifo"; } # Here we go my $script=$ss->SCRIPT(); system "$script $fifo2"; # script(1) session has finished # Reopen the old fifo to let the master know we are done. sysopen (FIFO,$fifo,O_WRONLY) or die $!; # Say GDBY, dick print FIFO "GDBY $handshake\n"; close FIFO; # all done. exit; } else { # Problem with the FIFO. (no -p $fifo) print "The logging FIFO doesn't exist. Can't run shell!\n"; } =pod =head1 NAME sudoshell, ss - Run a shell with logging =head1 SYNOPSIS sudoshell|ss [-] [-u|--user I] =head1 VERSION This manpage documents version ${VERSION} of sudoshell. =head1 DESCRIPTION I runs the I