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