summaryrefslogtreecommitdiffstats
path: root/web/server/h2o/libh2o/share/h2o/setuidgid
blob: c8e9a30ad906ab53f86c4f140d6217777a93a438 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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]:$!";