Skip Menu |

This queue is for tickets about the Net-Server CPAN distribution.

Report information
The Basics
Id: 41050
Status: open
Priority: 0/
Queue: Net-Server

People
Owner: Nobody in particular
Requestors: chris+rt [...] chrisdolan.net
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: 0.97



Subject: [PATCH] user/group owner for socket
On the madisonlinux.org mailing list, "Brad" posted the attached patch with this note: "I thought some folks on the list might find this useful. In working on a project of mine which uses Net::Server, I wanted it to create a socket readable/writeable by postfix smtpd. Currently, the only way to do that is to either run Net::Server as the postfix user (ick), or set a umask to make created files world-writeable (including the pid file, and anything else it creates -- bigger ick!). "I wrote a patch for Net::Server to allow specifying user/group socket ownership and/or socket modes. The patch is attached; apply, and pass the configuration options sock_owner, sock_group, and/or sock_mode (octal) to your Net::Server et voila! If any options are omitted, current behavior is unchanged."
Subject: Net-Server.sock_owner.patch
--- Server.pm.orig 2008-11-16 00:35:04.000000000 -0800 +++ Server.pm 2008-11-18 11:26:24.000000000 -0800 @@ -488,12 +488,64 @@ } + ### figure out group to own UNIX sockets + if ( defined $prop->{sock_group} ){ + if ( $prop->{sock_group} =~ /^([\w-]+( [\w-]+)*)$/ ){ + $prop->{sock_group} = eval { get_gid( $1 ) }; + $self->fatal( $@ ) if $@; + }else{ + $self->fatal("Invalid group socket owner \"$prop->{sock_group}\""); + } + } + + + ### figure out user to own UNIX sockets + if ( defined $prop->{sock_owner} ){ + if ( $prop->{sock_owner} =~ /^([\w-]+)$/ ){ + $prop->{sock_owner} = eval{ get_uid( $1 ) }; + $self->fatal ( $@ ) if $@; + }else{ + $self->fatal("Invalid socket owner \"$prop->{sock_owner}\""); + } + } + + + ### verify mode on UNIX sockets + if ( defined $prop->{sock_mode} ){ + my $orig_mode = $prop->{sock_mode}; + $prop->{sock_mode} = oct( $orig_mode ); + if ( ($prop->{sock_mode} > 07777) || ($prop->{sock_mode} < 1) ){ + $self->fatal("Invalid socket mode \"$orig_mode\""); + } + } + + ### chown any files or sockets that we need to if( $prop->{group} ne $) || $prop->{user} ne $> ){ my @chown_files = (); foreach my $sock ( @{ $prop->{sock} } ){ - push @chown_files, $sock->NS_unix_path - if ($sock->NS_proto eq 'UNIX') + if ($sock->NS_proto eq 'UNIX') { + my $file = $sock->NS_unix_path; + if (( defined $prop->{sock_owner} ) && ( defined $prop->{sock_group} )){ + chown( $prop->{sock_owner}, $prop->{sock_group}, $file ) + or $self->fatal("Couldn't chown \"$file\" [$!]\n"); + } + elsif ( defined $prop->{sock_owner} ){ + chown( $prop->{sock_owner}, (split(/\ /, $prop->{group}))[0], $file ) + or $self->fatal("Couldn't chown \"$file\" [$!]\n"); + } + elsif ( defined $prop->{sock_group} ){ + chown ( $prop->{user}, $prop->{sock_group}, $file ) + or $self->fatal("Couldn't chown \"$file\" [$!]\n"); + } + else { + push @chown_files, $file; + } + if ( defined $prop->{sock_mode} ){ + chmod( $prop->{sock_mode}, $file ) + or $self->fatal("Couldn't chmod \"$file\" [$!]\n"); + } + } } if( $prop->{pid_file_unlink} ){ push @chown_files, $prop->{pid_file}; @@ -1335,6 +1387,7 @@ foreach ( qw(conf_file user group chroot log_level + sock_owner sock_group sock_mode log_file pid_file background setsid listen reverse_lookups syslog_logsock syslog_ident
From: brad+bitcard [...] mifflinet.net
Hello, Brad Barden here. I created the patch Chris submitted. I'm attaching a patch for the Net::Server pod.
--- /usr/lib/perl5/vendor_perl/5.8.8/Net/Server.pod 2007-07-25 09:19:40.000000000 -0700 +++ Server.pod 2008-11-19 13:43:42.000000000 -0800 @@ -425,6 +425,10 @@ proto (tcp|udp|unix) "tcp" listen \d+ SOMAXCONN + sock_owner (uid|username) none + sock_group (gid|group) none + sock_mode "octal string" none + reverse_lookups 1 undef allow /regex/ none deny /regex/ none @@ -588,6 +592,24 @@ See L<IO::Socket>. Not used with udp protocol (or UNIX SOCK_DGRAM). +=item sock_owner + +Userid or username to own any UNIX sockets. Defaults to the value of +C<user>. + +=item sock_group + +Groupid or groupname to own any UNIX sockets. Defaults to the value of +C<group>. + +=item sock_mode + +Octal string defining the mode (permissions) on any UNIX sockets. Can be a +string representing an octal ("0660"), an integer or integer string (660 or +"660"), or any value which can be properly transformed to a file mode by +passing to C<oct()>. Defaults to undef (not set), in which case sockets are +created with the current umask. + =item reverse_lookups Specify whether to lookup the hostname of the connected IP.
From: brad+bitcard [...] mifflinet.net
I'm submitting an updated patch. There was an unforeseen circumstance of the last patch, which would make a reload of Net::Server fail when trying to use a sock_owner/sock_group different from the user to which Net::Server changed or not in the user's groups, respectively. This was an issue in Net::Server due to it's calling chown (again) on socket, pid, log, etc files when reloading, but since they were previously always changed to the uid/gid the process would run as, this did not create a problem. There is further description of this patch here: https://bugs.mifflinet.org/show_bug.cgi?id=3#c1
--- Server.pm.orig 2008-11-16 00:35:04.000000000 -0800 +++ Server.pm 2008-12-03 14:49:48.000000000 -0800 @@ -488,12 +488,65 @@ } + ### figure out group to own UNIX sockets + if ( defined $prop->{sock_group} ){ + if ( $prop->{sock_group} =~ /^([\w-]+( [\w-]+)*)$/ ){ + $prop->{sock_group} = eval { get_gid( $1 ) }; + $self->fatal( $@ ) if $@; + }else{ + $self->fatal("Invalid group socket owner \"$prop->{sock_group}\""); + } + } + + + ### figure out user to own UNIX sockets + if ( defined $prop->{sock_owner} ){ + if ( $prop->{sock_owner} =~ /^([\w-]+)$/ ){ + $prop->{sock_owner} = eval{ get_uid( $1 ) }; + $self->fatal ( $@ ) if $@; + }else{ + $self->fatal("Invalid socket owner \"$prop->{sock_owner}\""); + } + } + + + ### verify mode on UNIX sockets + if ( defined $prop->{sock_mode} ){ + my $orig_mode = $prop->{sock_mode}; + $prop->{sock_mode} = oct( $orig_mode ); + if ( ($prop->{sock_mode} > 07777) || ($prop->{sock_mode} < 1) ){ + $self->fatal("Invalid socket mode \"$orig_mode\""); + } + } + + ### chown any files or sockets that we need to - if( $prop->{group} ne $) || $prop->{user} ne $> ){ + ### Long painful story short, if $> isn't 0, this won't do much anyway + if( ($prop->{group} ne $) || $prop->{user} ne $>) && $> eq 0){ my @chown_files = (); foreach my $sock ( @{ $prop->{sock} } ){ - push @chown_files, $sock->NS_unix_path - if ($sock->NS_proto eq 'UNIX') + if ( $sock->NS_proto eq 'UNIX' ){ + my $file = $sock->NS_unix_path; + if (( defined $prop->{sock_owner} ) && ( defined $prop->{sock_group} )){ + chown( $prop->{sock_owner}, $prop->{sock_group}, $file ) + or $self->fatal("Couldn't chown \"$file\" [$!]\n"); + } + elsif ( defined $prop->{sock_owner} ){ + chown( $prop->{sock_owner}, (split(/\ /, $prop->{group}))[0], $file ) + or $self->fatal("Couldn't chown \"$file\" [$!]\n"); + } + elsif ( defined $prop->{sock_group} ){ + chown ( $prop->{user}, $prop->{sock_group}, $file ) + or $self->fatal("Couldn't chown \"$file\" [$!]\n"); + } + else { + push @chown_files, $file; + } + if ( defined $prop->{sock_mode} ){ + chmod( $prop->{sock_mode}, $file ) + or $self->fatal("Couldn't chmod \"$file\" [$!]\n"); + } + } } if( $prop->{pid_file_unlink} ){ push @chown_files, $prop->{pid_file}; @@ -1335,6 +1388,7 @@ foreach ( qw(conf_file user group chroot log_level + sock_owner sock_group sock_mode log_file pid_file background setsid listen reverse_lookups syslog_logsock syslog_ident
From: brad+bitcard [...] mifflinet.net
On Wed Dec 03 18:41:51 2008, bbarden wrote: Show quoted text
> This was an issue in Net::Server due to it's calling chown (again) on
socket, Show quoted text
> pid, log, etc files when reloading, but since they were previously always > changed to the uid/gid the process would run as, this did not create a > problem.
Actually, I suppose that's not true. On reload $prop->{user} should always equal $>, and $prop->{group} should always equal $), yes? It certainly isn't that way though, as the chown conditional gets entered (and fails with this patch when using sock_owner). More testing needed...