diff --git a/djabberd b/djabberd index 2e09cc2..9292aaf 100755 --- a/djabberd +++ b/djabberd @@ -31,7 +31,7 @@ BEGIN { $DEBUG = 0; -my ($daemonize); +my ($daemonize, $uid); my $conffile; @@ -39,10 +39,12 @@ Getopt::Long::GetOptions( 'd|daemon' => \$daemonize, 'debug=i' => \$DEBUG, 'conffile=s' => \$conffile, + 'u|uid=s' => \$uid, ); my $server = DJabberd->new( - daemonize => $daemonize + daemonize => $daemonize, + uid => $uid ); my @try_conf = ( $conffile, "/etc/djabberd/djabberd.conf", "djabberd.conf" ); diff --git a/lib/DJabberd.pm b/lib/DJabberd.pm index 04d32f4..2b137e8 100644 --- a/lib/DJabberd.pm +++ b/lib/DJabberd.pm @@ -58,6 +58,7 @@ sub new { 's2s_port' => delete $opts{s2s_port}, 'c2s_port' => delete($opts{c2s_port}) || 5222, # {=clientportnumber} 'old_ssl' => delete $opts{old_ssl}, + 'uid' => delete $opts{uid}, 'vhosts' => {}, 'fake_peers' => {}, # for s2s testing. $hostname => "ip:port" 'share_parsers' => 1, @@ -155,6 +156,11 @@ sub set_config_pidfile { $self->{pid_file} = $val; } +sub set_config_uid { + my ($self, $val) = @_; + $self->{uid} = $val; +} + our %fake_peers; sub set_fake_s2s_peer { my ($self, $host, $ipendpt) = @_; @@ -284,6 +290,7 @@ sub run { $self->_start_server($self->{admin_port}, "DJabberd::Connection::Admin") if $self->{admin_port}; DJabberd::Connection::Admin->on_startup; + $self->change_uid() if $self->{uid}; Danga::Socket->EventLoop(); unlink($self->{pid_file}) if (-f $self->{pid_file}); } @@ -530,6 +537,24 @@ sub _load_config_ref { } } +sub change_uid { + my ($self) = @_; + my $uid = $self->{uid}; + + die "Cannot change uid if not running as root\n" if ($>); + + $uid = getpwnam($uid) if ( $uid !~ /^\d+$/ ); + die "Inexistant user $self->{uid}" if ! $uid; + + # otherwise, we will not be able to remove it on termination + chown($uid, "root", $self->{pid_file}) if (-f $self->{pid_file}); + + POSIX::setuid($uid); + + die "Couldn't change to uid $self->{uid}" if (!$>); +} + + sub daemonize { my($pid, $sess_id, $i);