diff --git a/Shorewall-core/lib.base b/Shorewall-core/lib.base index 0cd8ee22b..0368b25c1 100644 --- a/Shorewall-core/lib.base +++ b/Shorewall-core/lib.base @@ -28,7 +28,7 @@ # SHOREWALL_LIBVERSION=40500 -SHOREWALL_CAPVERSION=40501 +SHOREWALL_CAPVERSION=40502 [ -n "${g_program:=shorewall}" ] diff --git a/Shorewall-core/lib.cli b/Shorewall-core/lib.cli index 2ddc069a2..fb73de784 100644 --- a/Shorewall-core/lib.cli +++ b/Shorewall-core/lib.cli @@ -1908,6 +1908,7 @@ determine_capabilities() { IPRANGE_MATCH= RECENT_MATCH= OWNER_MATCH= + OWNER_NAME_MATCH= IPSET_MATCH= OLD_IPSET_MATCH= IPSET_V5= @@ -2046,6 +2047,11 @@ determine_capabilities() { qt $g_tool -A $chain -m recent --update -j ACCEPT && RECENT_MATCH=Yes qt $g_tool -A $chain -m owner --uid-owner 0 -j ACCEPT && OWNER_MATCH=Yes + local name + name=$(id -un 2> /dev/null) + + [ -n "$name" ] && qt $g_tool -A $chain -m owner --uid-owner $name -j ACCEPT && OWNER_NAME_MATCH=Yes + if qt $g_tool -A $chain -m connmark --mark 2 -j ACCEPT; then CONNMARK_MATCH=Yes qt $g_tool -A $chain -m connmark --mark 2/0xFF -j ACCEPT && XCONNMARK_MATCH=Yes @@ -2226,6 +2232,7 @@ report_capabilities() { report_capability "IP range Match(IPRANGE_MATCH)" $IPRANGE_MATCH report_capability "Recent Match (RECENT_MATCH)" $RECENT_MATCH report_capability "Owner Match (OWNER_MATCH)" $OWNER_MATCH + report_capability "Owner Name Match (OWNER_NAME_MATCH)" $OWNER_NAME_MATCH if [ -n "$IPSET_MATCH" ]; then report_capability "Ipset Match (IPSET_MATCH)" $IPSET_MATCH [ -n "$OLD_IPSET_MATCH" ] && report_capability "OLD_Ipset Match (OLD_IPSET_MATCH)" $OLD_IPSET_MATCH @@ -2314,6 +2321,7 @@ report_capabilities1() { report_capability1 IPRANGE_MATCH report_capability1 RECENT_MATCH report_capability1 OWNER_MATCH + report_capability1 OWNER_NAME_MATCH report_capability1 IPSET_MATCH report_capability1 OLD_IPSET_MATCH report_capability1 CONNMARK diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 2b1e0b277..a081ba254 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -4066,6 +4066,21 @@ sub do_time( $ ) { $result; } +sub resolve_id( $$ ) { + my ( $id, $type ) = @_; + + if ( $globals{EXPORT} ) { + require_capability 'OWNER_NAME_MATCH', "Specifying a $type name", 's'; + } else { + my $num = $type eq 'user' ? getpwnam( $id ) : getgrnam( $id ); + fatal_error "Unknown $type ($id)" unless supplied $num; + $id = $num; + } + + $id; +} + + # # Create a "-m owner" match for the passed USER/GROUP # @@ -4075,6 +4090,8 @@ sub do_user( $ ) { return '' unless defined $user and $user ne '-'; + require_capability 'OWNER_MATCH', 'A non-empty USER column', 's'; + if ( $user =~ /^(!)?(.*)\+(.*)$/ ) { $rule .= "! --cmd-owner $2 " if supplied $2; $user = "!$1"; @@ -4086,24 +4103,26 @@ sub do_user( $ ) { if ( $user =~ /^(!)?(.*):(.*)$/ ) { my $invert = $1 ? '! ' : ''; my $group = defined $3 ? $3 : ''; + if ( supplied $2 ) { - $user = $2; - fatal_error "Unknown user ($user)" unless $user =~ /^\d+$/ || $globals{EXPORT} || defined getpwnam( $user ); + $user = $2; + $user = resolve_id( $user, 'user' ) unless $user =~ /\d+$/; $rule .= "${invert}--uid-owner $user "; } if ( $group ne '' ) { - fatal_error "Unknown group ($group)" unless $group =~ /\d+$/ || $globals{EXPORT} || defined getgrnam( $group ); + $group = resolve_id( $group, 'group' ) unless $group =~ /^\d+$/; $rule .= "${invert}--gid-owner $group "; } } elsif ( $user =~ /^(!)?(.*)$/ ) { my $invert = $1 ? '! ' : ''; $user = $2; + fatal_error "Invalid USER/GROUP (!)" if $user eq ''; - fatal_error "Unknown user ($user)" unless $user =~ /^\d+$/ || $globals{EXPORT} || defined getpwnam( $user ); + $user = resolve_id ($user, 'user' ) unless $user =~ /\d+$/; $rule .= "${invert}--uid-owner $user "; } else { - fatal_error "Unknown user ($user)" unless $user =~ /^\d+$/ || $globals{EXPORT} || defined getpwnam( $user ); + $user = resolve_id( $user, 'user' ) unless $user =~ /\d+$/; $rule .= "--uid-owner $user "; } diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm index 386b7aa13..e6973c5dc 100644 --- a/Shorewall/Perl/Shorewall/Config.pm +++ b/Shorewall/Perl/Shorewall/Config.pm @@ -243,6 +243,8 @@ my %capdesc = ( NAT_ENABLED => 'NAT', IPRANGE_MATCH => 'IP Range Match', RECENT_MATCH => 'Recent Match', OWNER_MATCH => 'Owner Match', + OWNER_NAME_MATCH + => 'Owner Name Match', IPSET_MATCH => 'Ipset Match', OLD_IPSET_MATCH => 'Old Ipset Match', IPSET_V5 => 'Version 5 ipsets', @@ -482,7 +484,7 @@ sub initialize( $ ) { STATEMATCH => '-m state --state', UNTRACKED => 0, VERSION => "4.4.22.1", - CAPVERSION => 40501 , + CAPVERSION => 40502 , ); # # From shorewall.conf file @@ -662,6 +664,7 @@ sub initialize( $ ) { IPRANGE_MATCH => undef, RECENT_MATCH => undef, OWNER_MATCH => undef, + OWNER_NAME_MATCH => undef, IPSET_MATCH => undef, OLD_IPSET_MATCH => undef, IPSET_V5 => undef, @@ -2679,6 +2682,12 @@ sub Owner_Match() { qt1( "$iptables -A $sillyname -m owner --uid-owner 0 -j ACCEPT" ); } +sub Owner_Name_Match() { + if ( my $name = `id -un 2> /dev/null` ) { + qt1( "$iptables -A $sillyname -m owner --uid-owner $name -j ACCEPT" ); + } +} + sub Connmark_Match() { qt1( "$iptables -A $sillyname -m connmark --mark 2 -j ACCEPT" ); } @@ -3002,6 +3011,7 @@ our %detect_capability = OLD_HL_MATCH => \&Old_Hashlimit_Match, OLD_IPP2P_MATCH => \&Old_Ipp2p_Match, OWNER_MATCH => \&Owner_Match, + OWNER_NAME_MATCH => \&Owner_Name_Match, PERSISTENT_SNAT => \&Persistent_Snat, PHYSDEV_BRIDGE => \&Physdev_Bridge, PHYSDEV_MATCH => \&Physdev_Match, @@ -3097,6 +3107,8 @@ sub determine_capabilities() { $capabilities{IPRANGE_MATCH} = detect_capability( 'IPRANGE_MATCH' ); $capabilities{RECENT_MATCH} = detect_capability( 'RECENT_MATCH' ); $capabilities{OWNER_MATCH} = detect_capability( 'OWNER_MATCH' ); + $capabilities{OWNER_NAME_MATCH} + = detect_capability( 'OWNER_NAME_MATCH' ); $capabilities{CONNMARK_MATCH} = detect_capability( 'CONNMARK_MATCH' ); $capabilities{XCONNMARK_MATCH} = detect_capability( 'XCONNMARK_MATCH' ); $capabilities{IPP2P_MATCH} = detect_capability( 'IPP2P_MATCH' );