xref: /titanic_51/usr/src/cmd/svc/shell/ipf_include.sh (revision 6a490867f28ff4ed3fa0e392eabf5d24b9068e70)
1eb1a3463STruong Nguyen#!/sbin/sh
2eb1a3463STruong Nguyen#
3eb1a3463STruong Nguyen# CDDL HEADER START
4eb1a3463STruong Nguyen#
5eb1a3463STruong Nguyen# The contents of this file are subject to the terms of the
6eb1a3463STruong Nguyen# Common Development and Distribution License (the "License").
7eb1a3463STruong Nguyen# You may not use this file except in compliance with the License.
8eb1a3463STruong Nguyen#
9eb1a3463STruong Nguyen# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10eb1a3463STruong Nguyen# or http://www.opensolaris.org/os/licensing.
11eb1a3463STruong Nguyen# See the License for the specific language governing permissions
12eb1a3463STruong Nguyen# and limitations under the License.
13eb1a3463STruong Nguyen#
14eb1a3463STruong Nguyen# When distributing Covered Code, include this CDDL HEADER in each
15eb1a3463STruong Nguyen# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16eb1a3463STruong Nguyen# If applicable, add the following below this CDDL HEADER, with the
17eb1a3463STruong Nguyen# fields enclosed by brackets "[]" replaced with your own identifying
18eb1a3463STruong Nguyen# information: Portions Copyright [yyyy] [name of copyright owner]
19eb1a3463STruong Nguyen#
20eb1a3463STruong Nguyen# CDDL HEADER END
21eb1a3463STruong Nguyen#
22ea7d3b1aSTruong Nguyen# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
237ddce999SHans Rosenfeld# Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
24eb1a3463STruong Nguyen#
25eb1a3463STruong Nguyen
266ba597c5SAnurag S. MaskeyIPFILTER_FMRI="svc:/network/ipfilter:default"
27eb1a3463STruong NguyenETC_IPF_DIR=/etc/ipf
286ba597c5SAnurag S. MaskeyIPNATCONF=`/usr/bin/svcprop -p config/ipnat_config_file $IPFILTER_FMRI \
296ba597c5SAnurag S. Maskey    2>/dev/null`
306ba597c5SAnurag S. Maskeyif [ $? -eq 1 ]; then
31eb1a3463STruong Nguyen	IPNATCONF=$ETC_IPF_DIR/ipnat.conf
326ba597c5SAnurag S. Maskeyfi
336ba597c5SAnurag S. MaskeyIPPOOLCONF=`/usr/bin/svcprop -p config/ippool_config_file $IPFILTER_FMRI \
346ba597c5SAnurag S. Maskey    2>/dev/null`
356ba597c5SAnurag S. Maskeyif [ $? -eq 1 ]; then
36eb1a3463STruong Nguyen	IPPOOLCONF=$ETC_IPF_DIR/ippool.conf
376ba597c5SAnurag S. Maskeyfi
38ada83f08STruong NguyenVAR_IPF_DIR=/var/run/ipf
39eb1a3463STruong NguyenIPFILCONF=$VAR_IPF_DIR/ipf.conf
407ddce999SHans RosenfeldIP6FILCONF=$VAR_IPF_DIR/ipf6.conf
41eb1a3463STruong NguyenIPFILOVRCONF=$VAR_IPF_DIR/ipf_ovr.conf
427ddce999SHans RosenfeldIP6FILOVRCONF=$VAR_IPF_DIR/ipf6_ovr.conf
43eb1a3463STruong NguyenIPF_LOCK=/var/run/ipflock
44eb1a3463STruong NguyenCONF_FILES=""
457ddce999SHans RosenfeldCONF6_FILES=""
46eb1a3463STruong NguyenNAT_FILES=""
47eb1a3463STruong NguyenIPF_SUFFIX=".ipf"
487ddce999SHans RosenfeldIPF6_SUFFIX=".ipf6"
49eb1a3463STruong NguyenNAT_SUFFIX=".nat"
50eb1a3463STruong Nguyen
51eb1a3463STruong Nguyen# version for configuration upgrades
52eb1a3463STruong NguyenCURRENT_VERSION=1
53eb1a3463STruong Nguyen
54eb1a3463STruong NguyenIPF_FMRI="svc:/network/ipfilter:default"
55eb1a3463STruong NguyenINETDFMRI="svc:/network/inetd:default"
56eb1a3463STruong NguyenRPCBINDFMRI="svc:/network/rpc/bind:default"
57eb1a3463STruong Nguyen
58eb1a3463STruong NguyenSMF_ONLINE="online"
59eb1a3463STruong NguyenSMF_MAINT="maintenance"
60eb1a3463STruong NguyenSMF_NONE="none"
61eb1a3463STruong Nguyen
62eb1a3463STruong NguyenFW_CONTEXT_PG="firewall_context"
63eb1a3463STruong NguyenMETHOD_PROP="ipf_method"
64eb1a3463STruong Nguyen
65eb1a3463STruong NguyenFW_CONFIG_PG="firewall_config"
66eb1a3463STruong NguyenPOLICY_PROP="policy"
67eb1a3463STruong NguyenAPPLY2_PROP="apply_to"
687ddce999SHans RosenfeldAPPLY2_6_PROP="apply_to_6"
69eb1a3463STruong NguyenEXCEPTIONS_PROP="exceptions"
707ddce999SHans RosenfeldEXCEPTIONS_6_PROP="exceptions_6"
717ddce999SHans RosenfeldTARGET_PROP="target"
727ddce999SHans RosenfeldTARGET_6_PROP="target_6"
737ddce999SHans RosenfeldBLOCKPOL_PROP="block_policy"
74eb1a3463STruong Nguyen
75eb1a3463STruong NguyenFW_CONFIG_DEF_PG="firewall_config_default"
76eb1a3463STruong NguyenFW_CONFIG_OVR_PG="firewall_config_override"
77eb1a3463STruong NguyenCUSTOM_FILE_PROP="custom_policy_file"
787ddce999SHans RosenfeldCUSTOM_FILE_6_PROP="custom_policy_file_6"
79eb1a3463STruong NguyenOPEN_PORTS_PROP="open_ports"
80eb1a3463STruong Nguyen
81eb1a3463STruong NguyenPREFIX_HOST="host:"
82eb1a3463STruong NguyenPREFIX_NET="network:"
83eb1a3463STruong NguyenPREFIX_POOL="pool:"
84eb1a3463STruong NguyenPREFIX_IF="if:"
85eb1a3463STruong Nguyen
866f7d61cdSTruong Q. NguyenGLOBAL_CONFIG=""
876f7d61cdSTruong Q. NguyenGLOBAL_POLICY=""
887ddce999SHans RosenfeldGLOBAL_BLOCK_POLICY=""
896f7d61cdSTruong Q. Nguyen
90eb1a3463STruong NguyenSERVINFO=/usr/lib/servinfo
91eb1a3463STruong Nguyen
92eb1a3463STruong Nguyen#
936f7d61cdSTruong Q. Nguyen# Get value(s) for given property from either firewall_config_default or
946f7d61cdSTruong Q. Nguyen# firewall_config_override property groups.
956f7d61cdSTruong Q. Nguyen#
966f7d61cdSTruong Q. Nguyen# global_get_prop_value pg_name propname
976f7d61cdSTruong Q. Nguyen#   pg_name - FW_CONFIG_DEF_PG or FW_CONFIG_OVR_PG
986f7d61cdSTruong Q. Nguyen#   propname - property name
996f7d61cdSTruong Q. Nguyen#
1006f7d61cdSTruong Q. Nguyenglobal_get_prop_value()
1016f7d61cdSTruong Q. Nguyen{
1026f7d61cdSTruong Q. Nguyen	target_pg=$1
1036f7d61cdSTruong Q. Nguyen	prop=$2
1046f7d61cdSTruong Q. Nguyen
1056f7d61cdSTruong Q. Nguyen	[ "$1" != $FW_CONFIG_OVR_PG -a "$1" != $FW_CONFIG_DEF_PG ] && return
1066f7d61cdSTruong Q. Nguyen
1076f7d61cdSTruong Q. Nguyen	[ "$1" == $FW_CONFIG_DEF_PG ] && extra_pg=$FW_CONFIG_OVR_PG  || \
1086f7d61cdSTruong Q. Nguyen		extra_pg=$FW_CONFIG_DEF_PG
1096f7d61cdSTruong Q. Nguyen
1106f7d61cdSTruong Q. Nguyen	value=`echo $GLOBAL_CONFIG | awk '{
1116f7d61cdSTruong Q. Nguyen		found=0
1126f7d61cdSTruong Q. Nguyen		for (i=1; i<=NF; i++) {
1136f7d61cdSTruong Q. Nguyen			if (found == 1) {
1146f7d61cdSTruong Q. Nguyen				if (index($i, target_pg) == 1 || index($i, extra_pg) == 1)
1156f7d61cdSTruong Q. Nguyen					break;
1166f7d61cdSTruong Q. Nguyen
1176f7d61cdSTruong Q. Nguyen				print $i;
1186f7d61cdSTruong Q. Nguyen			}
1196f7d61cdSTruong Q. Nguyen
1206f7d61cdSTruong Q. Nguyen			if (split($i, values, "/") < 2)
1216f7d61cdSTruong Q. Nguyen				continue;
1226f7d61cdSTruong Q. Nguyen
1236f7d61cdSTruong Q. Nguyen			if (values[1] == target_pg && values[2] == prop)
1246f7d61cdSTruong Q. Nguyen				found=1;
1256f7d61cdSTruong Q. Nguyen		}
1266f7d61cdSTruong Q. Nguyen	}' target_pg=$target_pg prop=$prop extra_pg=$extra_pg`
1276f7d61cdSTruong Q. Nguyen
1286f7d61cdSTruong Q. Nguyen	# Return
1296f7d61cdSTruong Q. Nguyen	echo "$value"
1306f7d61cdSTruong Q. Nguyen}
1316f7d61cdSTruong Q. Nguyen
1326f7d61cdSTruong Q. Nguyen#
1336f7d61cdSTruong Q. Nguyen# Initialize and cache network/ipfilter configuration, global configuration.
1346f7d61cdSTruong Q. Nguyen#
1356f7d61cdSTruong Q. Nguyen# Since an SMF service configuration may get updated during the execution of the
1366f7d61cdSTruong Q. Nguyen# service method, it's best to read all relevant configuration via one svcprop
1376f7d61cdSTruong Q. Nguyen# invocation and cache it for later use.
1386f7d61cdSTruong Q. Nguyen#
1397ddce999SHans Rosenfeld# This function reads and stores relevant configuration into GLOBAL_CONFIG and
1407ddce999SHans Rosenfeld# initializes the GLOBAL_POLICY and GLOBAL_BLOCK_POLICY variables. GLOBAL_CONFIG
1417ddce999SHans Rosenfeld# is a string containing pg/prop and their corresponding values (i.e. svcprop -p
1427ddce999SHans Rosenfeld# pg fmri output). To get values for a certain pg/prop, use
1437ddce999SHans Rosenfeld# global_get_prop_value().
1446f7d61cdSTruong Q. Nguyen#
1456f7d61cdSTruong Q. Nguyenglobal_init()
1466f7d61cdSTruong Q. Nguyen{
1476f7d61cdSTruong Q. Nguyen	GLOBAL_CONFIG=`svcprop -p ${FW_CONFIG_OVR_PG} -p ${FW_CONFIG_DEF_PG} \
1486f7d61cdSTruong Q. Nguyen        $IPF_FMRI 2>/dev/null | awk '{$2=" "; print $0}'`
1496f7d61cdSTruong Q. Nguyen
1506f7d61cdSTruong Q. Nguyen	GLOBAL_POLICY=`global_get_prop_value $FW_CONFIG_DEF_PG $POLICY_PROP`
1517ddce999SHans Rosenfeld        GLOBAL_BLOCK_POLICY=`global_get_prop_value $FW_CONFIG_DEF_PG \
1527ddce999SHans Rosenfeld	   $BLOCKPOL_PROP`
1536f7d61cdSTruong Q. Nguyen}
1546f7d61cdSTruong Q. Nguyen
1556f7d61cdSTruong Q. Nguyen#
156eb1a3463STruong Nguyen# Given a service, gets its config pg name
157eb1a3463STruong Nguyen#
158eb1a3463STruong Nguyenget_config_pg()
159eb1a3463STruong Nguyen{
160eb1a3463STruong Nguyen	if [ "$1" = "$IPF_FMRI" ]; then
161eb1a3463STruong Nguyen		echo "$FW_CONFIG_DEF_PG"
162eb1a3463STruong Nguyen	else
163eb1a3463STruong Nguyen		echo "$FW_CONFIG_PG"
164eb1a3463STruong Nguyen	fi
165eb1a3463STruong Nguyen	return 0
166eb1a3463STruong Nguyen}
167eb1a3463STruong Nguyen
168eb1a3463STruong Nguyen#
169eb1a3463STruong Nguyen# Given a service, gets its firewall policy
170eb1a3463STruong Nguyen#
171eb1a3463STruong Nguyenget_policy()
172eb1a3463STruong Nguyen{
173eb1a3463STruong Nguyen	config_pg=`get_config_pg $1`
174eb1a3463STruong Nguyen	svcprop -p $config_pg/${POLICY_PROP} $1 2>/dev/null
175eb1a3463STruong Nguyen}
176eb1a3463STruong Nguyen
177eb1a3463STruong Nguyen#
1787ddce999SHans Rosenfeld# block policy can be set to "return", which will expand into
1797ddce999SHans Rosenfeld# separate block rules for tcp (block return-rst ...) and all other
1807ddce999SHans Rosenfeld# protocols (block return-icmp-as-dest ...)
1817ddce999SHans Rosenfeld#
1827ddce999SHans Rosenfeldget_block_policy()
1837ddce999SHans Rosenfeld{
1847ddce999SHans Rosenfeld	config_pg=`get_config_pg $1`
1857ddce999SHans Rosenfeld	svcprop -p $config_pg/${BLOCKPOL_PROP} $1 2>/dev/null
1867ddce999SHans Rosenfeld}
1877ddce999SHans Rosenfeld
1887ddce999SHans Rosenfeld#
1897ddce999SHans Rosenfeld# Given a service, gets its source address exceptions for IPv4
190eb1a3463STruong Nguyen#
191eb1a3463STruong Nguyenget_exceptions()
192eb1a3463STruong Nguyen{
193eb1a3463STruong Nguyen	config_pg=`get_config_pg $1`
1947ddce999SHans Rosenfeld	exceptions=`svcprop -p $config_pg/${EXCEPTIONS_PROP} $1 2>/dev/null`
1957ddce999SHans Rosenfeld        echo $exceptions | sed -e 's/\\//g'
196eb1a3463STruong Nguyen}
197eb1a3463STruong Nguyen
198eb1a3463STruong Nguyen#
1997ddce999SHans Rosenfeld# Given a service, gets its source address exceptions for IPv6
2007ddce999SHans Rosenfeld#
2017ddce999SHans Rosenfeldget_exceptions_6()
2027ddce999SHans Rosenfeld{
2037ddce999SHans Rosenfeld	config_pg=`get_config_pg $1`
2047ddce999SHans Rosenfeld	exceptions6=`svcprop -p $config_pg/${EXCEPTIONS_6_PROP} $1 2>/dev/null`
2057ddce999SHans Rosenfeld        echo $exceptions6 | sed -e 's/\\//g'
2067ddce999SHans Rosenfeld}
2077ddce999SHans Rosenfeld
2087ddce999SHans Rosenfeld#
2097ddce999SHans Rosenfeld# Given a service, gets its firewalled source addresses for IPv4
210eb1a3463STruong Nguyen#
211eb1a3463STruong Nguyenget_apply2_list()
212eb1a3463STruong Nguyen{
213eb1a3463STruong Nguyen	config_pg=`get_config_pg $1`
2147ddce999SHans Rosenfeld	apply2=`svcprop -p $config_pg/${APPLY2_PROP} $1 2>/dev/null`
2157ddce999SHans Rosenfeld        echo $apply2 | sed -e 's/\\//g'
2167ddce999SHans Rosenfeld}
2177ddce999SHans Rosenfeld
2187ddce999SHans Rosenfeld#
2197ddce999SHans Rosenfeld# Given a service, gets its firewalled source addresses for IPv6
2207ddce999SHans Rosenfeld#
2217ddce999SHans Rosenfeldget_apply2_6_list()
2227ddce999SHans Rosenfeld{
2237ddce999SHans Rosenfeld	config_pg=`get_config_pg $1`
2247ddce999SHans Rosenfeld	apply2_6=`svcprop -p $config_pg/${APPLY2_6_PROP} $1 2>/dev/null`
2257ddce999SHans Rosenfeld        echo $apply2_6 | sed -e 's/\\//g'
2267ddce999SHans Rosenfeld}
2277ddce999SHans Rosenfeld
2287ddce999SHans Rosenfeld#
2297ddce999SHans Rosenfeld# Given a service, gets its firewalled target addresses for IPv4
2307ddce999SHans Rosenfeld#
2317ddce999SHans Rosenfeldget_target_list()
2327ddce999SHans Rosenfeld{
2337ddce999SHans Rosenfeld	config_pg=`get_config_pg $1`
2347ddce999SHans Rosenfeld	target=`svcprop -p $config_pg/${TARGET_PROP} $1 2>/dev/null`
2357ddce999SHans Rosenfeld	[ -z "$target" -o "$target" = '""' ] && target=any
2367ddce999SHans Rosenfeld	echo $target | sed -e 's/\\//g'
2377ddce999SHans Rosenfeld}
2387ddce999SHans Rosenfeld
2397ddce999SHans Rosenfeld#
2407ddce999SHans Rosenfeld# Given a service, gets its firewalled target addresses for IPv6
2417ddce999SHans Rosenfeld#
2427ddce999SHans Rosenfeldget_target_6_list()
2437ddce999SHans Rosenfeld{
2447ddce999SHans Rosenfeld	config_pg=`get_config_pg $1`
2457ddce999SHans Rosenfeld	target6=`svcprop -p $config_pg/${TARGET_6_PROP} $1 2>/dev/null`
2467ddce999SHans Rosenfeld	[ -z "$target6" -o "$target6" = '""' ] && target6=any
2477ddce999SHans Rosenfeld	echo $target6 | sed -e 's/\\//g'
248eb1a3463STruong Nguyen}
249eb1a3463STruong Nguyen
250eb1a3463STruong Nguyencheck_ipf_dir()
251eb1a3463STruong Nguyen{
252eb1a3463STruong Nguyen	[ -d $VAR_IPF_DIR ] && return 0
253eb1a3463STruong Nguyen	mkdir $VAR_IPF_DIR >/dev/null 2>&1 || return 1
254eb1a3463STruong Nguyen}
255eb1a3463STruong Nguyen
256eb1a3463STruong Nguyen#
257eb1a3463STruong Nguyen# fmri_to_file fmri suffix
258eb1a3463STruong Nguyen#
259eb1a3463STruong Nguyenfmri_to_file()
260eb1a3463STruong Nguyen{
261eb1a3463STruong Nguyen	check_ipf_dir || return 1
262eb1a3463STruong Nguyen	fprefix="${VAR_IPF_DIR}/`echo $1 | tr -s '/:' '__'`"
263eb1a3463STruong Nguyen	echo "${fprefix}${2}"
264eb1a3463STruong Nguyen}
265eb1a3463STruong Nguyen
266eb1a3463STruong Nguyen#
267eb1a3463STruong Nguyen# Return service's enabled property
268eb1a3463STruong Nguyen#
269eb1a3463STruong Nguyenservice_is_enabled()
270eb1a3463STruong Nguyen{
271eb1a3463STruong Nguyen	#
272eb1a3463STruong Nguyen	# Temporary enabled state overrides the persistent state
273eb1a3463STruong Nguyen	# so check it first.
274eb1a3463STruong Nguyen	#
275eb1a3463STruong Nguyen	enabled_ovr=`svcprop -c -p general_ovr/enabled $1 2>/dev/null`
276eb1a3463STruong Nguyen	if [ -n "$enabled_ovr" ]; then
277eb1a3463STruong Nguyen		[ "$enabled_ovr" = "true" ] && return 0 || return 1
278eb1a3463STruong Nguyen	fi
279eb1a3463STruong Nguyen
280eb1a3463STruong Nguyen	enabled=`svcprop -c -p general/enabled $1 2>/dev/null`
281eb1a3463STruong Nguyen	[ -n "$enabled" -a "$enabled" = "true" ] && return 0 || return 1
282eb1a3463STruong Nguyen}
283eb1a3463STruong Nguyen
284eb1a3463STruong Nguyen#
285eb1a3463STruong Nguyen# Return whether service is desired state
286eb1a3463STruong Nguyen#
287eb1a3463STruong Nguyen# Args: fmri state
288eb1a3463STruong Nguyen# Return:
289eb1a3463STruong Nguyen#  0 - desired state is service's current state
290eb1a3463STruong Nguyen#  1 - desired state is not service's current state
291eb1a3463STruong Nguyen#
292eb1a3463STruong Nguyenservice_check_state()
293eb1a3463STruong Nguyen{
294eb1a3463STruong Nguyen	#
295eb1a3463STruong Nguyen	# Make sure we're done with ongoing state transition
296eb1a3463STruong Nguyen	#
297eb1a3463STruong Nguyen	while [ "`svcprop -p restarter/next_state $1`" != "$SMF_NONE" ]; do
298eb1a3463STruong Nguyen		sleep 1
299eb1a3463STruong Nguyen	done
300eb1a3463STruong Nguyen
301eb1a3463STruong Nguyen	[ "`svcprop -p restarter/state $1`" = "$2" ] && return 0 || return 1
302eb1a3463STruong Nguyen}
303eb1a3463STruong Nguyen
304eb1a3463STruong Nguyen#
305eb1a3463STruong Nguyen# Deny/Allow list stores values in the form "host:addr", "network:addr/netmask",
306eb1a3463STruong Nguyen# "pool:number", and "if:interface". This function returns the
307eb1a3463STruong Nguyen# IP(addr or addr/netmask) value or a pool number.
308eb1a3463STruong Nguyen#
309eb1a3463STruong Nguyenget_IP()
310eb1a3463STruong Nguyen{
311eb1a3463STruong Nguyen	value_is_interface $1 && return 1
3127ddce999SHans Rosenfeld	echo "$1" | sed -n -e "s,^${PREFIX_POOL}\(.*\),pool/\1,p" \
3137ddce999SHans Rosenfeld	    -e "s,^${PREFIX_HOST}\(.*\),\1,p" \
3147ddce999SHans Rosenfeld	    -e "s,^${PREFIX_NET}\(.*\),\1,p" \
3157ddce999SHans Rosenfeld	    -e "s,^any,any,p"
316eb1a3463STruong Nguyen}
317eb1a3463STruong Nguyen
318eb1a3463STruong Nguyenget_interface()
319eb1a3463STruong Nguyen{
320eb1a3463STruong Nguyen	value_is_interface $1 || return 1
3217ddce999SHans Rosenfeld	scratch=`echo "$1" | sed -e "s/^${PREFIX_IF}//"`
322eb1a3463STruong Nguyen
323eb1a3463STruong Nguyen	ifconfig $scratch >/dev/null 2>&1 || return 1
324eb1a3463STruong Nguyen	echo $scratch | sed -e 's/:.*//'
325eb1a3463STruong Nguyen}
326eb1a3463STruong Nguyen
327eb1a3463STruong Nguyen#
328eb1a3463STruong Nguyen#
329eb1a3463STruong Nguyen#
330eb1a3463STruong Nguyenvalue_is_interface()
331eb1a3463STruong Nguyen{
332eb1a3463STruong Nguyen	[ -z "$1" ] && return 1
3337ddce999SHans Rosenfeld	echo $1 | grep "^${PREFIX_IF}" >/dev/null 2>&1
334eb1a3463STruong Nguyen}
335eb1a3463STruong Nguyen
336eb1a3463STruong Nguyen#
337eb1a3463STruong Nguyen# Remove rules in given file from active list without restarting ipfilter
338eb1a3463STruong Nguyen#
339eb1a3463STruong Nguyenremove_rules()
340eb1a3463STruong Nguyen{
3417ddce999SHans Rosenfeld	[ -f "$1" ] && ipf $2 -r -f $1 >/dev/null 2>&1
342eb1a3463STruong Nguyen}
343eb1a3463STruong Nguyen
344eb1a3463STruong Nguyenremove_nat_rules()
345eb1a3463STruong Nguyen{
346eb1a3463STruong Nguyen	[ -f "$1" ] && ipnat -r -f $1 >/dev/null 2>&1
347eb1a3463STruong Nguyen}
348eb1a3463STruong Nguyen
349eb1a3463STruong Nguyencheck_ipf_syntax()
350eb1a3463STruong Nguyen{
3517ddce999SHans Rosenfeld	ipf $2 -n -f $1 >/dev/null 2>&1
352eb1a3463STruong Nguyen}
353eb1a3463STruong Nguyen
354eb1a3463STruong Nguyencheck_nat_syntax()
355eb1a3463STruong Nguyen{
356eb1a3463STruong Nguyen	ipnat -n -f $1 >/dev/null 2>&1
357eb1a3463STruong Nguyen}
358eb1a3463STruong Nguyen
3597ddce999SHans Rosenfeldunique_ports()
3607ddce999SHans Rosenfeld{
3617ddce999SHans Rosenfeld	echo $* | xargs -n 1 echo | sort -u
3627ddce999SHans Rosenfeld}
3637ddce999SHans Rosenfeld
364eb1a3463STruong Nguyenfile_get_ports()
365eb1a3463STruong Nguyen{
3667ddce999SHans Rosenfeld	ipf $2 -n -v -f $1 2>/dev/null | sed -n -e \
367eb1a3463STruong Nguyen	    's/.*to.* port = \([a-z0-9]*\).*/\1/p' | uniq | \
368eb1a3463STruong Nguyen	    awk '{if (length($0) > 1) {printf("%s ", $1)}}'
369eb1a3463STruong Nguyen}
370eb1a3463STruong Nguyen
371eb1a3463STruong Nguyenget_active_ports()
372eb1a3463STruong Nguyen{
3737ddce999SHans Rosenfeld	ipfstat $1 -io 2>/dev/null | sed -n -e \
374eb1a3463STruong Nguyen	    's/.*to.* port = \([a-z0-9]*\).*/\1/p' | uniq | \
375eb1a3463STruong Nguyen	    awk '{if (length($0) > 1) {printf("%s ",$1)}}'
376eb1a3463STruong Nguyen}
377eb1a3463STruong Nguyen
378eb1a3463STruong Nguyen#
379eb1a3463STruong Nguyen# Given two list of ports, return failure if there's a duplicate.
380eb1a3463STruong Nguyen#
381eb1a3463STruong Nguyensets_check_duplicate()
382eb1a3463STruong Nguyen{
383eb1a3463STruong Nguyen	#
384eb1a3463STruong Nguyen	# If either list is empty, there isn't any conflict.
385eb1a3463STruong Nguyen	#
386eb1a3463STruong Nguyen	[ -z "$1" -o -z "$2" ] && return 0
387eb1a3463STruong Nguyen
388eb1a3463STruong Nguyen	for p in $1; do
389eb1a3463STruong Nguyen		for ap in $2; do
390eb1a3463STruong Nguyen			[ "$p" = "$ap" ] && return 1
391eb1a3463STruong Nguyen		done
392eb1a3463STruong Nguyen	done
393eb1a3463STruong Nguyen
394eb1a3463STruong Nguyen	return 0
395eb1a3463STruong Nguyen}
396eb1a3463STruong Nguyen
397eb1a3463STruong Nguyen#
398eb1a3463STruong Nguyen# Given a file containing ipf rules, check the syntax and verify
399eb1a3463STruong Nguyen# the rules don't conflict, use same port number, with active
400eb1a3463STruong Nguyen# rules (ipfstat -io output).
401eb1a3463STruong Nguyen#
402eb1a3463STruong Nguyenupdate_check_ipf_rules()
403eb1a3463STruong Nguyen{
4047ddce999SHans Rosenfeld	check_ipf_syntax $1 $2 || return 1
405eb1a3463STruong Nguyen
4067ddce999SHans Rosenfeld	lports=`file_get_ports $1 $2`
4077ddce999SHans Rosenfeld	lactive_ports=`get_active_ports $2`
408eb1a3463STruong Nguyen
409eb1a3463STruong Nguyen	sets_check_duplicate "$lports" "$lactive_ports" || return 1
410eb1a3463STruong Nguyen}
411eb1a3463STruong Nguyen
412eb1a3463STruong Nguyenserver_port_list=""
4137ddce999SHans Rosenfeldserver_port_list_6=""
414eb1a3463STruong Nguyen
415eb1a3463STruong Nguyen#
416eb1a3463STruong Nguyen# Given a file containing ipf rules, check the syntax and verify
417eb1a3463STruong Nguyen# the rules don't conflict with already processed services.
418eb1a3463STruong Nguyen#
419eb1a3463STruong Nguyen# The list of processed services' ports are maintained in the global
4207ddce999SHans Rosenfeld# variables 'server_port_list' and 'server_port_list_6'.
421eb1a3463STruong Nguyen#
422eb1a3463STruong Nguyencheck_ipf_rules()
423eb1a3463STruong Nguyen{
424eb1a3463STruong Nguyen
4257ddce999SHans Rosenfeld	check_ipf_syntax $1 $2 || return 1
4267ddce999SHans Rosenfeld
4277ddce999SHans Rosenfeld	lports=`file_get_ports $1 $2`
4287ddce999SHans Rosenfeld
4297ddce999SHans Rosenfeld	if [ "$2" = "-6" ]; then
4307ddce999SHans Rosenfeld		sets_check_duplicate "$lports" "$server_port_list_6" || return 1
4317ddce999SHans Rosenfeld	        server_port_list_6="$server_port_list_6 $lports"
4327ddce999SHans Rosenfeld	else
433eb1a3463STruong Nguyen		sets_check_duplicate "$lports" "$server_port_list" || return 1
434eb1a3463STruong Nguyen	        server_port_list="$server_port_list $lports"
4357ddce999SHans Rosenfeld	fi
4367ddce999SHans Rosenfeld
437eb1a3463STruong Nguyen	return 0
438eb1a3463STruong Nguyen}
439eb1a3463STruong Nguyen
440eb1a3463STruong Nguyenprepend_new_rules()
441eb1a3463STruong Nguyen{
4427ddce999SHans Rosenfeld	check_ipf_syntax $1 $2 && tail -r $1 | sed -e 's/^[a-z]/@0 &/' | \
4437ddce999SHans Rosenfeld	    ipf $2 -f - >/dev/null 2>&1
444eb1a3463STruong Nguyen}
445eb1a3463STruong Nguyen
446eb1a3463STruong Nguyenappend_new_rules()
447eb1a3463STruong Nguyen{
4487ddce999SHans Rosenfeld	check_ipf_syntax $1 $2 && ipf $2 -f $1 >/dev/null 2>&1
449eb1a3463STruong Nguyen}
450eb1a3463STruong Nguyen
451eb1a3463STruong Nguyenappend_new_nat_rules()
452eb1a3463STruong Nguyen{
453eb1a3463STruong Nguyen	check_nat_syntax $1 && ipnat -f $1 >/dev/null 2>&1
454eb1a3463STruong Nguyen}
455eb1a3463STruong Nguyen
456eb1a3463STruong Nguyen#
457eb1a3463STruong Nguyen# get port information from string of the form "proto:{port | port-port}"
458eb1a3463STruong Nguyen#
459eb1a3463STruong Nguyentuple_get_port()
460eb1a3463STruong Nguyen{
461*6a490867SHans Rosenfeld	port_str=`echo "$1" | sed -e 's/ //g; s/\\\//g; s/.*://' 2>/dev/null`
462eb1a3463STruong Nguyen	[ -z "$port_str" ] && return 1
463eb1a3463STruong Nguyen
464eb1a3463STruong Nguyen	echo $port_str | grep "-" >/dev/null
465eb1a3463STruong Nguyen	if  [ $? -eq  0 ]; then
466eb1a3463STruong Nguyen		echo $port_str | grep '^[0-9]\{1,5\}-[0-9]\{1,5\}$' >/dev/null || \
467eb1a3463STruong Nguyen		    return 1
468eb1a3463STruong Nguyen		ports=`echo $port_str | ( IFS=- read a b ; \
469eb1a3463STruong Nguyen		    [ $a \-le $b ] && echo $a $b || echo $b $a )`
470eb1a3463STruong Nguyen
471eb1a3463STruong Nguyen		for p in $ports; do
472eb1a3463STruong Nguyen			[ $p -gt 65535 ] && return 1
473eb1a3463STruong Nguyen		done
474eb1a3463STruong Nguyen		echo "$ports"
475eb1a3463STruong Nguyen	else
476eb1a3463STruong Nguyen		#
477eb1a3463STruong Nguyen		# port_str is a single port, verify and return it.
478eb1a3463STruong Nguyen		#
479eb1a3463STruong Nguyen		echo "$port_str" | grep '^[0-9]\{1,5\}$' >/dev/null || return 1
480eb1a3463STruong Nguyen		[ $port_str -gt 65535 ] && return 1
481eb1a3463STruong Nguyen		echo "$port_str"
482eb1a3463STruong Nguyen	fi
483eb1a3463STruong Nguyen}
484eb1a3463STruong Nguyen
485eb1a3463STruong Nguyen#
486eb1a3463STruong Nguyen# get proto info from string of the form "{tcp | udp}:port"
487eb1a3463STruong Nguyen#
488eb1a3463STruong Nguyentuple_get_proto()
489eb1a3463STruong Nguyen{
490eb1a3463STruong Nguyen	proto=`echo "$1" | sed -e 's/ //g; s/:.*//' 2>/dev/null`
491eb1a3463STruong Nguyen	[ -z "$proto" ] && return 0
492eb1a3463STruong Nguyen
493eb1a3463STruong Nguyen	[ "$proto" = "tcp" -o "$proto" = "udp" ] && echo $proto || return 1
494eb1a3463STruong Nguyen	return 0
495eb1a3463STruong Nguyen}
496eb1a3463STruong Nguyen
497eb1a3463STruong Nguyenipf_get_lock()
498eb1a3463STruong Nguyen{
499eb1a3463STruong Nguyen	newpid=$$
500eb1a3463STruong Nguyen
501eb1a3463STruong Nguyen	if [ -f "$IPF_LOCK/pid" ]; then
502eb1a3463STruong Nguyen		curpid=`cat $IPF_LOCK/pid 2>/dev/null`
503eb1a3463STruong Nguyen		[ "$curpid" = "$newpid" ] && return 0
504eb1a3463STruong Nguyen
505eb1a3463STruong Nguyen		#
506eb1a3463STruong Nguyen		# Clear lock if the owning process is no longer around.
507eb1a3463STruong Nguyen		#
508eb1a3463STruong Nguyen		ps -p $curpid >/dev/null 2>&1 || rm -r $IPF_LOCK >/dev/null 2>&1
509eb1a3463STruong Nguyen	fi
510eb1a3463STruong Nguyen
511eb1a3463STruong Nguyen	#
512eb1a3463STruong Nguyen	# Grab the lock
513eb1a3463STruong Nguyen	#
514eb1a3463STruong Nguyen	while :; do
515eb1a3463STruong Nguyen		mkdir $IPF_LOCK 2>/dev/null && break;
516eb1a3463STruong Nguyen		sleep 1
517eb1a3463STruong Nguyen	done
518eb1a3463STruong Nguyen	echo $newpid > $IPF_LOCK/pid
519eb1a3463STruong Nguyen}
520eb1a3463STruong Nguyen
521eb1a3463STruong Nguyen#
522eb1a3463STruong Nguyen# Remove lock if it's ours
523eb1a3463STruong Nguyen#
524eb1a3463STruong Nguyenipf_remove_lock()
525eb1a3463STruong Nguyen{
526eb1a3463STruong Nguyen	if [ -f "$IPF_LOCK/pid" ]; then
527eb1a3463STruong Nguyen		[ "`cat $IPF_LOCK/pid`" = "$$" ] && rm -r $IPF_LOCK
528eb1a3463STruong Nguyen	fi
529eb1a3463STruong Nguyen	return 0
530eb1a3463STruong Nguyen}
531eb1a3463STruong Nguyen
532eb1a3463STruong Nguyen#
533eb1a3463STruong Nguyen# Make IPFILCONF, /var/tmp/ipf/ipf.conf, a symlink to the input file argument.
534eb1a3463STruong Nguyen#
535eb1a3463STruong Nguyencustom_set_symlink()
536eb1a3463STruong Nguyen{
537eb1a3463STruong Nguyen	#
538caa64d54STruong Nguyen	# Nothing to do if the input file doesn't exist.
539eb1a3463STruong Nguyen	#
540eb1a3463STruong Nguyen	[ ! -f "$1" ] && return 0
541eb1a3463STruong Nguyen
542caa64d54STruong Nguyen	check_ipf_dir || return 1
543caa64d54STruong Nguyen
544eb1a3463STruong Nguyen	rm $IPFILCONF >/dev/null 2>&1
545eb1a3463STruong Nguyen	ln -s $1 $IPFILCONF >/dev/null 2>&1
546eb1a3463STruong Nguyen}
547eb1a3463STruong Nguyen
548eb1a3463STruong Nguyen#
549*6a490867SHans Rosenfeld# Make IP6FILCONF, /var/tmp/ipf/ipf6.conf, a symlink to the input file argument.
550*6a490867SHans Rosenfeld#
551*6a490867SHans Rosenfeldcustom_set_symlink_6()
552*6a490867SHans Rosenfeld{
553*6a490867SHans Rosenfeld	#
554*6a490867SHans Rosenfeld	# Nothing to do if the input file doesn't exist.
555*6a490867SHans Rosenfeld	#
556*6a490867SHans Rosenfeld	[ ! -f "$1" ] && return 0
557*6a490867SHans Rosenfeld
558*6a490867SHans Rosenfeld	check_ipf_dir || return 1
559*6a490867SHans Rosenfeld
560*6a490867SHans Rosenfeld	rm $IP6FILCONF >/dev/null 2>&1
561*6a490867SHans Rosenfeld	ln -s $1 $IP6FILCONF >/dev/null 2>&1
562*6a490867SHans Rosenfeld}
563*6a490867SHans Rosenfeld
564*6a490867SHans Rosenfeld#
565eb1a3463STruong Nguyen# New file replaces original file if they have different content
566eb1a3463STruong Nguyen#
567eb1a3463STruong Nguyenreplace_file()
568eb1a3463STruong Nguyen{
569eb1a3463STruong Nguyen	orig=$1
570eb1a3463STruong Nguyen	new=$2
571eb1a3463STruong Nguyen
572eb1a3463STruong Nguyen	#
573eb1a3463STruong Nguyen	# IPFILCONF may be a symlink, remove it if that's the case
574eb1a3463STruong Nguyen	#
575eb1a3463STruong Nguyen	if [ -L "$orig" ]; then
576eb1a3463STruong Nguyen		rm $orig
577eb1a3463STruong Nguyen		touch $orig
578eb1a3463STruong Nguyen	fi
579eb1a3463STruong Nguyen
580caa64d54STruong Nguyen	check_ipf_dir || return 1
581eb1a3463STruong Nguyen	mv $new $orig && return 0 || return 1
582eb1a3463STruong Nguyen}
583eb1a3463STruong Nguyen
584eb1a3463STruong Nguyen#
585eb1a3463STruong Nguyen# Given a service, gets the following details for ipf rule:
586eb1a3463STruong Nguyen# - policy
587eb1a3463STruong Nguyen# - protocol
588eb1a3463STruong Nguyen# - port(IANA port obtained by running servinfo)
589eb1a3463STruong Nguyen#
590eb1a3463STruong Nguyenprocess_server_svc()
591eb1a3463STruong Nguyen{
592eb1a3463STruong Nguyen	service=$1
593eb1a3463STruong Nguyen        policy=`get_policy ${service}`
594eb1a3463STruong Nguyen
595eb1a3463STruong Nguyen	#
596eb1a3463STruong Nguyen	# Empties service's rules file so callers won't use existing rule if
597eb1a3463STruong Nguyen	# we fail here.
598eb1a3463STruong Nguyen	#
599eb1a3463STruong Nguyen	file=`fmri_to_file $service $IPF_SUFFIX`
6007ddce999SHans Rosenfeld	file6=`fmri_to_file $service $IPF6_SUFFIX`
601eb1a3463STruong Nguyen	[ -z "$file" ] && return 1
602eb1a3463STruong Nguyen	echo "# $service" >${file}
6037ddce999SHans Rosenfeld	echo "# $service" >${file6}
604eb1a3463STruong Nguyen
605eb1a3463STruong Nguyen	#
606eb1a3463STruong Nguyen	# Nothing to do if policy is "use_global"
607eb1a3463STruong Nguyen	#
608eb1a3463STruong Nguyen	[ "$policy" = "use_global" ] && return 0
609eb1a3463STruong Nguyen
610eb1a3463STruong Nguyen	restarter=`svcprop -p general/restarter $service 2>/dev/null`
611eb1a3463STruong Nguyen	if [ "$restarter" = "$INETDFMRI" ]; then
612eb1a3463STruong Nguyen		iana_name=`svcprop -p inetd/name $service 2>/dev/null`
613eb1a3463STruong Nguyen		isrpc=`svcprop -p inetd/isrpc $service 2>/dev/null`
614eb1a3463STruong Nguyen	else
615eb1a3463STruong Nguyen		iana_name=`svcprop -p $FW_CONTEXT_PG/name $service 2>/dev/null`
616eb1a3463STruong Nguyen		isrpc=`svcprop -p $FW_CONTEXT_PG/isrpc $service 2>/dev/null`
617eb1a3463STruong Nguyen	fi
618eb1a3463STruong Nguyen
619eb1a3463STruong Nguyen	#
620eb1a3463STruong Nguyen	# Bail if iana_name isn't defined. Services with static rules
621eb1a3463STruong Nguyen	# like nis/client don't need to generate rules using
622eb1a3463STruong Nguyen	# iana name and protocol information.
623eb1a3463STruong Nguyen	#
624eb1a3463STruong Nguyen	[ -z "$iana_name" ] && return 1
625eb1a3463STruong Nguyen
626eb1a3463STruong Nguyen	#
627eb1a3463STruong Nguyen	# RPC services
628eb1a3463STruong Nguyen	#
629eb1a3463STruong Nguyen	if [ "$isrpc" = "true" ]; then
6307ddce999SHans Rosenfeld		# The ports used for IPv6 are usually also reachable
6317ddce999SHans Rosenfeld		# through IPv4, so generate IPv4 rules for them, too.
632eb1a3463STruong Nguyen		tports=`$SERVINFO -R -p -t -s $iana_name 2>/dev/null`
6337ddce999SHans Rosenfeld		tports6=`$SERVINFO -R -p -t6 -s $iana_name 2>/dev/null`
6347ddce999SHans Rosenfeld		if [ -n "$tports" -o -n "$tports6" ]; then
6357ddce999SHans Rosenfeld			tports=`unique_ports $tports $tports6`
636eb1a3463STruong Nguyen			for tport in $tports; do
637eb1a3463STruong Nguyen				generate_rules $service $policy "tcp" \
6387ddce999SHans Rosenfeld				    $tport $file
6397ddce999SHans Rosenfeld			done
6407ddce999SHans Rosenfeld		fi
6417ddce999SHans Rosenfeld
6427ddce999SHans Rosenfeld		if [ -n "$tports6" ]; then
6437ddce999SHans Rosenfeld			for tport6 in $tports6; do
6447ddce999SHans Rosenfeld				generate_rules $service $policy "tcp" \
6457ddce999SHans Rosenfeld				    $tport6 $file6 _6
646eb1a3463STruong Nguyen			done
647eb1a3463STruong Nguyen		fi
648eb1a3463STruong Nguyen
649eb1a3463STruong Nguyen		uports=`$SERVINFO -R -p -u -s $iana_name 2>/dev/null`
6507ddce999SHans Rosenfeld		uports6=`$SERVINFO -R -p -u6 -s $iana_name 2>/dev/null`
651eb1a3463STruong Nguyen		if [ -n "$uports" ]; then
6527ddce999SHans Rosenfeld			uports=`unique_ports $uports $uports6`
653eb1a3463STruong Nguyen			for uport in $uports; do
654eb1a3463STruong Nguyen				generate_rules $service $policy "udp" \
6557ddce999SHans Rosenfeld				    $uport $file
6567ddce999SHans Rosenfeld			done
6577ddce999SHans Rosenfeld		fi
6587ddce999SHans Rosenfeld
6597ddce999SHans Rosenfeld		if [ -n "$uports6" ]; then
6607ddce999SHans Rosenfeld			for uport6 in $uports6; do
6617ddce999SHans Rosenfeld				generate_rules $service $policy "udp" \
6627ddce999SHans Rosenfeld				    $uport6 $file6 _6
663eb1a3463STruong Nguyen			done
664eb1a3463STruong Nguyen		fi
665eb1a3463STruong Nguyen
666eb1a3463STruong Nguyen		return 0
667eb1a3463STruong Nguyen	fi
668eb1a3463STruong Nguyen
669eb1a3463STruong Nguyen	#
670eb1a3463STruong Nguyen	# Get the IANA port and supported protocols(tcp and udp)
671eb1a3463STruong Nguyen	#
672eb1a3463STruong Nguyen	tport=`$SERVINFO -p -t -s $iana_name 2>&1`
673eb1a3463STruong Nguyen	if [ $? -eq 0 -a -n "$tport" ]; then
6747ddce999SHans Rosenfeld		generate_rules $service $policy "tcp" $tport $file
6757ddce999SHans Rosenfeld	fi
6767ddce999SHans Rosenfeld
6777ddce999SHans Rosenfeld	tport6=`$SERVINFO -p -t6 -s $iana_name 2>&1`
6787ddce999SHans Rosenfeld	if [ $? -eq 0 -a -n "$tport6" ]; then
6797ddce999SHans Rosenfeld		generate_rules $service $policy "tcp" $tport6 $file6 _6
680eb1a3463STruong Nguyen	fi
681eb1a3463STruong Nguyen
682eb1a3463STruong Nguyen	uport=`$SERVINFO -p -u -s $iana_name 2>&1`
683eb1a3463STruong Nguyen	if [ $? -eq 0 -a -n "$uport" ]; then
6847ddce999SHans Rosenfeld		generate_rules $service $policy "udp" $uport $file
6857ddce999SHans Rosenfeld	fi
6867ddce999SHans Rosenfeld
6877ddce999SHans Rosenfeld	uport6=`$SERVINFO -p -u6 -s $iana_name 2>&1`
6887ddce999SHans Rosenfeld	if [ $? -eq 0 -a -n "$uport6" ]; then
6897ddce999SHans Rosenfeld		generate_rules $service $policy "udp" $uport6 $file6 _6
690eb1a3463STruong Nguyen	fi
691eb1a3463STruong Nguyen
692eb1a3463STruong Nguyen	return 0
693eb1a3463STruong Nguyen}
694eb1a3463STruong Nguyen
695eb1a3463STruong Nguyen#
696eb1a3463STruong Nguyen# Given a service's name, policy, protocol and port, generate ipf rules
697eb1a3463STruong Nguyen# - list of host/network/interface to apply policy
698eb1a3463STruong Nguyen#
699eb1a3463STruong Nguyen# A 'use_global' policy inherits the system-wided Global Default policy
700eb1a3463STruong Nguyen# from network/ipfilter. For {deny | allow} policies, the rules are
701eb1a3463STruong Nguyen# ordered as:
702eb1a3463STruong Nguyen#
703eb1a3463STruong Nguyen# - make exceptions to policy for those in "exceptions" list
704eb1a3463STruong Nguyen# - apply policy to those specified in "apply_to" list
705eb1a3463STruong Nguyen# - policy rule
706eb1a3463STruong Nguyen#
707eb1a3463STruong Nguyengenerate_rules()
708eb1a3463STruong Nguyen{
709eb1a3463STruong Nguyen	service=$1
710eb1a3463STruong Nguyen	mypolicy=$2
711eb1a3463STruong Nguyen	proto=$3
7127ddce999SHans Rosenfeld	port=$4
7137ddce999SHans Rosenfeld	out=$5
7147ddce999SHans Rosenfeld	_6=$6
715eb1a3463STruong Nguyen
716eb1a3463STruong Nguyen	#
717eb1a3463STruong Nguyen	# Default mode is to inherit from global's policy
718eb1a3463STruong Nguyen	#
719eb1a3463STruong Nguyen	[ "$mypolicy" = "use_global" ] && return 0
720eb1a3463STruong Nguyen
721eb1a3463STruong Nguyen	tcp_opts=""
722eb1a3463STruong Nguyen	[ "$proto" = "tcp" ] && tcp_opts="flags S keep state keep frags"
723eb1a3463STruong Nguyen
7247ddce999SHans Rosenfeld	block_policy=`get_block_policy $1`
7257ddce999SHans Rosenfeld        if [ "$block_policy" = "use_global" ]; then
7267ddce999SHans Rosenfeld		block_policy=${GLOBAL_BLOCK_POLICY}
7277ddce999SHans Rosenfeld        fi
7287ddce999SHans Rosenfeld
7297ddce999SHans Rosenfeld	if [ "$block_policy" = "return" ]; then
7307ddce999SHans Rosenfeld		[ "$proto" = "tcp" ] && block_policy="return-rst"
7317ddce999SHans Rosenfeld		[ "$proto" != "tcp" ] && block_policy="return-icmp-as-dest"
7327ddce999SHans Rosenfeld	else
7337ddce999SHans Rosenfeld		block_policy=""
7347ddce999SHans Rosenfeld        fi
7357ddce999SHans Rosenfeld
7367ddce999SHans Rosenfeld	iplist=`get_target${_6}_list $service`
7377ddce999SHans Rosenfeld
738eb1a3463STruong Nguyen	#
739eb1a3463STruong Nguyen	# Allow all if policy is 'none'
740eb1a3463STruong Nguyen	#
741eb1a3463STruong Nguyen	if [ "$mypolicy" = "none" ]; then
7427ddce999SHans Rosenfeld		for ip in $iplist; do
7437ddce999SHans Rosenfeld			daddr=`get_IP ${ip}`
7447ddce999SHans Rosenfeld			[ -z "$daddr" -o "$daddr" = '""' ] && continue
7457ddce999SHans Rosenfeld			echo "pass in log quick proto ${proto} from any to ${daddr}" \
746eb1a3463STruong Nguyen			    "port = ${port} ${tcp_opts}" >>${out}
7477ddce999SHans Rosenfeld		done
748eb1a3463STruong Nguyen		return 0
749eb1a3463STruong Nguyen	fi
750eb1a3463STruong Nguyen
751eb1a3463STruong Nguyen	#
7527ddce999SHans Rosenfeld	# For now, let's concern ourselves only with incoming traffic.
753eb1a3463STruong Nguyen	#
7547ddce999SHans Rosenfeld	[ "$mypolicy" = "deny" ] && { ecmd="pass"; acmd="block ${block_policy}"; }
7557ddce999SHans Rosenfeld	[ "$mypolicy" = "allow" ] && { ecmd="block ${block_policy}"; acmd="pass"; }
756eb1a3463STruong Nguyen
7577ddce999SHans Rosenfeld	for name in `get_exceptions${_6} $service`; do
758eb1a3463STruong Nguyen		[ -z "$name" -o "$name" = '""' ] && continue
759eb1a3463STruong Nguyen
760eb1a3463STruong Nguyen		ifc=`get_interface $name`
761eb1a3463STruong Nguyen		if [ $? -eq 0 -a -n "$ifc" ]; then
7627ddce999SHans Rosenfeld			for ip in $iplist; do
7637ddce999SHans Rosenfeld				daddr=`get_IP ${ip}`
7647ddce999SHans Rosenfeld				[ -z "$daddr" -o "$daddr" = '""' ] && continue
765eb1a3463STruong Nguyen				echo "${ecmd} in log quick on ${ifc} from any to" \
7667ddce999SHans Rosenfeld				    "${daddr} port = ${port}" >>${out}
7677ddce999SHans Rosenfeld			done
768eb1a3463STruong Nguyen			continue
769eb1a3463STruong Nguyen		fi
770eb1a3463STruong Nguyen
7717ddce999SHans Rosenfeld		saddr=`get_IP ${name}`
7727ddce999SHans Rosenfeld		if [ $? -eq 0 -a -n "$saddr" ]; then
7737ddce999SHans Rosenfeld			for ip in $iplist; do
7747ddce999SHans Rosenfeld				daddr=`get_IP ${ip}`
7757ddce999SHans Rosenfeld				[ -z "$daddr" -o "$daddr" = '""' ] && continue
7767ddce999SHans Rosenfeld				echo "${ecmd} in log quick proto ${proto} from ${saddr}" \
7777ddce999SHans Rosenfeld				    "to ${daddr} port = ${port} ${tcp_opts}" >>${out}
7787ddce999SHans Rosenfeld			done
779eb1a3463STruong Nguyen		fi
780eb1a3463STruong Nguyen	done
781eb1a3463STruong Nguyen
7827ddce999SHans Rosenfeld	for name in `get_apply2${_6}_list $service`; do
783eb1a3463STruong Nguyen		[ -z "$name" -o "$name" = '""' ] && continue
784eb1a3463STruong Nguyen
785eb1a3463STruong Nguyen		ifc=`get_interface $name`
786eb1a3463STruong Nguyen		if [ $? -eq 0 -a -n "$ifc" ]; then
7877ddce999SHans Rosenfeld			for ip in $iplist; do
7887ddce999SHans Rosenfeld				daddr=`get_IP ${ip}`
7897ddce999SHans Rosenfeld				[ -z "$daddr" -o "$daddr" = '""' ] && continue
790eb1a3463STruong Nguyen				echo "${acmd} in log quick on ${ifc} from any to" \
7917ddce999SHans Rosenfeld				    "${daddr} port = ${port}" >>${out}
7927ddce999SHans Rosenfeld			done
793eb1a3463STruong Nguyen			continue
794eb1a3463STruong Nguyen		fi
795eb1a3463STruong Nguyen
7967ddce999SHans Rosenfeld		saddr=`get_IP ${name}`
7977ddce999SHans Rosenfeld		if [ $? -eq 0 -a -n "$saddr" ]; then
7987ddce999SHans Rosenfeld			for ip in $iplist; do
7997ddce999SHans Rosenfeld				daddr=`get_IP ${ip}`
8007ddce999SHans Rosenfeld				[ -z "$daddr" -o "$daddr" = '""' ] && continue
8017ddce999SHans Rosenfeld				echo "${acmd} in log quick proto ${proto} from ${saddr}" \
8027ddce999SHans Rosenfeld				    "to ${daddr} port = ${port} ${tcp_opts}" >>${out}
8037ddce999SHans Rosenfeld			done
804eb1a3463STruong Nguyen		fi
805eb1a3463STruong Nguyen	done
806eb1a3463STruong Nguyen
8077ddce999SHans Rosenfeld	for ip in $iplist; do
8087ddce999SHans Rosenfeld		daddr=`get_IP ${ip}`
8097ddce999SHans Rosenfeld		[ -z "$daddr" -o "$daddr" = '""' ] && continue
8107ddce999SHans Rosenfeld		echo "${ecmd} in log quick proto ${proto} from any to ${daddr}" \
811eb1a3463STruong Nguyen		    "port = ${port} ${tcp_opts}" >>${out}
8127ddce999SHans Rosenfeld	done
813eb1a3463STruong Nguyen
814eb1a3463STruong Nguyen	return 0
815eb1a3463STruong Nguyen}
816eb1a3463STruong Nguyen
817eb1a3463STruong Nguyen#
818eb1a3463STruong Nguyen# Service has either IANA ports and proto or its own firewall method to
819eb1a3463STruong Nguyen# generate the rules.
820eb1a3463STruong Nguyen#
821eb1a3463STruong Nguyen# - if service has a custom method, use it to populate its rules
822eb1a3463STruong Nguyen# - if service has a firewall_config pg, use process_server_svc
823eb1a3463STruong Nguyen#
824eb1a3463STruong Nguyen# Argument - fmri
825eb1a3463STruong Nguyen#
826eb1a3463STruong Nguyenprocess_service()
827eb1a3463STruong Nguyen{
828eb1a3463STruong Nguyen	#
829eb1a3463STruong Nguyen	# Don't process network/ipfilter
830eb1a3463STruong Nguyen	#
831eb1a3463STruong Nguyen	[ "$1" = "$IPF_FMRI" ] && return 0
832eb1a3463STruong Nguyen
833eb1a3463STruong Nguyen	service_check_state $1 $SMF_MAINT && return 1
834eb1a3463STruong Nguyen
835eb1a3463STruong Nguyen	method=`svcprop -p $FW_CONTEXT_PG/$METHOD_PROP $1 2>/dev/null | \
836eb1a3463STruong Nguyen	    sed 's/\\\//g'`
837eb1a3463STruong Nguyen	if [ -n "$method" -a "$method" != '""' ]; then
838eb1a3463STruong Nguyen		( exec $method $1 >/dev/null )
839eb1a3463STruong Nguyen	else
840eb1a3463STruong Nguyen		svcprop -p $FW_CONFIG_PG $1 >/dev/null 2>&1 || return 1
841eb1a3463STruong Nguyen		process_server_svc $1 || return 1
842eb1a3463STruong Nguyen	fi
843eb1a3463STruong Nguyen	return 0
844eb1a3463STruong Nguyen}
845eb1a3463STruong Nguyen
846eb1a3463STruong Nguyen#
847eb1a3463STruong Nguyen# Generate rules for protocol/port defined in firewall_config_default/open_ports
848eb1a3463STruong Nguyen# property. These are non-service programs whose network resource info are
849eb1a3463STruong Nguyen# defined as "{tcp | upd}:{PORT | PORT-PORT}". Essentially, these programs need
850eb1a3463STruong Nguyen# some specific local ports to be opened. For example, BitTorrent clients need to
851eb1a3463STruong Nguyen# have 6881-6889 opened.
852eb1a3463STruong Nguyen#
853eb1a3463STruong Nguyenprocess_nonsvc_progs()
854eb1a3463STruong Nguyen{
855eb1a3463STruong Nguyen	out=$1
856eb1a3463STruong Nguyen	echo "# Non-service programs rules" >>${out}
8576f7d61cdSTruong Q. Nguyen	progs=`global_get_prop_value $FW_CONFIG_DEF_PG $OPEN_PORTS_PROP`
858eb1a3463STruong Nguyen
859eb1a3463STruong Nguyen	for prog in $progs; do
860eb1a3463STruong Nguyen		[ -z "$prog" -o "$prog" = '""' ] && continue
861eb1a3463STruong Nguyen
862eb1a3463STruong Nguyen		port=`tuple_get_port $prog`
863eb1a3463STruong Nguyen		[ $? -eq 1 -o -z "$port" ] && continue
864eb1a3463STruong Nguyen
865eb1a3463STruong Nguyen		proto=`tuple_get_proto $prog`
866eb1a3463STruong Nguyen		[ $? -eq 1 ] && continue
867eb1a3463STruong Nguyen
868eb1a3463STruong Nguyen		set -- $port
869eb1a3463STruong Nguyen		if  [ $# -gt 1 ]; then
870eb1a3463STruong Nguyen			if [ -z "$proto" ]; then
871eb1a3463STruong Nguyen				echo "pass in log quick from any to any" \
872eb1a3463STruong Nguyen				    "port ${1} >< ${2}" >>${out}
873eb1a3463STruong Nguyen			else
874eb1a3463STruong Nguyen				echo "pass in log quick proto ${proto} from any" \
875eb1a3463STruong Nguyen				    "to any port ${1} >< ${2}" >>${out}
876eb1a3463STruong Nguyen			fi
877eb1a3463STruong Nguyen		else
878eb1a3463STruong Nguyen			if [ -z "$proto" ]; then
879eb1a3463STruong Nguyen				echo "pass in log quick from any to any" \
880eb1a3463STruong Nguyen				    "port = ${1}" >>${out}
881eb1a3463STruong Nguyen			else
882eb1a3463STruong Nguyen				echo "pass in log quick proto ${proto} from any" \
883eb1a3463STruong Nguyen				    "to any port = ${1}" >>${out}
884eb1a3463STruong Nguyen			fi
885eb1a3463STruong Nguyen		fi
886eb1a3463STruong Nguyen	done
887eb1a3463STruong Nguyen
888eb1a3463STruong Nguyen	return 0
889eb1a3463STruong Nguyen}
890eb1a3463STruong Nguyen
891eb1a3463STruong Nguyen#
892eb1a3463STruong Nguyen# Generate a new /etc/ipf/ipf.conf. If firewall policy is 'none',
893eb1a3463STruong Nguyen# ipf.conf is empty .
894eb1a3463STruong Nguyen#
895eb1a3463STruong Nguyencreate_global_rules()
896eb1a3463STruong Nguyen{
8976f7d61cdSTruong Q. Nguyen	if [ "$GLOBAL_POLICY" = "custom" ]; then
8986f7d61cdSTruong Q. Nguyen		file=`global_get_prop_value $FW_CONFIG_DEF_PG $CUSTOM_FILE_PROP`
8997ddce999SHans Rosenfeld		file6=`global_get_prop_value $FW_CONFIG_DEF_PG $CUSTOM_FILE_6_PROP`
900eb1a3463STruong Nguyen
901eb1a3463STruong Nguyen		[ -n "$file" ] && custom_set_symlink $file
902*6a490867SHans Rosenfeld		[ -n "$file6" ] && custom_set_symlink_6 $file6
9037ddce999SHans Rosenfeld
904eb1a3463STruong Nguyen		return 0
905eb1a3463STruong Nguyen	fi
906eb1a3463STruong Nguyen
907eb1a3463STruong Nguyen	TEMP=`mktemp /var/run/ipf.conf.pid$$.XXXXXX`
9087ddce999SHans Rosenfeld	TEMP6=`mktemp /var/run/ipf6.conf.pid$$.XXXXXX`
909eb1a3463STruong Nguyen	process_nonsvc_progs $TEMP
9107ddce999SHans Rosenfeld	process_nonsvc_progs $TEMP6
911eb1a3463STruong Nguyen
912eb1a3463STruong Nguyen	echo "# Global Default rules" >>${TEMP}
9137ddce999SHans Rosenfeld	echo "# Global Default rules" >>${TEMP6}
9146f7d61cdSTruong Q. Nguyen	if [ "$GLOBAL_POLICY" != "none" ]; then
915eb1a3463STruong Nguyen		echo "pass out log quick all keep state" >>${TEMP}
9167ddce999SHans Rosenfeld		echo "pass out log quick all keep state" >>${TEMP6}
917eb1a3463STruong Nguyen	fi
918eb1a3463STruong Nguyen
9196f7d61cdSTruong Q. Nguyen	case "$GLOBAL_POLICY" in
920eb1a3463STruong Nguyen	'none')
921eb1a3463STruong Nguyen		# No rules
922eb1a3463STruong Nguyen		replace_file ${IPFILCONF} ${TEMP}
9237ddce999SHans Rosenfeld		replace_file ${IP6FILCONF} ${TEMP6}
924eb1a3463STruong Nguyen		return $?
925eb1a3463STruong Nguyen		;;
926eb1a3463STruong Nguyen
927eb1a3463STruong Nguyen	'deny')
928eb1a3463STruong Nguyen		ecmd="pass"
929eb1a3463STruong Nguyen		acmd="block"
930eb1a3463STruong Nguyen		;;
931eb1a3463STruong Nguyen
932eb1a3463STruong Nguyen	'allow')
933eb1a3463STruong Nguyen		ecmd="block"
934eb1a3463STruong Nguyen		acmd="pass"
935eb1a3463STruong Nguyen		;;
936eb1a3463STruong Nguyen	*)
937eb1a3463STruong Nguyen		return 1;
938eb1a3463STruong Nguyen		;;
939eb1a3463STruong Nguyen	esac
940eb1a3463STruong Nguyen
9416f7d61cdSTruong Q. Nguyen	for name in `global_get_prop_value $FW_CONFIG_DEF_PG $EXCEPTIONS_PROP`; do
942eb1a3463STruong Nguyen		[ -z "$name" -o "$name" = '""' ] && continue
943eb1a3463STruong Nguyen
944eb1a3463STruong Nguyen		ifc=`get_interface $name`
945eb1a3463STruong Nguyen		if [ $? -eq 0 -a -n "$ifc" ]; then
946eb1a3463STruong Nguyen			echo "${ecmd} in log quick on ${ifc} all" >>${TEMP}
947eb1a3463STruong Nguyen			continue
948eb1a3463STruong Nguyen		fi
949eb1a3463STruong Nguyen
950eb1a3463STruong Nguyen		addr=`get_IP ${name}`
951eb1a3463STruong Nguyen		if [ $? -eq 0 -a -n "$addr" ]; then
952eb1a3463STruong Nguyen			echo "${ecmd} in log quick from ${addr} to any" >>${TEMP}
953eb1a3463STruong Nguyen		fi
954eb1a3463STruong Nguyen
955eb1a3463STruong Nguyen	done
956eb1a3463STruong Nguyen
9577ddce999SHans Rosenfeld	for name in `global_get_prop_value $FW_CONFIG_DEF_PG $EXCEPTIONS_6_PROP`; do
9587ddce999SHans Rosenfeld		[ -z "$name" -o "$name" = '""' ] && continue
9597ddce999SHans Rosenfeld
9607ddce999SHans Rosenfeld		ifc=`get_interface $name`
9617ddce999SHans Rosenfeld		if [ $? -eq 0 -a -n "$ifc" ]; then
9627ddce999SHans Rosenfeld			echo "${ecmd} in log quick on ${ifc} all" >>${TEMP6}
9637ddce999SHans Rosenfeld			continue
9647ddce999SHans Rosenfeld		fi
9657ddce999SHans Rosenfeld
9667ddce999SHans Rosenfeld		addr=`get_IP ${name}`
9677ddce999SHans Rosenfeld		if [ $? -eq 0 -a -n "$addr" ]; then
9687ddce999SHans Rosenfeld			echo "${ecmd} in log quick from ${addr} to any" >>${TEMP6}
9697ddce999SHans Rosenfeld		fi
9707ddce999SHans Rosenfeld
9717ddce999SHans Rosenfeld	done
9727ddce999SHans Rosenfeld
9736f7d61cdSTruong Q. Nguyen	for name in `global_get_prop_value $FW_CONFIG_DEF_PG $APPLY2_PROP`; do
974eb1a3463STruong Nguyen		[ -z "$name" -o "$name" = '""' ] && continue
975eb1a3463STruong Nguyen
976eb1a3463STruong Nguyen		ifc=`get_interface $name`
977eb1a3463STruong Nguyen		if [ $? -eq 0 -a -n "$ifc" ]; then
978eb1a3463STruong Nguyen			echo "${acmd} in log quick on ${ifc} all" >>${TEMP}
979eb1a3463STruong Nguyen			continue
980eb1a3463STruong Nguyen		fi
981eb1a3463STruong Nguyen
982eb1a3463STruong Nguyen		addr=`get_IP ${name}`
983eb1a3463STruong Nguyen		if [ $? -eq 0 -a -n "$addr" ]; then
984eb1a3463STruong Nguyen			echo "${acmd} in log quick from ${addr} to any" >>${TEMP}
985eb1a3463STruong Nguyen		fi
986eb1a3463STruong Nguyen	done
987eb1a3463STruong Nguyen
9887ddce999SHans Rosenfeld	for name in `global_get_prop_value $FW_CONFIG_DEF_PG $APPLY2_6_PROP`; do
9897ddce999SHans Rosenfeld		[ -z "$name" -o "$name" = '""' ] && continue
9907ddce999SHans Rosenfeld
9917ddce999SHans Rosenfeld		ifc=`get_interface $name`
9927ddce999SHans Rosenfeld		if [ $? -eq 0 -a -n "$ifc" ]; then
9937ddce999SHans Rosenfeld			echo "${acmd} in log quick on ${ifc} all" >>${TEMP6}
9947ddce999SHans Rosenfeld			continue
9957ddce999SHans Rosenfeld		fi
9967ddce999SHans Rosenfeld
9977ddce999SHans Rosenfeld		addr=`get_IP ${name}`
9987ddce999SHans Rosenfeld		if [ $? -eq 0 -a -n "$addr" ]; then
9997ddce999SHans Rosenfeld			echo "${acmd} in log quick from ${addr} to any" >>${TEMP6}
10007ddce999SHans Rosenfeld		fi
10017ddce999SHans Rosenfeld	done
10027ddce999SHans Rosenfeld
10036f7d61cdSTruong Q. Nguyen	if [ "$GLOBAL_POLICY" = "allow" ]; then
1004eb1a3463STruong Nguyen		#
10057ddce999SHans Rosenfeld		# Allow DHCP(v6) traffic if running as a DHCP client
1006eb1a3463STruong Nguyen		#
1007eb1a3463STruong Nguyen		/sbin/netstrategy | grep dhcp >/dev/null 2>&1
1008eb1a3463STruong Nguyen		if [ $? -eq 0 ]; then
1009eb1a3463STruong Nguyen			echo "pass out log quick from any port = 68" \
1010eb1a3463STruong Nguyen			    "keep state" >>${TEMP}
1011eb1a3463STruong Nguyen			echo "pass in log quick from any to any port = 68" >>${TEMP}
10127ddce999SHans Rosenfeld
10137ddce999SHans Rosenfeld			echo "pass out log quick from any port = 546" \
10147ddce999SHans Rosenfeld			    "keep state" >>${TEMP6}
10157ddce999SHans Rosenfeld			echo "pass in log quick from any to any port = 546" >>${TEMP6}
1016eb1a3463STruong Nguyen		fi
1017eb1a3463STruong Nguyen		echo "block in log all" >>${TEMP}
10187ddce999SHans Rosenfeld		echo "block in log all" >>${TEMP6}
1019eb1a3463STruong Nguyen	fi
1020eb1a3463STruong Nguyen
1021eb1a3463STruong Nguyen	replace_file ${IPFILCONF} ${TEMP}
10227ddce999SHans Rosenfeld	replace_file ${IP6FILCONF} ${TEMP6}
1023eb1a3463STruong Nguyen	return $?
1024eb1a3463STruong Nguyen}
1025eb1a3463STruong Nguyen
1026eb1a3463STruong Nguyen#
1027eb1a3463STruong Nguyen# Generate a new /etc/ipf/ipf_ovr.conf, the override system-wide policy. It's
1028eb1a3463STruong Nguyen# a simplified policy that doesn't support 'exceptions' entities.
1029eb1a3463STruong Nguyen#
1030eb1a3463STruong Nguyen# If firewall policy is "none", no rules are generated.
1031eb1a3463STruong Nguyen#
1032eb1a3463STruong Nguyen# Note that "pass" rules don't have "quick" as we don't want
1033eb1a3463STruong Nguyen# them to override services' block rules.
1034eb1a3463STruong Nguyen#
1035eb1a3463STruong Nguyencreate_global_ovr_rules()
1036eb1a3463STruong Nguyen{
1037eb1a3463STruong Nguyen	#
1038eb1a3463STruong Nguyen	# Simply empty override file if global policy is 'custom'
1039eb1a3463STruong Nguyen	#
10406f7d61cdSTruong Q. Nguyen	if [ "$GLOBAL_POLICY" = "custom" ]; then
1041eb1a3463STruong Nguyen		echo "# 'custom' global policy" >$IPFILOVRCONF
10427ddce999SHans Rosenfeld		echo "# 'custom' global policy" >$IP6FILOVRCONF
1043eb1a3463STruong Nguyen		return 0
1044eb1a3463STruong Nguyen	fi
1045eb1a3463STruong Nguyen
1046eb1a3463STruong Nguyen	#
1047eb1a3463STruong Nguyen	# Get and process override policy
1048eb1a3463STruong Nguyen	#
10496f7d61cdSTruong Q. Nguyen	ovr_policy=`global_get_prop_value $FW_CONFIG_OVR_PG $POLICY_PROP`
10500a5f928cSTruong Nguyen	if [ "$ovr_policy" = "none" ]; then
10510a5f928cSTruong Nguyen		echo "# global override policy is 'none'" >$IPFILOVRCONF
10527ddce999SHans Rosenfeld		echo "# global override policy is 'none'" >$IP6FILOVRCONF
10530a5f928cSTruong Nguyen		return 0
10540a5f928cSTruong Nguyen	fi
1055eb1a3463STruong Nguyen
10560a5f928cSTruong Nguyen	TEMP=`mktemp /var/run/ipf_ovr.conf.pid$$.XXXXXX`
1057eb1a3463STruong Nguyen	[ "$ovr_policy" = "deny" ] && acmd="block in log quick"
1058eb1a3463STruong Nguyen	[ "$ovr_policy" = "allow" ] && acmd="pass in log"
1059eb1a3463STruong Nguyen
10606f7d61cdSTruong Q. Nguyen	apply2_list=`global_get_prop_value $FW_CONFIG_OVR_PG $APPLY2_PROP`
1061eb1a3463STruong Nguyen	for name in $apply2_list; do
1062eb1a3463STruong Nguyen		[ -z "$name" -o "$name" = '""' ] && continue
1063eb1a3463STruong Nguyen
1064eb1a3463STruong Nguyen		ifc=`get_interface $name`
1065eb1a3463STruong Nguyen		if [ $? -eq 0 -a -n "$ifc" ]; then
1066eb1a3463STruong Nguyen			echo "${acmd} on ${ifc} all" >>${TEMP}
1067eb1a3463STruong Nguyen			continue
1068eb1a3463STruong Nguyen		fi
1069eb1a3463STruong Nguyen
1070eb1a3463STruong Nguyen		addr=`get_IP ${name}`
1071eb1a3463STruong Nguyen		if [ $? -eq 0 -a -n "$addr" ]; then
1072eb1a3463STruong Nguyen			echo "${acmd} from ${addr} to any" >>${TEMP}
1073eb1a3463STruong Nguyen		fi
1074eb1a3463STruong Nguyen	done
1075eb1a3463STruong Nguyen
10767ddce999SHans Rosenfeld	apply2_6_list=`global_get_prop_value $FW_CONFIG_OVR_PG $APPLY2_6_PROP`
10777ddce999SHans Rosenfeld	for name in $apply2_6_list; do
10787ddce999SHans Rosenfeld		[ -z "$name" -o "$name" = '""' ] && continue
10797ddce999SHans Rosenfeld
10807ddce999SHans Rosenfeld		ifc=`get_interface $name`
10817ddce999SHans Rosenfeld		if [ $? -eq 0 -a -n "$ifc" ]; then
10827ddce999SHans Rosenfeld			echo "${acmd} on ${ifc} all" >>${TEMP6}
10837ddce999SHans Rosenfeld			continue
10847ddce999SHans Rosenfeld		fi
10857ddce999SHans Rosenfeld
10867ddce999SHans Rosenfeld		addr=`get_IP ${name}`
10877ddce999SHans Rosenfeld		if [ $? -eq 0 -a -n "$addr" ]; then
10887ddce999SHans Rosenfeld			echo "${acmd} from ${addr} to any" >>${TEMP6}
10897ddce999SHans Rosenfeld		fi
10907ddce999SHans Rosenfeld	done
10917ddce999SHans Rosenfeld
1092eb1a3463STruong Nguyen	replace_file ${IPFILOVRCONF} ${TEMP}
10937ddce999SHans Rosenfeld	replace_file ${IP6FILOVRCONF} ${TEMP6}
1094eb1a3463STruong Nguyen	return $?
1095eb1a3463STruong Nguyen}
1096eb1a3463STruong Nguyen
1097eb1a3463STruong Nguyen#
1098eb1a3463STruong Nguyen# Service is put into maintenance state due to its invalid firewall
1099eb1a3463STruong Nguyen# definition and/or policy.
1100eb1a3463STruong Nguyen#
1101eb1a3463STruong Nguyensvc_mark_maintenance()
1102eb1a3463STruong Nguyen{
1103eb1a3463STruong Nguyen	svcadm mark maintenance $1 >/dev/null 2>&1
1104eb1a3463STruong Nguyen
1105eb1a3463STruong Nguyen	date=`date`
1106eb1a3463STruong Nguyen	echo "[ $date ${0}: $1 has invalid ipf configuration. ]"
1107eb1a3463STruong Nguyen	echo "[ $date ${0}: placing $1 in maintenance. ]"
1108eb1a3463STruong Nguyen
1109eb1a3463STruong Nguyen	#
1110eb1a3463STruong Nguyen	# Move service's rule files to another location since
1111eb1a3463STruong Nguyen	# they're most likely invalid.
1112eb1a3463STruong Nguyen	#
1113eb1a3463STruong Nguyen	ipfile=`fmri_to_file $1 $IPF_SUFFIX`
1114eb1a3463STruong Nguyen	[ -f "$ipfile" ] && mv $ipfile "$ipfile.bak"
11157ddce999SHans Rosenfeld	ip6file=`fmri_to_file $1 $IPF6_SUFFIX`
11167ddce999SHans Rosenfeld	[ -f "$ip6file" ] && mv $ip6file "$ip6file.bak"
1117eb1a3463STruong Nguyen
1118eb1a3463STruong Nguyen	natfile=`fmri_to_file $1 $NAT_SUFFIX`
1119eb1a3463STruong Nguyen	[ -f "$natfile" ] && mv $natfile "$natfile.bak"
1120eb1a3463STruong Nguyen
1121eb1a3463STruong Nguyen	return 0
1122eb1a3463STruong Nguyen}
1123eb1a3463STruong Nguyen
1124eb1a3463STruong Nguyensvc_is_server()
1125eb1a3463STruong Nguyen{
1126eb1a3463STruong Nguyen	svcprop -p $FW_CONFIG_PG $1 >/dev/null 2>&1
1127eb1a3463STruong Nguyen}
1128eb1a3463STruong Nguyen
1129eb1a3463STruong Nguyen#
1130eb1a3463STruong Nguyen# Create rules for enabled firewalling and client services.
1131eb1a3463STruong Nguyen# - obtain the list of enabled services and process them
1132eb1a3463STruong Nguyen# - save the list of rules file for later use
1133eb1a3463STruong Nguyen#
1134eb1a3463STruong Nguyencreate_services_rules()
1135eb1a3463STruong Nguyen{
1136eb1a3463STruong Nguyen	#
1137eb1a3463STruong Nguyen	# Do nothing if global policy is 'custom'
1138eb1a3463STruong Nguyen	#
11396f7d61cdSTruong Q. Nguyen	[ "$GLOBAL_POLICY" = "custom" ] && return 0
1140eb1a3463STruong Nguyen
1141eb1a3463STruong Nguyen	ipf_get_lock
1142eb1a3463STruong Nguyen
1143eb1a3463STruong Nguyen	#
1144eb1a3463STruong Nguyen	# Get all enabled services
1145eb1a3463STruong Nguyen	#
1146eb1a3463STruong Nguyen	allsvcs=`svcprop -cf -p general/enabled -p general_ovr/enabled '*' \
1147eb1a3463STruong Nguyen	    2>/dev/null | sed -n 's,^\(svc:.*\)/:properties/.* true$,\1,p' | sort -u`
1148eb1a3463STruong Nguyen
1149eb1a3463STruong Nguyen	#
1150eb1a3463STruong Nguyen	# Process enabled services
1151eb1a3463STruong Nguyen	#
1152eb1a3463STruong Nguyen	for s in $allsvcs; do
1153eb1a3463STruong Nguyen		service_is_enabled $s || continue
1154eb1a3463STruong Nguyen		process_service $s || continue
1155eb1a3463STruong Nguyen
1156eb1a3463STruong Nguyen		ipfile=`fmri_to_file $s $IPF_SUFFIX`
1157eb1a3463STruong Nguyen		if [ -n "$ipfile" -a -r "$ipfile" ]; then
1158eb1a3463STruong Nguyen			check_ipf_syntax $ipfile
1159eb1a3463STruong Nguyen			if [ $? -ne 0 ]; then
1160eb1a3463STruong Nguyen				svc_mark_maintenance $s
1161eb1a3463STruong Nguyen				continue
1162eb1a3463STruong Nguyen			fi
1163eb1a3463STruong Nguyen
1164eb1a3463STruong Nguyen			svc_is_server $s
1165eb1a3463STruong Nguyen			if [ $? -eq 0 ]; then
1166eb1a3463STruong Nguyen				check_ipf_rules $ipfile
1167eb1a3463STruong Nguyen				if [ $? -ne 0 ]; then
1168eb1a3463STruong Nguyen					svc_mark_maintenance $s
1169eb1a3463STruong Nguyen					continue
1170eb1a3463STruong Nguyen				fi
1171eb1a3463STruong Nguyen			fi
1172eb1a3463STruong Nguyen			CONF_FILES="$CONF_FILES $ipfile"
1173eb1a3463STruong Nguyen		fi
1174eb1a3463STruong Nguyen
11757ddce999SHans Rosenfeld		ip6file=`fmri_to_file $s $IPF6_SUFFIX`
11767ddce999SHans Rosenfeld		if [ -n "$ip6file" -a -r "$ip6file" ]; then
11777ddce999SHans Rosenfeld			check_ipf_syntax $ip6file -6
11787ddce999SHans Rosenfeld			if [ $? -ne 0 ]; then
11797ddce999SHans Rosenfeld				svc_mark_maintenance $s
11807ddce999SHans Rosenfeld				continue
11817ddce999SHans Rosenfeld			fi
11827ddce999SHans Rosenfeld
11837ddce999SHans Rosenfeld			svc_is_server $s
11847ddce999SHans Rosenfeld			if [ $? -eq 0 ]; then
11857ddce999SHans Rosenfeld				check_ipf_rules $ip6file -6
11867ddce999SHans Rosenfeld				if [ $? -ne 0 ]; then
11877ddce999SHans Rosenfeld					svc_mark_maintenance $s
11887ddce999SHans Rosenfeld					continue
11897ddce999SHans Rosenfeld				fi
11907ddce999SHans Rosenfeld			fi
11917ddce999SHans Rosenfeld			CONF6_FILES="$CONF6_FILES $ip6file"
11927ddce999SHans Rosenfeld		fi
11937ddce999SHans Rosenfeld
1194eb1a3463STruong Nguyen		natfile=`fmri_to_file $s $NAT_SUFFIX`
1195eb1a3463STruong Nguyen		if [ -n "$natfile" -a -r "$natfile" ]; then
1196eb1a3463STruong Nguyen			check_nat_syntax $natfile
1197eb1a3463STruong Nguyen			if [ $? -ne 0 ]; then
1198eb1a3463STruong Nguyen				svc_mark_maintenance $s
1199eb1a3463STruong Nguyen				continue
1200eb1a3463STruong Nguyen			fi
1201eb1a3463STruong Nguyen
1202eb1a3463STruong Nguyen			NAT_FILES="$NAT_FILES $natfile"
1203eb1a3463STruong Nguyen		fi
1204eb1a3463STruong Nguyen	done
1205eb1a3463STruong Nguyen
1206eb1a3463STruong Nguyen	ipf_remove_lock
1207eb1a3463STruong Nguyen	return 0
1208eb1a3463STruong Nguyen}
1209eb1a3463STruong Nguyen
1210eb1a3463STruong Nguyen#
1211eb1a3463STruong Nguyen# We update a services ipf ruleset in the following manners:
1212eb1a3463STruong Nguyen# - service is disabled, tear down its rules.
1213eb1a3463STruong Nguyen# - service is disable or refreshed(online), setup or update its rules.
1214eb1a3463STruong Nguyen#
1215eb1a3463STruong Nguyenservice_update_rules()
1216eb1a3463STruong Nguyen{
1217eb1a3463STruong Nguyen	svc=$1
1218eb1a3463STruong Nguyen
1219eb1a3463STruong Nguyen	ipfile=`fmri_to_file $svc $IPF_SUFFIX`
12207ddce999SHans Rosenfeld	ip6file=`fmri_to_file $svc $IPF6_SUFFIX`
12217ddce999SHans Rosenfeld	[ -n "$ipfile" ] && remove_rules $ipfile
12227ddce999SHans Rosenfeld	[ -n "$ip6file" ] && remove_rules $ip6file -6
1223eb1a3463STruong Nguyen
12247ddce999SHans Rosenfeld	[ -z "$ipfile" -a -z "$ip6file" ] && return 0
1225eb1a3463STruong Nguyen
1226eb1a3463STruong Nguyen	natfile=`fmri_to_file $svc $NAT_SUFFIX`
1227eb1a3463STruong Nguyen	[ -n "$natfile" ] && remove_nat_rules $natfile
1228eb1a3463STruong Nguyen
1229eb1a3463STruong Nguyen	#
1230eb1a3463STruong Nguyen	# Don't go further if service is disabled or in maintenance.
1231eb1a3463STruong Nguyen	#
1232eb1a3463STruong Nguyen	service_is_enabled $svc || return 0
1233eb1a3463STruong Nguyen	service_check_state $1 $SMF_MAINT && return 0
1234eb1a3463STruong Nguyen
1235eb1a3463STruong Nguyen	process_service $svc || return 1
1236eb1a3463STruong Nguyen	if [ -f "$ipfile" ]; then
1237eb1a3463STruong Nguyen		check_ipf_syntax $ipfile
1238eb1a3463STruong Nguyen		if [ $? -ne 0 ]; then
1239eb1a3463STruong Nguyen			svc_mark_maintenance $svc
1240eb1a3463STruong Nguyen			return 1
1241eb1a3463STruong Nguyen		fi
1242eb1a3463STruong Nguyen	fi
1243eb1a3463STruong Nguyen
12447ddce999SHans Rosenfeld	if [ -f "$ip6file" ]; then
12457ddce999SHans Rosenfeld		check_ipf_syntax $ip6file -6
12467ddce999SHans Rosenfeld		if [ $? -ne 0 ]; then
12477ddce999SHans Rosenfeld			svc_mark_maintenance $svc
12487ddce999SHans Rosenfeld			return 1
12497ddce999SHans Rosenfeld		fi
12507ddce999SHans Rosenfeld	fi
12517ddce999SHans Rosenfeld
1252eb1a3463STruong Nguyen	if [ -f "$natfile" ]; then
1253eb1a3463STruong Nguyen		check_nat_syntax $natfile
1254eb1a3463STruong Nguyen		if [ $? -ne 0 ]; then
1255eb1a3463STruong Nguyen			svc_mark_maintenance $svc
1256eb1a3463STruong Nguyen			return 1
1257eb1a3463STruong Nguyen		fi
1258eb1a3463STruong Nguyen	fi
1259eb1a3463STruong Nguyen
1260eb1a3463STruong Nguyen	if [ -f "$ipfile" ]; then
1261eb1a3463STruong Nguyen		svc_is_server $svc
1262eb1a3463STruong Nguyen		if [ $? -eq 0 ]; then
1263eb1a3463STruong Nguyen			update_check_ipf_rules $ipfile
1264eb1a3463STruong Nguyen			if [ $? -ne 0 ]; then
1265eb1a3463STruong Nguyen				svc_mark_maintenance $svc
1266eb1a3463STruong Nguyen				return 1
1267eb1a3463STruong Nguyen			fi
1268eb1a3463STruong Nguyen		fi
1269eb1a3463STruong Nguyen
1270eb1a3463STruong Nguyen		prepend_new_rules $ipfile
1271eb1a3463STruong Nguyen
1272eb1a3463STruong Nguyen		#
1273eb1a3463STruong Nguyen		# reload Global Override rules to
1274eb1a3463STruong Nguyen		# maintain correct ordering.
1275eb1a3463STruong Nguyen		#
1276eb1a3463STruong Nguyen		remove_rules $IPFILOVRCONF
1277eb1a3463STruong Nguyen		prepend_new_rules $IPFILOVRCONF
1278eb1a3463STruong Nguyen	fi
1279eb1a3463STruong Nguyen
12807ddce999SHans Rosenfeld	if [ -f "$ip6file" ]; then
12817ddce999SHans Rosenfeld		svc_is_server $svc
12827ddce999SHans Rosenfeld		if [ $? -eq 0 ]; then
12837ddce999SHans Rosenfeld			update_check_ipf_rules $ip6file -6
12847ddce999SHans Rosenfeld			if [ $? -ne 0 ]; then
12857ddce999SHans Rosenfeld				svc_mark_maintenance $svc
12867ddce999SHans Rosenfeld				return 1
12877ddce999SHans Rosenfeld			fi
12887ddce999SHans Rosenfeld		fi
12897ddce999SHans Rosenfeld
12907ddce999SHans Rosenfeld		prepend_new_rules $ip6file -6
12917ddce999SHans Rosenfeld
12927ddce999SHans Rosenfeld		#
12937ddce999SHans Rosenfeld		# reload Global Override rules to
12947ddce999SHans Rosenfeld		# maintain correct ordering.
12957ddce999SHans Rosenfeld		#
12967ddce999SHans Rosenfeld		remove_rules $IP6FILOVRCONF -6
12977ddce999SHans Rosenfeld		prepend_new_rules $IP6FILOVRCONF -6
12987ddce999SHans Rosenfeld	fi
12997ddce999SHans Rosenfeld
1300eb1a3463STruong Nguyen	[ -f "$natfile" ] && append_new_nat_rules $natfile
1301eb1a3463STruong Nguyen
1302eb1a3463STruong Nguyen	return 0
1303eb1a3463STruong Nguyen}
1304eb1a3463STruong Nguyen
1305eb1a3463STruong Nguyen#
1306eb1a3463STruong Nguyen# Call the service_update_rules with appropriate svc fmri.
1307eb1a3463STruong Nguyen#
1308eb1a3463STruong Nguyen# This is called from '/lib/svc/method/ipfilter fw_update' whenever
1309eb1a3463STruong Nguyen# a service is disabled/enabled/refreshed.
1310eb1a3463STruong Nguyen#
1311eb1a3463STruong Nguyenservice_update()
1312eb1a3463STruong Nguyen{
1313eb1a3463STruong Nguyen	svc=$1
1314eb1a3463STruong Nguyen	ret=0
1315eb1a3463STruong Nguyen
1316ea7d3b1aSTruong Nguyen	#
1317ea7d3b1aSTruong Nguyen	# If ipfilter isn't online or global policy is 'custom',
1318ea7d3b1aSTruong Nguyen	# nothing should be done.
1319ea7d3b1aSTruong Nguyen	#
13206f7d61cdSTruong Q. Nguyen	[ "$GLOBAL_POLICY" = "custom" ] && return 0
1321ea7d3b1aSTruong Nguyen	service_check_state $SMF_FMRI $SMF_ONLINE || return 0
1322ea7d3b1aSTruong Nguyen
1323eb1a3463STruong Nguyen	ipf_get_lock
1324eb1a3463STruong Nguyen	service_update_rules $svc || ret=1
1325eb1a3463STruong Nguyen
1326eb1a3463STruong Nguyen	ipf_remove_lock
1327eb1a3463STruong Nguyen	return $ret
1328eb1a3463STruong Nguyen}
13296f7d61cdSTruong Q. Nguyen
13306f7d61cdSTruong Q. Nguyen#
13316f7d61cdSTruong Q. Nguyen# Initialize global configuration
13326f7d61cdSTruong Q. Nguyen#
13336f7d61cdSTruong Q. Nguyenglobal_init
13346f7d61cdSTruong Q. Nguyen
1335