diff --git a/bin/install.pike b/bin/install.pike
index fd95ff5ee10d97e4c52b8a9891abfce4351418a2..fbcdd166a4b29f4ad513c142631d24c4e7a67361 100644
--- a/bin/install.pike
+++ b/bin/install.pike
@@ -420,6 +420,11 @@ string translate(string filename, mapping translator)
     combine_path(translate(dirname(filename),translator),basename(filename));
 };
 
+void tarfilter(string filename)
+{
+  ((program)combine_path(__FILE__, "..", "tarfilter"))()->
+    main(3, ({ "tarfilter", filename, filename }));
+}
 
 void do_export()
 {
@@ -604,6 +609,9 @@ done
       tararg="rf";
     }
 
+  status("Filtering to root/root ownership", tmpname+".tar");
+  tarfilter(tmpname+".tar");
+
   status("Creating",tmpname+".tar.gz");
 
   Process.create_process(({"gzip","-9",tmpname+".tar"}))->wait();
@@ -615,6 +623,9 @@ done
   Process.create_process( ({ "tar","cf", export_base_name})+ to_export)
     ->wait();
 
+  status("Filtering to root/root ownership", export_base_name);
+  tarfilter(export_base_name);
+
   chmod(export_base_name,0755);
 
   status("Cleaning up","");
diff --git a/bin/mkpackage.pike b/bin/mkpackage.pike
index ae82b98737684a7ea8836b3d52720b848907374c..b8dd37bff1838187fa492a338b9e514bb5cae95c 100644
--- a/bin/mkpackage.pike
+++ b/bin/mkpackage.pike
@@ -142,6 +142,10 @@ class Package
       cd(original_wd);
     }
 
+    // Filter to root/root ownership.
+    ((program)combine_path(__FILE__, "..", "tarfilter"))()->
+      main(3, ({ "tarfilter", package_filename, package_filename }));
+  
     chmod(package_filename, 0755);
 
     rmrf("#!", setup_filename);
diff --git a/bin/tarfilter.pike b/bin/tarfilter.pike
new file mode 100755
index 0000000000000000000000000000000000000000..e1738dc4f8b37f081d86f0a6ab35a42828536a09
--- /dev/null
+++ b/bin/tarfilter.pike
@@ -0,0 +1,86 @@
+#!/usr/local/bin/pike
+
+//
+// Filters a tar file applying root/root ownership.
+//
+
+void copydata(Stdio.File in, Stdio.File out, int size)
+{
+  while(size>0) {
+    string s = in->read((size>8192? 8192 : size));
+    if(s == "") {
+      werror("READ ERROR on input\n");
+      exit(1);
+    }
+    out->write(s);
+    size -= strlen(s);
+  }
+}
+
+void doit(Stdio.File in, Stdio.File out)
+{
+  for(;;) {
+    string s = in->read(512);
+    if(s == "")
+      break;
+    if(strlen(s) != 512) {
+      werror("READ ERROR on input\n");
+      exit(1);
+    }
+    if(s-"\0" == "") {
+      out->write(s);
+      continue;
+    }
+    array a =
+      array_sscanf(s, "%100s%8s%8s%8s%12s%12s%8s%c%100s%8s%32s%32s%8s%8s");
+    int csum, size;
+    sscanf(a[4], "%o", size);
+    sscanf(a[6], "%o", csum);
+    s=s[..147]+"        "+s[156..];
+    if(`+(@values(s[..511])) != csum) {
+      werror("CHECKSUM ERROR on input!\n");
+      exit(1);
+    }
+    a[2] = "     0 \0";
+    a[3] = "     0 \0";
+    if((a[9]/"\0")[0]-" " == "ustar") {
+      a[10] = "root\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+      a[11] = "root\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+    }
+    a[6] = "        ";
+    s = sprintf("%100s%8s%8s%8s%12s%12s%8s%c%100s%8s%32s%32s%8s%8s", @a)+
+      s[345..];
+    out->write(s[..147]+sprintf("%07o\0", `+(@values(s[..511])))+s[156..]);
+    copydata(in, out, size);
+    if(size & 511)
+      copydata(in, out, 512-(size & 511));
+  }
+}
+
+int main(int argc, array(string) argv)
+{
+  Stdio.File s = Stdio.File("stdin");
+  Stdio.File d = Stdio.File("stdout");
+  
+  if(argc == 3)
+  {
+    s = Stdio.File(argv[1], "r");
+    d = Stdio.File(argv[2]+".tmp", "cwt");
+  }
+  
+  doit(s, d);
+
+  if(argc == 3)
+  {
+    d->close();
+    s->close();
+    
+    if(!mv(argv[2]+".tmp", argv[2]))
+    {
+      werror("FATAL! mv(%O, %O) failed.", argv[2], argv[2]);
+      exit(1);
+    }
+  }
+  
+  return 0;
+}