Xref: feenix.metronet.com comp.unix.questions:10239 comp.unix.admin:5249 comp.unix.shell:3972
Newsgroups: comp.unix.questions,comp.unix.admin,comp.unix.shell
Path: feenix.metronet.com!news.utdallas.edu!wupost!howland.reston.ans.net!agate!boulder!wraeththu.cs.colorado.edu!tchrist
From: Tom Christiansen <
[email protected]>
Subject: Re: rvi - restricted vi??
Message-ID: <
[email protected]>
Originator:
[email protected]
Sender:
[email protected] (The Daily Planet)
Nntp-Posting-Host: wraeththu.cs.colorado.edu
Reply-To:
[email protected] (Tom Christiansen)
Organization: University of Colorado, Boulder
References: <
[email protected]>
Date: Wed, 1 Sep 1993 15:55:12 GMT
Lines: 120
From the keyboard of
[email protected] (Cindy Wang):
:I know someone who is setting up restricted shell. He'd like
:to have vi in /usr/rbin but couldn't because of the :!shell feature
:in vi. Is there a rvi -- restricted vi somewhere?
I've used this, which is a wrapper around any editor.
--tom
#!/usr/bin/perl
#
# seced -- secure editor wrapper
# Tom Christiansen <
[email protected]>
# based on an idea by Ray Davis <
[email protected]>
#
# install suid root or with a suid wrapper
%ok = ( '/usr/ucb/vi', 1,
'/usr/ucb/ex', 1,
'/bin/ed', 1,
'/usr/local/bin/emacs', 1,
);
$tmpdir = "/tmp/seced.$$";
die "$0: Not superuser\n" if $>;
die "usage: $0 file ...\n" if $#ARGV < 0;
chop($cwd = `pwd`);
mkdir($tmpdir,0700) || die "can't mkdir $tmpdir: $!";
chdir($tmpdir) || die "can't chdir $tmpdir: $!";
mkdir('tmp', 0777) || die "can't mkdir $tmpdir/tmp: $!";
&cp_editor;
&cp_files;
if ($kid = fork) {
die "cannot fork: $!" if $kid == -1;
$pid = wait until $pid == $kid || $pid == -1;
die "wait: no kids" if $pid == -1;
warn "$0: edit failed with status " . ($? >> 8) . "\n"
if $?;
} else {
chroot($tmpdir) || die "can't chroot $tmpdir: $!";
exec($editor, @ARGV);
# NOT REACHED
}
&replace_files unless $?;
chdir('/') || die "absurd failure to chdir to /: $!";
exec('/bin/rm', '-rf', $tmpdir);
# NOT REACHED
sub cp_editor {
$editor = $ENV{'SECED'}
|| $ENV{'VISUAL'}
|| $ENV{'EDITOR'}
|| '/usr/ucb/vi';
die "$0: need full path for \$EDITOR: $editor\n"
unless $editor =~ m#^/#;
die "$0: illegal \$EDITOR: $editor\n"
unless defined $ok{$editor};
system('/bin/cp', $editor, '.')
&& die "$0: couldn't cp editor\n";
if ($editor eq '/usr/ucb/vi' || $editor eq '/usr/ucb/ex') {
$home = $ENV{'HOME'} || '/';
$startup = "$home/.exrc";
if (-e $startup && -O _) {
system('/bin/cp', $startup, '.')
&& die "$0: couldn't cp $startup\n";
chown($<, -1, '.exrc');
}
}
$editor =~ s#.*(/[^/]+)$#.$1#;
}
sub cp_files {
@files = grep(/^[^-]/, @ARGV);
grep(s#^[^/]#$cwd/$&#, @files);
die "no files to edit" if $#files < 0;
system('/bin/cp', @files, '.')
&& die "couldn't cp files";
chown($<, -1, <*>)
|| die "couldn't chown files to uid $<";
for (@files) {
($local = $_) =~ s#.*/##;
unless (-T) {
warn "$0: WARNING: $_ not a text file\n";
sleep(1);
}
$mtime{$_} = (stat($local))[9];
}
}
sub replace_files {
for (@files) {
($local = $_) =~ s#.*/##;
if ((stat($local))[9] == $mtime{$_}) {
warn "$0: $_ unmodified\n";
next;
}
system('/bin/cp', $local, $_)
&& die "$0: can't cp $local $_\n";
}
}
--
Tom Christiansen
[email protected] 303-444-3212