#!/usr/bin/perl # #!/usr/bin/perl # # Copyright (C) 2006 Mandriva # # Author: Florent Villard # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # run commands which needs root privilege # use strict; my $program_name = 'iurt_root_command'; use Mkcd::Commandline qw(parseCommandLine usage); use MDK::Common; my $arg = @ARGV; my (@params, %run); $run{program_name} = $program_name; my %authorized_modules = ( 'unionfs' => 1 ); my $sudo = '/usr/bin/sudo'; $run{todo} = [ ]; @params = ( # [ "one letter option", "long name option", "number of args (-X means ´at least X´)", "help text", "function to call", "log info"] # # no_rsync, config_help and copy_srpm kept for compatibility reasons # [ "", "$program_name", 0, "[--verbose ] [--modprobe ] [--mkdir [--parents] ... ]", "$program_name is a perl script to execute commands which need root privilege, it helps probram which needs occasional root privileges for some commands.", sub { $arg or usage($program_name, \@params) }, "Running $program_name" ], [ "", "mkdir", [ ["", "mkdir", -1, "[--parents] ... ]", "mkdir create the given path", sub { my ($tmp, @arg) = @_; $tmp->[0] ||= {}; push @$tmp, @arg; 1 }, "Setting auto mode arguments"], ["p", "parents", 0, "", "Also create needed parents directories", sub { my ($tmp) = @_; $tmp->[0]{parents} = 1; 1 }, "Set the parents flag"], ], "[--parents] ... ]", "mkdir create the given path", \&mkdir, "Creating the path" ], [ "", "rm", [ ["", "rm", -1, "[-f] [-r] ... ]", "remove the provided files", sub { my ($tmp, @arg) = @_; $tmp->[0] ||= {}; push @$tmp, @arg; 1 }, "Setting rm command arguments"], ["r", "recursive", 0, "", "Also create needed parents directories", sub { my ($tmp) = @_; $tmp->[0]{recursive} = 1; 1 }, "Set the recursive flag"], ], "[-r] ... ]", "Remove files", \&rm, "Removing files" ], [ "", "initdb", 1 , "]", "perform a rpm --initdb in the chroot.", \&initdb, "Initializing the rpm database" ], [ "v", "verbose", 1, "", "modprobe try to modprobe the given module if authorized.", sub { $run{verbose} = @_->[0]; 1 }, "Setting verbose level" ], [ "", "modprobe", 1, "]", "modprobe try to modprobe the given module if authorized.", \&modprobe, "Modprobing" ], ); open(my $LOG, ">&STDERR"); $run{LOG} = $LOG; my $todo = parseCommandLine($program_name, \@ARGV, \@params); @ARGV and usage($program_name, \@params, "@ARGV, too many arguments"); foreach my $t (@$todo) { print {$run{LOG}} "$program_name: $t->[2]\n" if $run{verbose} > 5; &{$t->[0]}(\%run, @{$t->[1]}) or print {$run{LOG}} "ERROR: $t->[2]\n"; } exit; sub modprobe { my ($run, $module) = @_; if (!$authorized_modules{$module}) { print {$run->{LOG}} "ERROR $program_name: unauthorized module $module\n"; return 0 } system($sudo, "/sbin/depmod", "-a"); !system($sudo, "/sbin/modprobe", "-f", $module) } sub mkdir { my ($run, $opt, @dir) = @_; foreach my $path (@dir) { -d $path and next; if ($path =~ m,/dev|/proc|/root|/var, && $path !~ /chroot|unionfs/) { print {$run->{LOG}} "ERROR $program_name: $path creation forbidden\n"; } if ($opt->{parents}) { mkdir_p $path } else { mkdir $path } } 1 } sub initdb { my ($run, $chroot) = @_; if (-d $chroot && $chroot !~ /chroot|unionfs/) { print {$run{LOG}} "ERROR $program_name: rpm --initdb not authorized in $chroot\n"; return 0 } !system("rpm", "--initdb", "--root", "$chroot") } sub rm { my ($run, $opt, @files) = @_; my $ok = 1; my $done; my $unauthorized = "^(/etc|/root|/dev|/var|/lib|/usr)"; foreach my $f (@files) { if (-d $f) { if (!$opt->{recursive}) { print {$run->{LOG}} "$program_name: could not remove directories without the -r option\n"; $ok = 0 } else { if ($f =~ m,$unauthorized,) { print {$run->{LOG}} "$program_name: removal of $f forbidden\n"; $ok = 0 } else { system($sudo, 'rm', '-rf', $f); print {$run->{LOG}} "$program_name: removing $f\n" if $run->{verbose}; $done = 1 } } } else { if ($f =~ m,/root|/dev|/var|/lib|/usr,) { print {$run->{LOG}} "$program_name: removal of $f forbidden\n"; $ok = 0 } else { if ($f =~ /\*?/) { foreach my $file (glob $f) { if ($f =~ m,/root|/dev|/var|/lib|/usr,) { print {$run->{LOG}} "$program_name: removal of $f forbidden\n"; $ok = 0 } else { unlink $file; $done = 1; print {$run->{LOG}} "$program_name: removing $file\n" if $run->{verbose} } } } else { unlink $f; $done = 1; print {$run->{LOG}} "$program_name: removing $f\n" if $run->{verbose} } } } } if (!$done) { print {$run->{LOG}} "$program_name: nothing deleted\n" } $ok }