ikiwiki/ikiwiki-mass-rebuild

116 lines
2.4 KiB
Perl
Executable File
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/perl
use warnings;
use strict;
sub supplemental_groups {
my $user=shift;
my @list;
while (my @fields=getgrent()) {
if (grep { $_ eq $user } split(' ', $fields[3])) {
push @list, $fields[2];
}
}
return @list;
}
sub samelists {
my %a=map { $_ => 1 } split(' ', shift());
my %b=map { $_ => 1 } split(' ', shift());
foreach my $i (keys %b) {
if (! exists $a{$i}) {
return 0;
}
}
foreach my $i (keys %a) {
if (! exists $b{$i}) {
return 0;
}
}
return 1;
}
sub processline {
my $user=shift;
my $setup=shift;
if (! getpwnam("$user")) {
print STDERR "warning: user $user does not exist\n";
return
}
if (! -f "$setup") {
print STDERR "warning: $setup does not exist, skipping\n";
return;
}
print "Processing $setup as user $user ...\n";
# su is not used because it passes arguments through the shell,
# which is not safe for untrusted setup file names.
defined(my $pid = fork) or die "Cant fork: $!";
if (! $pid) {
my ($uuid, $ugid) = (getpwnam($user))[2, 3];
my $grouplist=join(" ", $ugid, sort {$a <=> $b} $ugid, supplemental_groups($user));
if (! samelists(($)=$grouplist), $grouplist)) {
die "failed to set egid $grouplist (got back $))";
}
$(=$ugid;
$<=$uuid;
$>=$uuid;
if ($< != $uuid || $> != $uuid || $( != $ugid) {
die "failed to drop permissions to $user";
}
%ENV=(
PATH => $ENV{PATH},
HOME => (getpwnam($user))[7],
);
exec("ikiwiki", "-setup", $setup, @ARGV);
die "failed to run ikiwiki: $!";
}
waitpid($pid,0);
if ($?) {
print STDERR "Processing $setup as user $user failed with code $?\n";
}
}
sub processlist {
my $file=shift;
my $forceuser=shift;
my $list;
open ($list, "<$file") || die "$file: $!";
while (<$list>) {
chomp;
s/^\s+//;
s/\s+$//;
next if /^#/ || ! length;
if (/^([^\s]+)\s+([^\s]+)$/) {
my $user=$1;
my $setup=$2;
if (defined $forceuser && $forceuser ne $user) {
print STDERR "warning: in $file line $., attempt to set user to $user, but user forced to $forceuser. Skipping\n";
}
processline($user, $setup);
}
elsif (/^([^\s]+)$/) {
my $user=$1;
my $home=(getpwnam($user))[7];
if (defined $home && -d $home) {
my $dotfile="$home/.ikiwiki/wikilist";
if (-e $dotfile) {
processlist($dotfile, $user);
}
}
}
}
close $list;
}
my $wikilist="/etc/ikiwiki/wikilist";
if (-e $wikilist) {
processlist($wikilist);
}