prefork: - add --detach option to daemonize like forkserver
- use user/group switching from forkserver to support secondary groups (needed with plugins/queue/postfix-queue) git-svn-id: https://svn.perl.org/qpsmtpd/trunk@905 958fd67b-6ff1-0310-b445-bb7760255be9
This commit is contained in:
parent
96d3f6d40a
commit
502e1d286e
@ -73,6 +73,7 @@ my $quiet = 0;
|
|||||||
my $status = 0;
|
my $status = 0;
|
||||||
my $signal = '';
|
my $signal = '';
|
||||||
my $pretty = 0;
|
my $pretty = 0;
|
||||||
|
my $detach = 0;
|
||||||
my $user;
|
my $user;
|
||||||
|
|
||||||
# help text
|
# help text
|
||||||
@ -91,6 +92,7 @@ Usage: qpsmtpd-prefork [ options ]
|
|||||||
--user username : User the daemon should run as
|
--user username : User the daemon should run as
|
||||||
--pid-file path : Path to pid file
|
--pid-file path : Path to pid file
|
||||||
--renice-parent int : Subtract value from parent process nice level (default: $re_nice)
|
--renice-parent int : Subtract value from parent process nice level (default: $re_nice)
|
||||||
|
--detach : detach from controlling terminal (daemonize)
|
||||||
--help : This message
|
--help : This message
|
||||||
EOT
|
EOT
|
||||||
exit 0;
|
exit 0;
|
||||||
@ -109,10 +111,11 @@ GetOptions(
|
|||||||
'pretty-child' => \$pretty,
|
'pretty-child' => \$pretty,
|
||||||
'user=s' => \$user,
|
'user=s' => \$user,
|
||||||
'renice-parent=i' => \$re_nice,
|
'renice-parent=i' => \$re_nice,
|
||||||
|
'detach' => \$detach,
|
||||||
'help' => \&usage,
|
'help' => \&usage,
|
||||||
) || &usage;
|
) || &usage;
|
||||||
|
|
||||||
$user = $1 if ($user =~ /(\w+)/);
|
if ($user =~ /^([\w\-]+)$/) { $user = $1 } else { &usage }
|
||||||
|
|
||||||
# set max from ip to max number of children if option is set to disabled
|
# set max from ip to max number of children if option is set to disabled
|
||||||
$maxconnip = $max_children if ($maxconnip == 0);
|
$maxconnip = $max_children if ($maxconnip == 0);
|
||||||
@ -125,26 +128,32 @@ $idle_children = $max_children
|
|||||||
if (!$idle_children || $idle_children > $max_children || $idle_children < -1);
|
if (!$idle_children || $idle_children > $max_children || $idle_children < -1);
|
||||||
$chld_pool = $idle_children;
|
$chld_pool = $idle_children;
|
||||||
|
|
||||||
|
if ($detach) {
|
||||||
|
open STDIN, '/dev/null' or die "/dev/null: $!";
|
||||||
|
open STDOUT, '>/dev/null' or die "/dev/null: $!";
|
||||||
|
open STDERR, '>&STDOUT' or die "open(stderr): $!";
|
||||||
|
defined (my $pid = fork) or die "fork: $!";
|
||||||
|
exit 0 if $pid;
|
||||||
|
POSIX::setsid or die "setsid: $!";
|
||||||
|
}
|
||||||
|
|
||||||
run();
|
run();
|
||||||
|
|
||||||
#start daemon
|
#start daemon
|
||||||
sub run {
|
sub run {
|
||||||
# get UUID/GUID
|
# get UUID/GUID
|
||||||
my ($uuid, $ugid, $group);
|
my ($quid, $qgid, $groups);
|
||||||
if ($user) {
|
if ($user) {
|
||||||
my $T_uuid = `id -u $user`;
|
(undef, undef, $quid, $qgid) = getpwnam $user
|
||||||
my $T_ugid = `id -g $user`;
|
or die "unable to determine uid/gid for $user\n";
|
||||||
my $T_group = `id -n -g $user`;
|
$groups = "$qgid $qgid";
|
||||||
chomp($T_uuid);
|
while (my ($name,$passwd,$gid,$members) = getgrent()) {
|
||||||
chomp($T_ugid);
|
my @m = split(/ /, $members);
|
||||||
chomp($T_group);
|
if (grep {$_ eq $user} @m) {
|
||||||
|
$groups .= " $gid";
|
||||||
# make the following vars taint happy
|
}
|
||||||
$uuid = $1 if ($T_uuid =~ /(\d+)/);
|
}
|
||||||
$ugid = $1 if ($T_ugid =~ /(\d+)/);
|
endgrent;
|
||||||
$group = $1 if ($T_group =~ /(\w+)/);
|
|
||||||
die("FATAL: unknown user <$user> or missing group information")
|
|
||||||
if (!$uuid || !$ugid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
my @Socket_opts = (
|
my @Socket_opts = (
|
||||||
@ -182,12 +191,12 @@ sub run {
|
|||||||
|
|
||||||
if ($user) {
|
if ($user) {
|
||||||
# change UUID/UGID
|
# change UUID/UGID
|
||||||
$) = "$ugid $ugid"; # effective gid
|
$) = $groups;
|
||||||
$( = $ugid; # real gid
|
POSIX::setgid($qgid) or die "unable to change gid: $!\n";
|
||||||
$> = $uuid; # effective uid
|
POSIX::setuid($quid) or die "unable to change uid: $!\n";
|
||||||
$< = $uuid; # real uid. we now cannot setuid anymore
|
$> = $quid;
|
||||||
die "FATAL: failed to setuid to user: $user, uid: $uuid\n"
|
die "FATAL: failed to setuid to user: $user, uid: $quid\n"
|
||||||
if ($> != $uuid and $> != ($uuid - 2**32));
|
if ($> != $quid and $> != ($quid - 2**32));
|
||||||
}
|
}
|
||||||
|
|
||||||
# setup shared memory
|
# setup shared memory
|
||||||
|
Loading…
Reference in New Issue
Block a user