Annotation of embedaddon/rsync/support/lsh, revision 1.1.1.2

1.1.1.2 ! misho       1: #!/usr/bin/perl
1.1       misho       2: # This script can be used as a "remote shell" command that is only
                      3: # capable of pretending to connect to "localhost".  This is useful
                      4: # for testing or for running a local copy where the sender and the
                      5: # receiver needs to use different options (e.g. --fake-super).  If
1.1.1.2 ! misho       6: # we get -l USER, we try to become the USER, either directly (must
        !             7: # be root) or by using "sudo -H -u USER" (requires --sudo option).
1.1       misho       8: 
1.1.1.2 ! misho       9: use strict;
        !            10: use warnings;
        !            11: use Getopt::Long;
        !            12: use English '-no_match_vars';
1.1       misho      13: 
1.1.1.2 ! misho      14: &Getopt::Long::Configure('bundling');
        !            15: &Getopt::Long::Configure('require_order');
        !            16: GetOptions(
        !            17:     'l=s' => \( my $login_name ),
        !            18:     '1|2|4|6|A|a|C|f|g|k|M|N|n|q|s|T|t|V|v|X|x|Y' => sub { }, # Ignore
        !            19:     'b|c|D|e|F|i|L|m|O|o|p|R|S|w=s' => sub { }, # Ignore
        !            20:     'no-cd' => \( my $no_chdir ),
        !            21:     'sudo' => \( my $use_sudo ),
        !            22: ) or &usage;
        !            23: &usage unless @ARGV > 1;
        !            24: 
        !            25: my $host = shift;
        !            26: if ($host =~ s/^([^@]+)\@//) {
        !            27:     $login_name = $1;
        !            28: }
        !            29: if ($host ne 'localhost') {
        !            30:     die "lsh: unable to connect to host $host\n";
        !            31: }
        !            32: 
        !            33: my ($home_dir, @cmd);
        !            34: if ($login_name) {
        !            35:     my ($uid, $gid);
        !            36:     if ($login_name =~ /\D/) {
        !            37:        $uid = getpwnam($login_name);
        !            38:        die "Unknown user: $login_name\n" unless defined $uid;
        !            39:     } else {
        !            40:        $uid = $login_name;
        !            41:     }
        !            42:     ($login_name, $gid, $home_dir) = (getpwuid($uid))[0,3,7];
        !            43:     if ($use_sudo) {
        !            44:        unshift @ARGV, "cd '$home_dir' &&" unless $no_chdir;
        !            45:        unshift @cmd, qw( sudo -H -u ), $login_name;
        !            46:        $no_chdir = 1;
        !            47:     } else {
        !            48:        my $groups = "$gid $gid";
        !            49:        while (my ($grgid, $grmembers) = (getgrent)[2,3]) {
        !            50:            if ($grgid != $gid && $grmembers =~ /(^|\s)\Q$login_name\E(\s|$)/o) {
        !            51:                $groups .= " $grgid";
        !            52:            }
        !            53:        }
        !            54: 
        !            55:        my ($ruid, $euid) = ($UID, $EUID);
        !            56:        $GID = $EGID = $groups;
        !            57:        $UID = $EUID = $uid;
        !            58:        die "Cannot set ruid: $! (use --sudo?)\n" if $UID == $ruid && $ruid != $uid;
        !            59:        die "Cannot set euid: $! (use --sudo?)\n" if $EUID == $euid && $euid != $uid;
        !            60: 
        !            61:        $ENV{USER} = $ENV{USERNAME} = $login_name;
        !            62:        $ENV{HOME} = $home_dir;
        !            63:     }
        !            64: } else {
        !            65:     $home_dir = (getpwuid($UID))[7];
        !            66: }
        !            67: 
        !            68: unless ($no_chdir) {
        !            69:     chdir $home_dir or die "Unable to chdir to $home_dir: $!\n";
        !            70: }
        !            71: 
        !            72: push @cmd, '/bin/sh', '-c', "@ARGV";
        !            73: exec @cmd;
        !            74: die "Failed to exec: $!\n";
        !            75: 
        !            76: sub usage
        !            77: {
        !            78:     die <<EOT;
        !            79: Usage: lsh [-l user] [--sudo] [--no-cd] localhost COMMAND [...]
        !            80: EOT
        !            81: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>