summaryrefslogtreecommitdiff
path: root/ikiwiki-mass-rebuild
blob: 0057beb4f1735f957045adb9ccb1f2893a89bbdc (plain)
  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;
  4. sub supplemental_groups {
  5. my $user=shift;
  6. my @list;
  7. while (my @fields=getgrent()) {
  8. if (grep { $_ eq $user } split(' ', $fields[3])) {
  9. push @list, $fields[2];
  10. }
  11. }
  12. return @list;
  13. }
  14. sub processline {
  15. my $user=shift;
  16. my $setup=shift;
  17. if (! getpwnam("$user")) {
  18. print STDERR "warning: user $user does not exist\n";
  19. return
  20. }
  21. if (! -f "$setup") {
  22. print STDERR "warning: $setup does not exist, skipping\n";
  23. return;
  24. }
  25. print "Processing $setup as user $user ...\n";
  26. # su is not used because it passes arguments through the shell,
  27. # which is not safe for untrusted setup file names.
  28. defined(my $pid = fork) or die "Can’t fork: $!";
  29. if (! $pid) {
  30. my ($uuid, $ugid) = (getpwnam($user))[2, 3];
  31. my $grouplist=join(" ", $ugid, $ugid, supplemental_groups($user));
  32. undef $!;
  33. $)=$grouplist;
  34. if ($!) {
  35. die "failed to set egid $grouplist: $!";
  36. }
  37. $(=$ugid;
  38. $<=$uuid;
  39. $>=$uuid;
  40. if ($< != $uuid || $> != $uuid || $( != $ugid) {
  41. die "failed to drop permissions to $user";
  42. }
  43. %ENV=(
  44. PATH => $ENV{PATH},
  45. HOME => (getpwnam($user))[7],
  46. );
  47. exec("ikiwiki", "-setup", $setup, @ARGV);
  48. die "failed to run ikiwiki: $!";
  49. }
  50. waitpid($pid,0);
  51. if ($?) {
  52. print STDERR "Processing $setup as user $user failed with code $?\n";
  53. }
  54. }
  55. sub processlist {
  56. my $file=shift;
  57. my $forceuser=shift;
  58. my $list;
  59. open ($list, "<$file") || die "$file: $!";
  60. while (<$list>) {
  61. chomp;
  62. s/^\s+//;
  63. s/\s+$//;
  64. next if /^#/ || ! length;
  65. if (/^([^\s]+)\s+([^\s]+)$/) {
  66. my $user=$1;
  67. my $setup=$2;
  68. if (defined $forceuser && $forceuser ne $user) {
  69. print STDERR "warning: in $file line $., attempt to set user to $user, but user forced to $forceuser. Skipping\n";
  70. }
  71. processline($user, $setup);
  72. }
  73. elsif (/^([^\s]+)$/) {
  74. my $user=$1;
  75. my $home=(getpwnam($user))[7];
  76. if (defined $home && -d $home) {
  77. my $dotfile="$home/.ikiwiki/wikilist";
  78. if (-e $dotfile) {
  79. processlist($dotfile, $user);
  80. }
  81. }
  82. }
  83. }
  84. close $list;
  85. }
  86. my $wikilist="/etc/ikiwiki/wikilist";
  87. if (-e $wikilist) {
  88. processlist($wikilist);
  89. }