summaryrefslogtreecommitdiffstats
path: root/web/server/h2o/libh2o/share/h2o/setuidgid
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xweb/server/h2o/libh2o/share/h2o/setuidgid46
1 files changed, 46 insertions, 0 deletions
diff --git a/web/server/h2o/libh2o/share/h2o/setuidgid b/web/server/h2o/libh2o/share/h2o/setuidgid
new file mode 100755
index 00000000..c8e9a30a
--- /dev/null
+++ b/web/server/h2o/libh2o/share/h2o/setuidgid
@@ -0,0 +1,46 @@
+#! /bin/sh
+exec ${H2O_PERL:-perl} -x $0 "$@"
+#! perl
+
+use strict;
+use warnings;
+use POSIX qw(setuid setgid);
+
+die "usage: share/h2o/setuidgid username child\n"
+ unless @ARGV >= 2;
+my $username = shift @ARGV;
+
+# get user entry
+my ($uid, @groups) = do {
+ my @e = getpwnam($username)
+ or die "unknown user: $username\n";
+ +($e[2], $e[3]);
+};
+
+# add supp. groups to @groups
+setgrent;
+while (my @e = getgrent) {
+ if ($e[3] && grep { $_ eq $username } split /\s+/, $e[3]) {
+ push @groups, $e[2]
+ unless grep { $_ == $e[2] } @groups;
+ }
+}
+endgrent;
+
+# setgid
+setgid($groups[0])
+ or die "setgid failed:$!";
+
+# setgroups
+$! = 0;
+$) = join " ", $groups[0], @groups;
+die "setgroups failed:$!"
+ if $!;
+
+# setuid
+setuid($uid)
+ or die "setuid failed:$!";
+
+# exec
+exec @ARGV
+ or die "failed to exec: $ARGV[0]:$!";