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