summaryrefslogtreecommitdiff
path: root/ikiwiki-mass-rebuild
blob: 3d0ca734c4652368c9486e5479ce92279efdb610 (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, sort {$a <=> $b} $ugid, supplemental_groups($user));
  32. if (($)=$grouplist) ne $grouplist) {
  33. die "failed to set egid $grouplist (got back $))";
  34. }
  35. $(=$ugid;
  36. $<=$uuid;
  37. $>=$uuid;
  38. if ($< != $uuid || $> != $uuid || $( != $ugid) {
  39. die "failed to drop permissions to $user";
  40. }
  41. %ENV=(
  42. PATH => $ENV{PATH},
  43. HOME => (getpwnam($user))[7],
  44. );
  45. exec("ikiwiki", "-setup", $setup, @ARGV);
  46. die "failed to run ikiwiki: $!";
  47. }
  48. waitpid($pid,0);
  49. if ($?) {
  50. print STDERR "Processing $setup as user $user failed with code $?\n";
  51. }
  52. }
  53. sub processlist {
  54. my $file=shift;
  55. my $forceuser=shift;
  56. my $list;
  57. open ($list, "<$file") || die "$file: $!";
  58. while (<$list>) {
  59. chomp;
  60. s/^\s+//;
  61. s/\s+$//;
  62. next if /^#/ || ! length;
  63. if (/^([^\s]+)\s+([^\s]+)$/) {
  64. my $user=$1;
  65. my $setup=$2;
  66. if (defined $forceuser && $forceuser ne $user) {
  67. print STDERR "warning: in $file line $., attempt to set user to $user, but user forced to $forceuser. Skipping\n";
  68. }
  69. processline($user, $setup);
  70. }
  71. elsif (/^([^\s]+)$/) {
  72. my $user=$1;
  73. my $home=(getpwnam($user))[7];
  74. if (defined $home && -d $home) {
  75. my $dotfile="$home/.ikiwiki/wikilist";
  76. if (-e $dotfile) {
  77. processlist($dotfile, $user);
  78. }
  79. }
  80. }
  81. }
  82. close $list;
  83. }
  84. my $wikilist="/etc/ikiwiki/wikilist";
  85. if (-e $wikilist) {
  86. processlist($wikilist);
  87. }