use strict; use File::Path; # heh use Getopt::Std; die "Not running as root (uid=$<)\n" if $<; getopts( 'u:', \my %opt ); if (!exists $opt{u}) { die "You must specify a user (or uid) with the -u switch\n"; } my ($uid, $gid) = $opt{u} =~ /\D/ ? (getpwnam($opt{u}))[2,3] : (getpwuid($opt{u}))[2,3] ; rmtree('EXTRA') if -d 'EXTRA'; create_dir('EXTRA', 0755); # directory EXTRA/1 could be deleted by a # non-privileged account, including one file belonging to root. create_dir( 'EXTRA/1', 0777, $uid, $gid ); create_file( 'EXTRA/1/a', 0600, $uid, $gid ); create_file( 'EXTRA/1/b', 0400, $uid, $gid ); # contents of EXTRA/2 can be removed by a # non-privileged account. create_dir( 'EXTRA/2', 0700, $uid, $gid ); create_file( 'EXTRA/2/a', 0066, $<, $( ); create_file( 'EXTRA/2/b', 0400, $<, $( ); create_file( 'EXTRA/2/c', 0000, $uid, $gid ); # directory EXTRA/3 contains sundry files create_dir( 'EXTRA/3', 0700, $uid, $gid ); create_file( 'EXTRA/3/a', 0400, $<, $( ); create_file( 'EXTRA/3/b', 0400, $uid, $gid ); # directory EXTRA/4 is a symlink to EXTRA/3 symlink './3', 'EXTRA/4' or die "symlink: $!"; create_dir( 'EXTRA/3/M', 0700, $uid, $gid ); create_file( 'EXTRA/3/M/xx', 0400, $uid, $gid ); create_file( 'EXTRA/3/M/yy', 0400, $uid, $gid ); create_dir( 'EXTRA/3/S', 0000, $<, $( ); create_dir( 'EXTRA/3/T', 0000, $<, $( ); create_dir( 'EXTRA/3/U', 0000, $<, $( ); create_dir( 'EXTRA/3/V', 0700, $uid, $gid ); symlink './M', 'EXTRA/3/N' or die "symlink: $!"; # inaccessible child dir create_dir( 'EXTRA/5', 0700, $<, $( ); create_file( 'EXTRA/5/xx', 0700, $<, $( ); create_file( 'EXTRA/5/yy', 0700, $<, $( ); chmod( 0200, 'EXTRA/5' ); sub create_dir { my $dir = shift; my $mask = shift; my $uid = shift; my $gid = shift; if (!-d $dir) { mkdir $dir, $mask or die "mkdir $dir: $!\n"; } if (defined $uid and defined $gid) { chown $uid, $gid, $dir or die "failed to chown dir $dir to ($uid,$gid)\n" } } sub create_file { my $file = shift; my $mask = shift; my $uid = shift; my $gid = shift; open OUT, "> $file" or die "Cannot open $file for output: $!\n"; print OUT <