Support multiple parameters in macros.

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2012-11-26 11:04:19 -08:00
parent fc87576005
commit 7673b1ac4b
7 changed files with 144 additions and 91 deletions

View File

@ -71,6 +71,14 @@
# Remaining Any value in the rules file REPLACES the value
# columns given in the macro file.
#
# Multiple parameters may be passed to a macro. Within this file, $1 refers to the first parameter,
# $2 to the second an so on. $1 is a synonym for PARAM but may be used anywhere in the file whereas
# PARAM may only be used in the ACTION column.
#
# You can specify default values for parameters by using DEFAULT or DEFAULTS entry:
#
# DEFAULTS <default for $1>,<default for $2>,...
#
#######################################################################################################
# DO NOT REMOVE THE FOLLOWING LINE
FORMAT 2

View File

@ -307,6 +307,51 @@ sub use_policy_action( $ );
sub normalize_action( $$$ );
sub normalize_action_name( $ );
sub process_default_action( $$$$ ) {
my ( $originalpolicy, $policy, $default, $level ) = @_;
if ( supplied $default ) {
my $default_option = ( $policy =~ /_DEFAULT$/ );
my ( $def, $param ) = get_target_param( $default );
if ( supplied $level ) {
validate_level( $level );
} else {
$level = 'none';
}
if ( "\L$default" eq 'none' ) {
if ( supplied $param || ( supplied $level && $level ne 'none' ) ) {
if ( $default_option ) {
fatal_error "Invalid setting (originalpolicy) for $policy";
} else {
fatal_error "Invalid policy ($originalpolicy)";
}
}
$default = 'none';
} elsif ( $actions{$def} ) {
$default = supplied $param ? normalize_action( $def, $level, $param ) :
$level eq 'none' ? normalize_action_name $def :
normalize_action( $def, $level, '' );
use_policy_action( $default );
} elsif ( find_macro( $def ) ) {
$default = join( '.', 'macro', $def ) unless $default =~ /^macro./;
$default = "$def($param)" if supplied $param;
} elsif ( $default_option ) {
fatal_error "Unknown Action ($default) in $policy setting";
} else {
fatal_error "Unknown Default Action ($default)";
}
$default = join( ':', $default, $level ) if $level ne 'none';
} else {
$default = $default_actions{$policy} || 'none';
}
$default;
}
#
# Process an entry in the policy file.
#
@ -338,11 +383,11 @@ sub process_a_policy() {
require_capability 'AUDIT_TARGET', ":audit", "s" if $audit;
my ( $policy, $default, $remainder ) = split( /:/, $originalpolicy, 3 );
my ( $policy, $default, $level, $remainder ) = split( /:/, $originalpolicy, 4 );
fatal_error "Invalid or missing POLICY ($originalpolicy)" unless $policy;
fatal_error "Invalid default action ($default:$remainder)" if defined $remainder;
fatal_error "Invalid default action ($default:$level:$remainder)" if defined $remainder;
( $policy , my $queue ) = get_target_param $policy;
@ -352,28 +397,7 @@ sub process_a_policy() {
fatal_error "A $policy policy may not be audited" unless $auditpolicies{$policy};
}
if ( $default ) {
my ( $def, $param ) = get_target_param( $default );
if ( "\L$default" eq 'none' ) {
$default = 'none';
} elsif ( $actions{$def} ) {
$default = supplied $param ? normalize_action( $def, 'none', $param ) : normalize_action_name $def;
use_policy_action( $default );
} elsif ( find_macro( $def ) ) {
$def = join( '.', 'macro', $def ) unless $default =~ /^macro./;
if ( supplied $param ) {
validate_level($param);
$default = join( ':', $def, $param );
} else {
$default = $def;
}
} else {
fatal_error "Unknown Default Action ($default)";
}
} else {
$default = $default_actions{$policy} || 'none';
}
$default = process_default_action( $originalpolicy, $policy, $default, $level );
if ( defined $queue ) {
fatal_error "Invalid policy ($policy($queue))" unless $policy eq 'NFQUEUE';
@ -506,24 +530,9 @@ sub process_policies()
my $action = $config{$option};
unless ( $action eq 'none' ) {
my ( $act, $param ) = get_target_param( $action );
if ( "\L$action" eq 'none' ) {
$action = 'none';
} elsif ( $actions{$act} ) {
$action = supplied $param ? normalize_action( $act, 'none', $param ) : normalize_action_name $act;
use_policy_action( $action );
} elsif ( find_macro( $act ) ) {
$action = join( '.', 'macro', $act ) unless $action =~ /^macro\./;
if ( supplied $param ) {
validate_level( $param );
$action = join( ':', $action, $param );
}
} elsif ( $targets{$act} ) {
fatal_error "Invalid setting ($action) for $option";
} else {
fatal_error "Default Action $option=$action not found";
}
my ( $default, $level, $remainder ) = split( /:/, $action, 3 );
fatal_error "Invalid setting ( $action ) for $option" if supplied $remainder;
$action = process_default_action( $action, $option, $default, $level );
}
$default_actions{$map{$option}} = $action;
@ -577,10 +586,12 @@ sub policy_rules( $$$$$ ) {
#
my ( $macro ) = split ':', $default;
( $macro, my $param ) = get_target_param( $macro );
process_macro( $macro, #Macro
$chainref, #Chain
$default, #Target
'', #Param
$param || '', #Param
'-', #Source
'-', #Dest
'-', #Proto
@ -1607,6 +1618,10 @@ sub process_macro ($$$$$$$$$$$$$$$$$$$) {
macro_comment $macro;
my $oldparms = push_action_params( $chainref, $param );
( $param ) = get_action_params( 1 );
my $macrofile = $macros{$macro};
progress_message "..Expanding Macro $macrofile...";
@ -1651,8 +1666,9 @@ sub process_macro ($$$$$$$$$$$$$$$$$$$) {
next;
}
if ( $mtarget eq 'DEFAULT' ) {
$param = $msource unless supplied $param;
if ( $mtarget =~ /^DEFAULTS?$/ ) {
default_action_params( $macro, split_list( $msource, 'defaults' ) );
( $param ) = get_action_params( 1 ) unless supplied $param;
next;
}
@ -1729,6 +1745,8 @@ sub process_macro ($$$$$$$$$$$$$$$$$$$) {
progress_message "..End Macro $macrofile";
pop_action_params( $oldparms );
clear_comment unless $nocomment;
return $generated;
@ -1795,7 +1813,7 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$$ ) {
my $actiontype = $targets{$basictarget} || find_macro ( $basictarget );
if ( $config{ MAPOLDACTIONS } ) {
( $basictarget, $actiontype , $param ) = map_old_actions( $basictarget ) unless $actiontype || $param;
( $basictarget, $actiontype , $param ) = map_old_actions( $basictarget ) unless $actiontype || supplied $param;
}
fatal_error "Unknown ACTION ($action)" unless $actiontype;

View File

@ -91,7 +91,7 @@
role="bold">QUEUE</emphasis>|<emphasis
role="bold">NFQUEUE</emphasis>[(<emphasis>queuenumber</emphasis>)]|<emphasis
role="bold">NONE</emphasis>}[<emphasis
role="bold">:</emphasis>{<emphasis>default-action-or-macro</emphasis>|<emphasis
role="bold">:</emphasis>{<emphasis>default-action-or-macro</emphasis>[:level]|<emphasis
role="bold">None</emphasis>}]</term>
<listitem>
@ -123,10 +123,12 @@
</listitem>
</orderedlist>
<para>Both actions and macros can have parameters specified. In the
case of a macro, only one parameter is allowed and specifies the log
level to be applied to each bare LOG rule (e.g., a rule specifying
'LOG' with no level or tag in the ACTION column).</para>
<para>Both actions and macros can have parameters specified.</para>
<para>Beginning with Shorewall 4.5.10, the macro or action name can
be followed optionally by a colon and a log level. The level will be
applied to each rule in the action or macro body that does not
already have a log level.</para>
<para>Possible actions are:</para>

View File

@ -92,7 +92,7 @@
<variablelist>
<varlistentry>
<term><emphasis
role="bold">ACCEPT_DEFAULT=</emphasis>{<emphasis>action</emphasis>|<emphasis
role="bold">ACCEPT_DEFAULT=</emphasis>{<emphasis>action</emphasis>[(<replaceable>parameters</replaceable>)][:<replaceable>level</replaceable>]|<emphasis
role="bold">none</emphasis>}</term>
<listitem>
@ -102,7 +102,7 @@
<varlistentry>
<term><emphasis
role="bold">DROP_DEFAULT=</emphasis>{<emphasis>action</emphasis>|<emphasis
role="bold">DROP_DEFAULT=</emphasis>{<emphasis>action</emphasis>[(<replaceable>parameters</replaceable>)][:<replaceable>level</replaceable>]|<emphasis
role="bold">none</emphasis>}</term>
<listitem>
@ -112,7 +112,7 @@
<varlistentry>
<term><emphasis
role="bold">NFQUEUE_DEFAULT=</emphasis>{<emphasis>action</emphasis>|<emphasis
role="bold">NFQUEUE_DEFAULT=</emphasis>{<emphasis>action</emphasis>[(<replaceable>parameters</replaceable>)][:<replaceable>level</replaceable>]|<emphasis
role="bold">none</emphasis>}</term>
<listitem>
@ -122,7 +122,7 @@
<varlistentry>
<term><emphasis
role="bold">QUEUE_DEFAULT=</emphasis>{<emphasis>action</emphasis>|<emphasis
role="bold">QUEUE_DEFAULT=</emphasis>{<emphasis>action</emphasis>[(<replaceable>parameters</replaceable>)][:<replaceable>level</replaceable>]|<emphasis
role="bold">none</emphasis>}</term>
<listitem>
@ -132,7 +132,7 @@
<varlistentry>
<term><emphasis
role="bold">REJECT_DEFAULT=</emphasis>{<emphasis>action</emphasis>|<emphasis
role="bold">REJECT_DEFAULT=</emphasis>{<emphasis>action</emphasis>[(<replaceable>parameters</replaceable>)][:<replaceable>level</replaceable>]|<emphasis
role="bold">none</emphasis>}</term>
<listitem>
@ -190,10 +190,15 @@
specify the name of the macro file (e.g., <emphasis
role="bold">macro.</emphasis><replaceable>macro-name</replaceable>).</para>
<para>You can pass parameters to the specified action or macro
(e.g., <emphasis>myaction(audit,DROP)</emphasis>). In the case of a
macro, only a single parameter may be passed; that parameter is
interpreted as the log level for rules in the macro body.</para>
<para>You can pass <replaceable>parameters</replaceable> to the
specified action or macro (e.g.,
<emphasis>myaction(audit,DROP)</emphasis>).</para>
<para>Beginning with Shorewall 4.5.10, the macro or action name can
be followed optionally by a colon and a log
<replaceable>level</replaceable>. The level will be applied to each
rule in the action or macro body that does not already have a log
level.</para>
</listitem>
</varlistentry>

View File

@ -123,10 +123,10 @@
</listitem>
</orderedlist>
<para>Both actions and macros can have parameters specified. In the
case of a macro, only one parameter is allowed and specifies the log
level to be applied to each bare LOG rule (e.g., a rule specifying
'LOG' with no level or tag in the ACTION column).</para>
<para>Beginning with Shorewall 4.5.10, the macro or action name can
be followed optionally by a colon and a log level. The level will be
applied to each rule in the action or macro body that does not
already have a log level.</para>
<para>Possible actions are:</para>

View File

@ -78,7 +78,7 @@
<variablelist>
<varlistentry>
<term><emphasis
role="bold">ACCEPT_DEFAULT=</emphasis>{<emphasis>action</emphasis>|<emphasis
role="bold">ACCEPT_DEFAULT=</emphasis>{<emphasis>action</emphasis>[(<replaceable>parameters</replaceable>)][:<replaceable>level</replaceable>]|<emphasis
role="bold">none</emphasis>}</term>
<listitem>
@ -88,7 +88,7 @@
<varlistentry>
<term><emphasis
role="bold">DROP_DEFAULT=</emphasis>{<emphasis>action</emphasis>|<emphasis
role="bold">DROP_DEFAULT=</emphasis>{<emphasis>action</emphasis>[(<replaceable>parameters</replaceable>)][:<replaceable>level</replaceable>]|<emphasis
role="bold">none</emphasis>}</term>
<listitem>
@ -98,7 +98,7 @@
<varlistentry>
<term><emphasis
role="bold">NFQUEUE_DEFAULT=</emphasis>{<emphasis>action</emphasis>|<emphasis
role="bold">NFQUEUE_DEFAULT=</emphasis>{<emphasis>action</emphasis>[(<replaceable>parameters</replaceable>)][:<replaceable>level</replaceable>]|<emphasis
role="bold">none</emphasis>}</term>
<listitem>
@ -108,7 +108,7 @@
<varlistentry>
<term><emphasis
role="bold">QUEUE_DEFAULT=</emphasis>{<emphasis>action</emphasis>|<emphasis
role="bold">QUEUE_DEFAULT=</emphasis>{<emphasis>action</emphasis>[(<replaceable>parameters</replaceable>)][:<replaceable>level</replaceable>]|<emphasis
role="bold">none</emphasis>}</term>
<listitem>
@ -118,7 +118,7 @@
<varlistentry>
<term><emphasis
role="bold">REJECT_DEFAULT=</emphasis>{<emphasis>action</emphasis>|<emphasis
role="bold">REJECT_DEFAULT=</emphasis>{<emphasis>action</emphasis>[(<replaceable>parameters</replaceable>)][:<replaceable>level</replaceable>]|<emphasis
role="bold">none</emphasis>}</term>
<listitem>
@ -168,10 +168,15 @@
specify the name of the macro file here (e.g., <emphasis
role="bold">macro.</emphasis><replaceable>macro-name</replaceable>).</para>
<para>You can pass parameters to the specified action or macro
(e.g., <emphasis>myaction(audit,DROP)</emphasis>). In the case of a
macro, only a single parameter may be passed; that parameter is
interpreted as the log level for rules in the macro body.</para>
<para>You can pass <replaceable>parameters</replaceable> to the
specified action or macro (e.g.,
<emphasis>myaction(audit,DROP)</emphasis>).</para>
<para>Beginning with Shorewall 4.5.10, the macro or action name can
be followed optionally by a colon and a log
<replaceable>level</replaceable>. The level will be applied to each
rule in the action or macro body that does not already have a log
level.</para>
</listitem>
</varlistentry>

View File

@ -291,6 +291,21 @@ ACCEPT fw loc tcp 135,139,445</programlisting>
<para>Beginning with Shorewall 4.5.10, macros may also be used as <ulink
url="Actions.html#Default">default actions</ulink>.</para>
<para>Also beginning with Shorewall 4.5.10, you may pass multiple
parameters in a macro invocation. Within the macro body, $1 expands to
the value of the first parameter, $2 expands to the value of the second
and so on.</para>
<para>You can specify default values for parameters using a DEFAULT or
DEFAULTS line.</para>
<programlisting>DEFAULTS <replaceable>def1</replaceable>,<replaceable>def2</replaceable>,...</programlisting>
<para>where <replaceable>def1</replaceable> is the default value for the
first parameter, <replaceable>def2</replaceable> is the default value
for the second parameter and so on. You can specify an empty default
using '-' (e.g. DEFAULTS DROP,-,audit).</para>
</section>
<section>