xref: /onnv-gate/usr/src/cmd/svc/shell/ipf_include.sh (revision 12848:c9ca63c180bd)
18823STruong.Q.Nguyen@Sun.COM#!/sbin/sh
28823STruong.Q.Nguyen@Sun.COM#
38823STruong.Q.Nguyen@Sun.COM# CDDL HEADER START
48823STruong.Q.Nguyen@Sun.COM#
58823STruong.Q.Nguyen@Sun.COM# The contents of this file are subject to the terms of the
68823STruong.Q.Nguyen@Sun.COM# Common Development and Distribution License (the "License").
78823STruong.Q.Nguyen@Sun.COM# You may not use this file except in compliance with the License.
88823STruong.Q.Nguyen@Sun.COM#
98823STruong.Q.Nguyen@Sun.COM# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
108823STruong.Q.Nguyen@Sun.COM# or http://www.opensolaris.org/os/licensing.
118823STruong.Q.Nguyen@Sun.COM# See the License for the specific language governing permissions
128823STruong.Q.Nguyen@Sun.COM# and limitations under the License.
138823STruong.Q.Nguyen@Sun.COM#
148823STruong.Q.Nguyen@Sun.COM# When distributing Covered Code, include this CDDL HEADER in each
158823STruong.Q.Nguyen@Sun.COM# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
168823STruong.Q.Nguyen@Sun.COM# If applicable, add the following below this CDDL HEADER, with the
178823STruong.Q.Nguyen@Sun.COM# fields enclosed by brackets "[]" replaced with your own identifying
188823STruong.Q.Nguyen@Sun.COM# information: Portions Copyright [yyyy] [name of copyright owner]
198823STruong.Q.Nguyen@Sun.COM#
208823STruong.Q.Nguyen@Sun.COM# CDDL HEADER END
218823STruong.Q.Nguyen@Sun.COM#
2212469STruong.Q.Nguyen@Sun.COM# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
238823STruong.Q.Nguyen@Sun.COM#
248823STruong.Q.Nguyen@Sun.COM
2511767SAnurag.Maskey@Sun.COMIPFILTER_FMRI="svc:/network/ipfilter:default"
268823STruong.Q.Nguyen@Sun.COMETC_IPF_DIR=/etc/ipf
2711767SAnurag.Maskey@Sun.COMIP6FILCONF=`/usr/bin/svcprop -p config/ipf6_config_file $IPFILTER_FMRI \
2811767SAnurag.Maskey@Sun.COM    2>/dev/null`
2911767SAnurag.Maskey@Sun.COMif [ $? -eq 1 ]; then
3011767SAnurag.Maskey@Sun.COM	IP6FILCONF=$ETC_IPF_DIR/ipf6.conf
3111767SAnurag.Maskey@Sun.COMfi
3211767SAnurag.Maskey@Sun.COMIPNATCONF=`/usr/bin/svcprop -p config/ipnat_config_file $IPFILTER_FMRI \
3311767SAnurag.Maskey@Sun.COM    2>/dev/null`
3411767SAnurag.Maskey@Sun.COMif [ $? -eq 1 ]; then
3511767SAnurag.Maskey@Sun.COM	IPNATCONF=$ETC_IPF_DIR/ipnat.conf
3611767SAnurag.Maskey@Sun.COMfi
3711767SAnurag.Maskey@Sun.COMIPPOOLCONF=`/usr/bin/svcprop -p config/ippool_config_file $IPFILTER_FMRI \
3811767SAnurag.Maskey@Sun.COM    2>/dev/null`
3911767SAnurag.Maskey@Sun.COMif [ $? -eq 1 ]; then
4011767SAnurag.Maskey@Sun.COM	IPPOOLCONF=$ETC_IPF_DIR/ippool.conf
4111767SAnurag.Maskey@Sun.COMfi
4210058STruong.Q.Nguyen@Sun.COMVAR_IPF_DIR=/var/run/ipf
438823STruong.Q.Nguyen@Sun.COMIPFILCONF=$VAR_IPF_DIR/ipf.conf
448823STruong.Q.Nguyen@Sun.COMIPFILOVRCONF=$VAR_IPF_DIR/ipf_ovr.conf
458823STruong.Q.Nguyen@Sun.COMIPF_LOCK=/var/run/ipflock
468823STruong.Q.Nguyen@Sun.COMCONF_FILES=""
478823STruong.Q.Nguyen@Sun.COMNAT_FILES=""
488823STruong.Q.Nguyen@Sun.COMIPF_SUFFIX=".ipf"
498823STruong.Q.Nguyen@Sun.COMNAT_SUFFIX=".nat"
508823STruong.Q.Nguyen@Sun.COM
518823STruong.Q.Nguyen@Sun.COM# version for configuration upgrades
528823STruong.Q.Nguyen@Sun.COMCURRENT_VERSION=1
538823STruong.Q.Nguyen@Sun.COM
548823STruong.Q.Nguyen@Sun.COMIPF_FMRI="svc:/network/ipfilter:default"
558823STruong.Q.Nguyen@Sun.COMINETDFMRI="svc:/network/inetd:default"
568823STruong.Q.Nguyen@Sun.COMRPCBINDFMRI="svc:/network/rpc/bind:default"
578823STruong.Q.Nguyen@Sun.COM
588823STruong.Q.Nguyen@Sun.COMSMF_ONLINE="online"
598823STruong.Q.Nguyen@Sun.COMSMF_MAINT="maintenance"
608823STruong.Q.Nguyen@Sun.COMSMF_NONE="none"
618823STruong.Q.Nguyen@Sun.COM
628823STruong.Q.Nguyen@Sun.COMFW_CONTEXT_PG="firewall_context"
638823STruong.Q.Nguyen@Sun.COMMETHOD_PROP="ipf_method"
648823STruong.Q.Nguyen@Sun.COM
658823STruong.Q.Nguyen@Sun.COMFW_CONFIG_PG="firewall_config"
668823STruong.Q.Nguyen@Sun.COMPOLICY_PROP="policy"
678823STruong.Q.Nguyen@Sun.COMAPPLY2_PROP="apply_to"
688823STruong.Q.Nguyen@Sun.COMEXCEPTIONS_PROP="exceptions"
698823STruong.Q.Nguyen@Sun.COM
708823STruong.Q.Nguyen@Sun.COMFW_CONFIG_DEF_PG="firewall_config_default"
718823STruong.Q.Nguyen@Sun.COMFW_CONFIG_OVR_PG="firewall_config_override"
728823STruong.Q.Nguyen@Sun.COMCUSTOM_FILE_PROP="custom_policy_file"
738823STruong.Q.Nguyen@Sun.COMOPEN_PORTS_PROP="open_ports"
748823STruong.Q.Nguyen@Sun.COM
758823STruong.Q.Nguyen@Sun.COMPREFIX_HOST="host:"
768823STruong.Q.Nguyen@Sun.COMPREFIX_NET="network:"
778823STruong.Q.Nguyen@Sun.COMPREFIX_POOL="pool:"
788823STruong.Q.Nguyen@Sun.COMPREFIX_IF="if:"
798823STruong.Q.Nguyen@Sun.COM
80*12848STony.Q.Nguyen@oracle.comGLOBAL_CONFIG=""
81*12848STony.Q.Nguyen@oracle.comGLOBAL_POLICY=""
82*12848STony.Q.Nguyen@oracle.com
838823STruong.Q.Nguyen@Sun.COMSERVINFO=/usr/lib/servinfo
848823STruong.Q.Nguyen@Sun.COM
858823STruong.Q.Nguyen@Sun.COM#
86*12848STony.Q.Nguyen@oracle.com# Get value(s) for given property from either firewall_config_default or
87*12848STony.Q.Nguyen@oracle.com# firewall_config_override property groups.
88*12848STony.Q.Nguyen@oracle.com#
89*12848STony.Q.Nguyen@oracle.com# global_get_prop_value pg_name propname
90*12848STony.Q.Nguyen@oracle.com#   pg_name - FW_CONFIG_DEF_PG or FW_CONFIG_OVR_PG
91*12848STony.Q.Nguyen@oracle.com#   propname - property name
92*12848STony.Q.Nguyen@oracle.com#
93*12848STony.Q.Nguyen@oracle.comglobal_get_prop_value()
94*12848STony.Q.Nguyen@oracle.com{
95*12848STony.Q.Nguyen@oracle.com	target_pg=$1
96*12848STony.Q.Nguyen@oracle.com	prop=$2
97*12848STony.Q.Nguyen@oracle.com
98*12848STony.Q.Nguyen@oracle.com	[ "$1" != $FW_CONFIG_OVR_PG -a "$1" != $FW_CONFIG_DEF_PG ] && return
99*12848STony.Q.Nguyen@oracle.com
100*12848STony.Q.Nguyen@oracle.com	[ "$1" == $FW_CONFIG_DEF_PG ] && extra_pg=$FW_CONFIG_OVR_PG  || \
101*12848STony.Q.Nguyen@oracle.com		extra_pg=$FW_CONFIG_DEF_PG
102*12848STony.Q.Nguyen@oracle.com
103*12848STony.Q.Nguyen@oracle.com	value=`echo $GLOBAL_CONFIG | awk '{
104*12848STony.Q.Nguyen@oracle.com		found=0
105*12848STony.Q.Nguyen@oracle.com		for (i=1; i<=NF; i++) {
106*12848STony.Q.Nguyen@oracle.com			if (found == 1) {
107*12848STony.Q.Nguyen@oracle.com				if (index($i, target_pg) == 1 || index($i, extra_pg) == 1)
108*12848STony.Q.Nguyen@oracle.com					break;
109*12848STony.Q.Nguyen@oracle.com
110*12848STony.Q.Nguyen@oracle.com				print $i;
111*12848STony.Q.Nguyen@oracle.com			}
112*12848STony.Q.Nguyen@oracle.com
113*12848STony.Q.Nguyen@oracle.com			if (split($i, values, "/") < 2)
114*12848STony.Q.Nguyen@oracle.com				continue;
115*12848STony.Q.Nguyen@oracle.com
116*12848STony.Q.Nguyen@oracle.com			if (values[1] == target_pg && values[2] == prop)
117*12848STony.Q.Nguyen@oracle.com				found=1;
118*12848STony.Q.Nguyen@oracle.com		}
119*12848STony.Q.Nguyen@oracle.com	}' target_pg=$target_pg prop=$prop extra_pg=$extra_pg`
120*12848STony.Q.Nguyen@oracle.com
121*12848STony.Q.Nguyen@oracle.com	# Return
122*12848STony.Q.Nguyen@oracle.com	echo "$value"
123*12848STony.Q.Nguyen@oracle.com}
124*12848STony.Q.Nguyen@oracle.com
125*12848STony.Q.Nguyen@oracle.com#
126*12848STony.Q.Nguyen@oracle.com# Initialize and cache network/ipfilter configuration, global configuration.
127*12848STony.Q.Nguyen@oracle.com#
128*12848STony.Q.Nguyen@oracle.com# Since an SMF service configuration may get updated during the execution of the
129*12848STony.Q.Nguyen@oracle.com# service method, it's best to read all relevant configuration via one svcprop
130*12848STony.Q.Nguyen@oracle.com# invocation and cache it for later use.
131*12848STony.Q.Nguyen@oracle.com#
132*12848STony.Q.Nguyen@oracle.com# This function reads and store relevant configuration into GLOBAL_CONFIG and
133*12848STony.Q.Nguyen@oracle.com# initializes GLOBAL_POLICY variable. GLOBAL_CONFIG is a string containing pg/prop
134*12848STony.Q.Nguyen@oracle.com# and their corresponding values (i.e. svcprop -p pg fmri output). To get values
135*12848STony.Q.Nguyen@oracle.com# for a certain pg/prop, use global_get_prop_value().
136*12848STony.Q.Nguyen@oracle.com#
137*12848STony.Q.Nguyen@oracle.comglobal_init()
138*12848STony.Q.Nguyen@oracle.com{
139*12848STony.Q.Nguyen@oracle.com	GLOBAL_CONFIG=`svcprop -p ${FW_CONFIG_OVR_PG} -p ${FW_CONFIG_DEF_PG} \
140*12848STony.Q.Nguyen@oracle.com        $IPF_FMRI 2>/dev/null | awk '{$2=" "; print $0}'`
141*12848STony.Q.Nguyen@oracle.com
142*12848STony.Q.Nguyen@oracle.com	GLOBAL_POLICY=`global_get_prop_value $FW_CONFIG_DEF_PG $POLICY_PROP`
143*12848STony.Q.Nguyen@oracle.com}
144*12848STony.Q.Nguyen@oracle.com
145*12848STony.Q.Nguyen@oracle.com#
1468823STruong.Q.Nguyen@Sun.COM# Given a service, gets its config pg name
1478823STruong.Q.Nguyen@Sun.COM#
1488823STruong.Q.Nguyen@Sun.COMget_config_pg()
1498823STruong.Q.Nguyen@Sun.COM{
1508823STruong.Q.Nguyen@Sun.COM	if [ "$1" = "$IPF_FMRI" ]; then
1518823STruong.Q.Nguyen@Sun.COM		echo "$FW_CONFIG_DEF_PG"
1528823STruong.Q.Nguyen@Sun.COM	else
1538823STruong.Q.Nguyen@Sun.COM		echo "$FW_CONFIG_PG"
1548823STruong.Q.Nguyen@Sun.COM	fi
1558823STruong.Q.Nguyen@Sun.COM	return 0
1568823STruong.Q.Nguyen@Sun.COM}
1578823STruong.Q.Nguyen@Sun.COM
1588823STruong.Q.Nguyen@Sun.COM#
1598823STruong.Q.Nguyen@Sun.COM# Given a service, gets its firewall policy
1608823STruong.Q.Nguyen@Sun.COM#
1618823STruong.Q.Nguyen@Sun.COMget_policy()
1628823STruong.Q.Nguyen@Sun.COM{
1638823STruong.Q.Nguyen@Sun.COM	config_pg=`get_config_pg $1`
1648823STruong.Q.Nguyen@Sun.COM	svcprop -p $config_pg/${POLICY_PROP} $1 2>/dev/null
1658823STruong.Q.Nguyen@Sun.COM}
1668823STruong.Q.Nguyen@Sun.COM
1678823STruong.Q.Nguyen@Sun.COM#
1688823STruong.Q.Nguyen@Sun.COM# Given a service, gets its firewall policy
1698823STruong.Q.Nguyen@Sun.COM#
1708823STruong.Q.Nguyen@Sun.COMget_exceptions()
1718823STruong.Q.Nguyen@Sun.COM{
1728823STruong.Q.Nguyen@Sun.COM	config_pg=`get_config_pg $1`
1738823STruong.Q.Nguyen@Sun.COM	svcprop -p $config_pg/${EXCEPTIONS_PROP} $1 2>/dev/null
1748823STruong.Q.Nguyen@Sun.COM}
1758823STruong.Q.Nguyen@Sun.COM
1768823STruong.Q.Nguyen@Sun.COM#
1778823STruong.Q.Nguyen@Sun.COM# Given a service, gets its firewall policy
1788823STruong.Q.Nguyen@Sun.COM#
1798823STruong.Q.Nguyen@Sun.COMget_apply2_list()
1808823STruong.Q.Nguyen@Sun.COM{
1818823STruong.Q.Nguyen@Sun.COM	config_pg=`get_config_pg $1`
1828823STruong.Q.Nguyen@Sun.COM	svcprop -p $config_pg/${APPLY2_PROP} $1 2>/dev/null
1838823STruong.Q.Nguyen@Sun.COM}
1848823STruong.Q.Nguyen@Sun.COM
1858823STruong.Q.Nguyen@Sun.COMcheck_ipf_dir()
1868823STruong.Q.Nguyen@Sun.COM{
1878823STruong.Q.Nguyen@Sun.COM	[ -d $VAR_IPF_DIR ] && return 0
1888823STruong.Q.Nguyen@Sun.COM	mkdir $VAR_IPF_DIR >/dev/null 2>&1 || return 1
1898823STruong.Q.Nguyen@Sun.COM}
1908823STruong.Q.Nguyen@Sun.COM
1918823STruong.Q.Nguyen@Sun.COM#
1928823STruong.Q.Nguyen@Sun.COM# fmri_to_file fmri suffix
1938823STruong.Q.Nguyen@Sun.COM#
1948823STruong.Q.Nguyen@Sun.COMfmri_to_file()
1958823STruong.Q.Nguyen@Sun.COM{
1968823STruong.Q.Nguyen@Sun.COM	check_ipf_dir || return 1
1978823STruong.Q.Nguyen@Sun.COM	fprefix="${VAR_IPF_DIR}/`echo $1 | tr -s '/:' '__'`"
1988823STruong.Q.Nguyen@Sun.COM	echo "${fprefix}${2}"
1998823STruong.Q.Nguyen@Sun.COM}
2008823STruong.Q.Nguyen@Sun.COM
2018823STruong.Q.Nguyen@Sun.COM#
2028823STruong.Q.Nguyen@Sun.COM# Return service's enabled property
2038823STruong.Q.Nguyen@Sun.COM#
2048823STruong.Q.Nguyen@Sun.COMservice_is_enabled()
2058823STruong.Q.Nguyen@Sun.COM{
2068823STruong.Q.Nguyen@Sun.COM	#
2078823STruong.Q.Nguyen@Sun.COM	# Temporary enabled state overrides the persistent state
2088823STruong.Q.Nguyen@Sun.COM	# so check it first.
2098823STruong.Q.Nguyen@Sun.COM	#
2108823STruong.Q.Nguyen@Sun.COM	enabled_ovr=`svcprop -c -p general_ovr/enabled $1 2>/dev/null`
2118823STruong.Q.Nguyen@Sun.COM	if [ -n "$enabled_ovr" ]; then
2128823STruong.Q.Nguyen@Sun.COM		[ "$enabled_ovr" = "true" ] && return 0 || return 1
2138823STruong.Q.Nguyen@Sun.COM	fi
2148823STruong.Q.Nguyen@Sun.COM
2158823STruong.Q.Nguyen@Sun.COM	enabled=`svcprop -c -p general/enabled $1 2>/dev/null`
2168823STruong.Q.Nguyen@Sun.COM	[ -n "$enabled" -a "$enabled" = "true" ] && return 0 || return 1
2178823STruong.Q.Nguyen@Sun.COM}
2188823STruong.Q.Nguyen@Sun.COM
2198823STruong.Q.Nguyen@Sun.COM#
2208823STruong.Q.Nguyen@Sun.COM# Return whether service is desired state
2218823STruong.Q.Nguyen@Sun.COM#
2228823STruong.Q.Nguyen@Sun.COM# Args: fmri state
2238823STruong.Q.Nguyen@Sun.COM# Return:
2248823STruong.Q.Nguyen@Sun.COM#  0 - desired state is service's current state
2258823STruong.Q.Nguyen@Sun.COM#  1 - desired state is not service's current state
2268823STruong.Q.Nguyen@Sun.COM#
2278823STruong.Q.Nguyen@Sun.COMservice_check_state()
2288823STruong.Q.Nguyen@Sun.COM{
2298823STruong.Q.Nguyen@Sun.COM	#
2308823STruong.Q.Nguyen@Sun.COM	# Make sure we're done with ongoing state transition
2318823STruong.Q.Nguyen@Sun.COM	#
2328823STruong.Q.Nguyen@Sun.COM	while [ "`svcprop -p restarter/next_state $1`" != "$SMF_NONE" ]; do
2338823STruong.Q.Nguyen@Sun.COM		sleep 1
2348823STruong.Q.Nguyen@Sun.COM	done
2358823STruong.Q.Nguyen@Sun.COM
2368823STruong.Q.Nguyen@Sun.COM	[ "`svcprop -p restarter/state $1`" = "$2" ] && return 0 || return 1
2378823STruong.Q.Nguyen@Sun.COM}
2388823STruong.Q.Nguyen@Sun.COM
2398823STruong.Q.Nguyen@Sun.COM#
2408823STruong.Q.Nguyen@Sun.COM# Deny/Allow list stores values in the form "host:addr", "network:addr/netmask",
2418823STruong.Q.Nguyen@Sun.COM# "pool:number", and "if:interface". This function returns the
2428823STruong.Q.Nguyen@Sun.COM# IP(addr or addr/netmask) value or a pool number.
2438823STruong.Q.Nguyen@Sun.COM#
2448823STruong.Q.Nguyen@Sun.COMget_IP()
2458823STruong.Q.Nguyen@Sun.COM{
2468823STruong.Q.Nguyen@Sun.COM	value_is_interface $1 && return 1
2478823STruong.Q.Nguyen@Sun.COM	echo "$1" | sed -n -e 's,^pool:\(.*\),pool/\1,p' \
2488823STruong.Q.Nguyen@Sun.COM	    -e 's,^host:\(.*\),\1,p' \
2498823STruong.Q.Nguyen@Sun.COM	    -e 's,^network:\(.*\),\1,p'
2508823STruong.Q.Nguyen@Sun.COM}
2518823STruong.Q.Nguyen@Sun.COM
2528823STruong.Q.Nguyen@Sun.COMget_interface()
2538823STruong.Q.Nguyen@Sun.COM{
2548823STruong.Q.Nguyen@Sun.COM	value_is_interface $1 || return 1
2558823STruong.Q.Nguyen@Sun.COM	scratch=`echo "$1" | sed -e 's/^if://'`
2568823STruong.Q.Nguyen@Sun.COM
2578823STruong.Q.Nguyen@Sun.COM	ifconfig $scratch >/dev/null 2>&1 || return 1
2588823STruong.Q.Nguyen@Sun.COM	echo $scratch | sed -e 's/:.*//'
2598823STruong.Q.Nguyen@Sun.COM}
2608823STruong.Q.Nguyen@Sun.COM
2618823STruong.Q.Nguyen@Sun.COM#
2628823STruong.Q.Nguyen@Sun.COM#
2638823STruong.Q.Nguyen@Sun.COM#
2648823STruong.Q.Nguyen@Sun.COMvalue_is_interface()
2658823STruong.Q.Nguyen@Sun.COM{
2668823STruong.Q.Nguyen@Sun.COM	[ -z "$1" ] && return 1
2678823STruong.Q.Nguyen@Sun.COM	echo $1 | grep "^if:" >/dev/null 2>&1
2688823STruong.Q.Nguyen@Sun.COM}
2698823STruong.Q.Nguyen@Sun.COM
2708823STruong.Q.Nguyen@Sun.COM#
2718823STruong.Q.Nguyen@Sun.COM# Remove rules in given file from active list without restarting ipfilter
2728823STruong.Q.Nguyen@Sun.COM#
2738823STruong.Q.Nguyen@Sun.COMremove_rules()
2748823STruong.Q.Nguyen@Sun.COM{
2758823STruong.Q.Nguyen@Sun.COM	[ -f "$1" ] && ipf -r -f $1 >/dev/null 2>&1
2768823STruong.Q.Nguyen@Sun.COM}
2778823STruong.Q.Nguyen@Sun.COM
2788823STruong.Q.Nguyen@Sun.COMremove_nat_rules()
2798823STruong.Q.Nguyen@Sun.COM{
2808823STruong.Q.Nguyen@Sun.COM	[ -f "$1" ] && ipnat -r -f $1 >/dev/null 2>&1
2818823STruong.Q.Nguyen@Sun.COM}
2828823STruong.Q.Nguyen@Sun.COM
2838823STruong.Q.Nguyen@Sun.COMcheck_ipf_syntax()
2848823STruong.Q.Nguyen@Sun.COM{
2858823STruong.Q.Nguyen@Sun.COM	ipf -n -f $1 >/dev/null 2>&1
2868823STruong.Q.Nguyen@Sun.COM}
2878823STruong.Q.Nguyen@Sun.COM
2888823STruong.Q.Nguyen@Sun.COMcheck_nat_syntax()
2898823STruong.Q.Nguyen@Sun.COM{
2908823STruong.Q.Nguyen@Sun.COM	ipnat -n -f $1 >/dev/null 2>&1
2918823STruong.Q.Nguyen@Sun.COM}
2928823STruong.Q.Nguyen@Sun.COM
2938823STruong.Q.Nguyen@Sun.COMfile_get_ports()
2948823STruong.Q.Nguyen@Sun.COM{
2958823STruong.Q.Nguyen@Sun.COM	ipf -n -v -f $1 2>/dev/null | sed -n -e \
2968823STruong.Q.Nguyen@Sun.COM	    's/.*to.* port = \([a-z0-9]*\).*/\1/p' | uniq | \
2978823STruong.Q.Nguyen@Sun.COM	    awk '{if (length($0) > 1) {printf("%s ", $1)}}'
2988823STruong.Q.Nguyen@Sun.COM}
2998823STruong.Q.Nguyen@Sun.COM
3008823STruong.Q.Nguyen@Sun.COMget_active_ports()
3018823STruong.Q.Nguyen@Sun.COM{
3028823STruong.Q.Nguyen@Sun.COM	ipfstat -io 2>/dev/null | sed -n -e \
3038823STruong.Q.Nguyen@Sun.COM	    's/.*to.* port = \([a-z0-9]*\).*/\1/p' | uniq | \
3048823STruong.Q.Nguyen@Sun.COM	    awk '{if (length($0) > 1) {printf("%s ",$1)}}'
3058823STruong.Q.Nguyen@Sun.COM}
3068823STruong.Q.Nguyen@Sun.COM
3078823STruong.Q.Nguyen@Sun.COM#
3088823STruong.Q.Nguyen@Sun.COM# Given two list of ports, return failure if there's a duplicate.
3098823STruong.Q.Nguyen@Sun.COM#
3108823STruong.Q.Nguyen@Sun.COMsets_check_duplicate()
3118823STruong.Q.Nguyen@Sun.COM{
3128823STruong.Q.Nguyen@Sun.COM	#
3138823STruong.Q.Nguyen@Sun.COM	# If either list is empty, there isn't any conflict.
3148823STruong.Q.Nguyen@Sun.COM	#
3158823STruong.Q.Nguyen@Sun.COM	[ -z "$1" -o -z "$2" ] && return 0
3168823STruong.Q.Nguyen@Sun.COM
3178823STruong.Q.Nguyen@Sun.COM	for p in $1; do
3188823STruong.Q.Nguyen@Sun.COM		for ap in $2; do
3198823STruong.Q.Nguyen@Sun.COM			[ "$p" = "$ap" ] && return 1
3208823STruong.Q.Nguyen@Sun.COM		done
3218823STruong.Q.Nguyen@Sun.COM	done
3228823STruong.Q.Nguyen@Sun.COM
3238823STruong.Q.Nguyen@Sun.COM	return 0
3248823STruong.Q.Nguyen@Sun.COM}
3258823STruong.Q.Nguyen@Sun.COM
3268823STruong.Q.Nguyen@Sun.COM#
3278823STruong.Q.Nguyen@Sun.COM# Given a file containing ipf rules, check the syntax and verify
3288823STruong.Q.Nguyen@Sun.COM# the rules don't conflict, use same port number, with active
3298823STruong.Q.Nguyen@Sun.COM# rules (ipfstat -io output).
3308823STruong.Q.Nguyen@Sun.COM#
3318823STruong.Q.Nguyen@Sun.COMupdate_check_ipf_rules()
3328823STruong.Q.Nguyen@Sun.COM{
3338823STruong.Q.Nguyen@Sun.COM	check_ipf_syntax $1 || return 1
3348823STruong.Q.Nguyen@Sun.COM
3358823STruong.Q.Nguyen@Sun.COM	lports=`file_get_ports $1`
3368823STruong.Q.Nguyen@Sun.COM	lactive_ports=`get_active_ports`
3378823STruong.Q.Nguyen@Sun.COM
3388823STruong.Q.Nguyen@Sun.COM	sets_check_duplicate "$lports" "$lactive_ports" || return 1
3398823STruong.Q.Nguyen@Sun.COM}
3408823STruong.Q.Nguyen@Sun.COM
3418823STruong.Q.Nguyen@Sun.COMserver_port_list=""
3428823STruong.Q.Nguyen@Sun.COM
3438823STruong.Q.Nguyen@Sun.COM#
3448823STruong.Q.Nguyen@Sun.COM# Given a file containing ipf rules, check the syntax and verify
3458823STruong.Q.Nguyen@Sun.COM# the rules don't conflict with already processed services.
3468823STruong.Q.Nguyen@Sun.COM#
3478823STruong.Q.Nguyen@Sun.COM# The list of processed services' ports are maintained in the global
3488823STruong.Q.Nguyen@Sun.COM# variable 'server_port_list'.
3498823STruong.Q.Nguyen@Sun.COM#
3508823STruong.Q.Nguyen@Sun.COMcheck_ipf_rules()
3518823STruong.Q.Nguyen@Sun.COM{
3528823STruong.Q.Nguyen@Sun.COM	check_ipf_syntax $1 || return 1
3538823STruong.Q.Nguyen@Sun.COM
3548823STruong.Q.Nguyen@Sun.COM	lports=`file_get_ports $1`
3558823STruong.Q.Nguyen@Sun.COM	sets_check_duplicate "$lports" "$server_port_list" || return 1
3568823STruong.Q.Nguyen@Sun.COM	server_port_list="$server_port_list $lports"
3578823STruong.Q.Nguyen@Sun.COM	return 0
3588823STruong.Q.Nguyen@Sun.COM}
3598823STruong.Q.Nguyen@Sun.COM
3608823STruong.Q.Nguyen@Sun.COMprepend_new_rules()
3618823STruong.Q.Nguyen@Sun.COM{
3628823STruong.Q.Nguyen@Sun.COM	check_ipf_syntax $1 && tail -r $1 | sed -e 's/^[a-z]/@0 &/' | \
3638823STruong.Q.Nguyen@Sun.COM	    ipf -f - >/dev/null 2>&1
3648823STruong.Q.Nguyen@Sun.COM}
3658823STruong.Q.Nguyen@Sun.COM
3668823STruong.Q.Nguyen@Sun.COMappend_new_rules()
3678823STruong.Q.Nguyen@Sun.COM{
3688823STruong.Q.Nguyen@Sun.COM	check_ipf_syntax $1 && ipf -f $1 >/dev/null 2>&1
3698823STruong.Q.Nguyen@Sun.COM}
3708823STruong.Q.Nguyen@Sun.COM
3718823STruong.Q.Nguyen@Sun.COMappend_new_nat_rules()
3728823STruong.Q.Nguyen@Sun.COM{
3738823STruong.Q.Nguyen@Sun.COM	check_nat_syntax $1 && ipnat -f $1 >/dev/null 2>&1
3748823STruong.Q.Nguyen@Sun.COM}
3758823STruong.Q.Nguyen@Sun.COM
3768823STruong.Q.Nguyen@Sun.COM#
3778823STruong.Q.Nguyen@Sun.COM# get port information from string of the form "proto:{port | port-port}"
3788823STruong.Q.Nguyen@Sun.COM#
3798823STruong.Q.Nguyen@Sun.COMtuple_get_port()
3808823STruong.Q.Nguyen@Sun.COM{
3818823STruong.Q.Nguyen@Sun.COM	port_str=`echo "$1" | sed -e 's/ //g; s/.*://' 2>/dev/null`
3828823STruong.Q.Nguyen@Sun.COM	[ -z "$port_str" ] && return 1
3838823STruong.Q.Nguyen@Sun.COM
3848823STruong.Q.Nguyen@Sun.COM	echo $port_str | grep "-" >/dev/null
3858823STruong.Q.Nguyen@Sun.COM	if  [ $? -eq  0 ]; then
3868823STruong.Q.Nguyen@Sun.COM		echo $port_str | grep '^[0-9]\{1,5\}-[0-9]\{1,5\}$' >/dev/null || \
3878823STruong.Q.Nguyen@Sun.COM		    return 1
3888823STruong.Q.Nguyen@Sun.COM		ports=`echo $port_str | ( IFS=- read a b ; \
3898823STruong.Q.Nguyen@Sun.COM		    [ $a \-le $b ] && echo $a $b || echo $b $a )`
3908823STruong.Q.Nguyen@Sun.COM
3918823STruong.Q.Nguyen@Sun.COM		for p in $ports; do
3928823STruong.Q.Nguyen@Sun.COM			[ $p -gt 65535 ] && return 1
3938823STruong.Q.Nguyen@Sun.COM		done
3948823STruong.Q.Nguyen@Sun.COM		echo "$ports"
3958823STruong.Q.Nguyen@Sun.COM	else
3968823STruong.Q.Nguyen@Sun.COM		#
3978823STruong.Q.Nguyen@Sun.COM		# port_str is a single port, verify and return it.
3988823STruong.Q.Nguyen@Sun.COM		#
3998823STruong.Q.Nguyen@Sun.COM		echo "$port_str" | grep '^[0-9]\{1,5\}$' >/dev/null || return 1
4008823STruong.Q.Nguyen@Sun.COM		[ $port_str -gt 65535 ] && return 1
4018823STruong.Q.Nguyen@Sun.COM		echo "$port_str"
4028823STruong.Q.Nguyen@Sun.COM	fi
4038823STruong.Q.Nguyen@Sun.COM}
4048823STruong.Q.Nguyen@Sun.COM
4058823STruong.Q.Nguyen@Sun.COM#
4068823STruong.Q.Nguyen@Sun.COM# get proto info from string of the form "{tcp | udp}:port"
4078823STruong.Q.Nguyen@Sun.COM#
4088823STruong.Q.Nguyen@Sun.COMtuple_get_proto()
4098823STruong.Q.Nguyen@Sun.COM{
4108823STruong.Q.Nguyen@Sun.COM	proto=`echo "$1" | sed -e 's/ //g; s/:.*//' 2>/dev/null`
4118823STruong.Q.Nguyen@Sun.COM	[ -z "$proto" ] && return 0
4128823STruong.Q.Nguyen@Sun.COM
4138823STruong.Q.Nguyen@Sun.COM	[ "$proto" = "tcp" -o "$proto" = "udp" ] && echo $proto || return 1
4148823STruong.Q.Nguyen@Sun.COM	return 0
4158823STruong.Q.Nguyen@Sun.COM}
4168823STruong.Q.Nguyen@Sun.COM
4178823STruong.Q.Nguyen@Sun.COMipf_get_lock()
4188823STruong.Q.Nguyen@Sun.COM{
4198823STruong.Q.Nguyen@Sun.COM	newpid=$$
4208823STruong.Q.Nguyen@Sun.COM
4218823STruong.Q.Nguyen@Sun.COM	if [ -f "$IPF_LOCK/pid" ]; then
4228823STruong.Q.Nguyen@Sun.COM		curpid=`cat $IPF_LOCK/pid 2>/dev/null`
4238823STruong.Q.Nguyen@Sun.COM		[ "$curpid" = "$newpid" ] && return 0
4248823STruong.Q.Nguyen@Sun.COM
4258823STruong.Q.Nguyen@Sun.COM		#
4268823STruong.Q.Nguyen@Sun.COM		# Clear lock if the owning process is no longer around.
4278823STruong.Q.Nguyen@Sun.COM		#
4288823STruong.Q.Nguyen@Sun.COM		ps -p $curpid >/dev/null 2>&1 || rm -r $IPF_LOCK >/dev/null 2>&1
4298823STruong.Q.Nguyen@Sun.COM	fi
4308823STruong.Q.Nguyen@Sun.COM
4318823STruong.Q.Nguyen@Sun.COM	#
4328823STruong.Q.Nguyen@Sun.COM	# Grab the lock
4338823STruong.Q.Nguyen@Sun.COM	#
4348823STruong.Q.Nguyen@Sun.COM	while :; do
4358823STruong.Q.Nguyen@Sun.COM		mkdir $IPF_LOCK 2>/dev/null && break;
4368823STruong.Q.Nguyen@Sun.COM		sleep 1
4378823STruong.Q.Nguyen@Sun.COM	done
4388823STruong.Q.Nguyen@Sun.COM	echo $newpid > $IPF_LOCK/pid
4398823STruong.Q.Nguyen@Sun.COM}
4408823STruong.Q.Nguyen@Sun.COM
4418823STruong.Q.Nguyen@Sun.COM#
4428823STruong.Q.Nguyen@Sun.COM# Remove lock if it's ours
4438823STruong.Q.Nguyen@Sun.COM#
4448823STruong.Q.Nguyen@Sun.COMipf_remove_lock()
4458823STruong.Q.Nguyen@Sun.COM{
4468823STruong.Q.Nguyen@Sun.COM	if [ -f "$IPF_LOCK/pid" ]; then
4478823STruong.Q.Nguyen@Sun.COM		[ "`cat $IPF_LOCK/pid`" = "$$" ] && rm -r $IPF_LOCK
4488823STruong.Q.Nguyen@Sun.COM	fi
4498823STruong.Q.Nguyen@Sun.COM	return 0
4508823STruong.Q.Nguyen@Sun.COM}
4518823STruong.Q.Nguyen@Sun.COM
4528823STruong.Q.Nguyen@Sun.COM#
4538823STruong.Q.Nguyen@Sun.COM# Make IPFILCONF, /var/tmp/ipf/ipf.conf, a symlink to the input file argument.
4548823STruong.Q.Nguyen@Sun.COM#
4558823STruong.Q.Nguyen@Sun.COMcustom_set_symlink()
4568823STruong.Q.Nguyen@Sun.COM{
4578823STruong.Q.Nguyen@Sun.COM	#
4588846STruong.Q.Nguyen@Sun.COM	# Nothing to do if the input file doesn't exist.
4598823STruong.Q.Nguyen@Sun.COM	#
4608823STruong.Q.Nguyen@Sun.COM	[ ! -f "$1" ] && return 0
4618823STruong.Q.Nguyen@Sun.COM
4628846STruong.Q.Nguyen@Sun.COM	check_ipf_dir || return 1
4638846STruong.Q.Nguyen@Sun.COM
4648823STruong.Q.Nguyen@Sun.COM	rm $IPFILCONF >/dev/null 2>&1
4658823STruong.Q.Nguyen@Sun.COM	ln -s $1 $IPFILCONF >/dev/null 2>&1
4668823STruong.Q.Nguyen@Sun.COM}
4678823STruong.Q.Nguyen@Sun.COM
4688823STruong.Q.Nguyen@Sun.COM#
4698823STruong.Q.Nguyen@Sun.COM# New file replaces original file if they have different content
4708823STruong.Q.Nguyen@Sun.COM#
4718823STruong.Q.Nguyen@Sun.COMreplace_file()
4728823STruong.Q.Nguyen@Sun.COM{
4738823STruong.Q.Nguyen@Sun.COM	orig=$1
4748823STruong.Q.Nguyen@Sun.COM	new=$2
4758823STruong.Q.Nguyen@Sun.COM
4768823STruong.Q.Nguyen@Sun.COM	#
4778823STruong.Q.Nguyen@Sun.COM	# IPFILCONF may be a symlink, remove it if that's the case
4788823STruong.Q.Nguyen@Sun.COM	#
4798823STruong.Q.Nguyen@Sun.COM	if [ -L "$orig" ]; then
4808823STruong.Q.Nguyen@Sun.COM		rm $orig
4818823STruong.Q.Nguyen@Sun.COM		touch $orig
4828823STruong.Q.Nguyen@Sun.COM	fi
4838823STruong.Q.Nguyen@Sun.COM
4848846STruong.Q.Nguyen@Sun.COM	check_ipf_dir || return 1
4858823STruong.Q.Nguyen@Sun.COM	mv $new $orig && return 0 || return 1
4868823STruong.Q.Nguyen@Sun.COM}
4878823STruong.Q.Nguyen@Sun.COM
4888823STruong.Q.Nguyen@Sun.COM#
4898823STruong.Q.Nguyen@Sun.COM# Given a service, gets the following details for ipf rule:
4908823STruong.Q.Nguyen@Sun.COM# - policy
4918823STruong.Q.Nguyen@Sun.COM# - protocol
4928823STruong.Q.Nguyen@Sun.COM# - port(IANA port obtained by running servinfo)
4938823STruong.Q.Nguyen@Sun.COM#
4948823STruong.Q.Nguyen@Sun.COMprocess_server_svc()
4958823STruong.Q.Nguyen@Sun.COM{
4968823STruong.Q.Nguyen@Sun.COM	service=$1
4978823STruong.Q.Nguyen@Sun.COM	ip="any"
4988823STruong.Q.Nguyen@Sun.COM        policy=`get_policy ${service}`
4998823STruong.Q.Nguyen@Sun.COM
5008823STruong.Q.Nguyen@Sun.COM	#
5018823STruong.Q.Nguyen@Sun.COM	# Empties service's rules file so callers won't use existing rule if
5028823STruong.Q.Nguyen@Sun.COM	# we fail here.
5038823STruong.Q.Nguyen@Sun.COM	#
5048823STruong.Q.Nguyen@Sun.COM	file=`fmri_to_file $service $IPF_SUFFIX`
5058823STruong.Q.Nguyen@Sun.COM	[ -z "$file" ] && return 1
5068823STruong.Q.Nguyen@Sun.COM	echo "# $service" >${file}
5078823STruong.Q.Nguyen@Sun.COM
5088823STruong.Q.Nguyen@Sun.COM	#
5098823STruong.Q.Nguyen@Sun.COM	# Nothing to do if policy is "use_global"
5108823STruong.Q.Nguyen@Sun.COM	#
5118823STruong.Q.Nguyen@Sun.COM	[ "$policy" = "use_global" ] && return 0
5128823STruong.Q.Nguyen@Sun.COM
5138823STruong.Q.Nguyen@Sun.COM	restarter=`svcprop -p general/restarter $service 2>/dev/null`
5148823STruong.Q.Nguyen@Sun.COM	if [ "$restarter" = "$INETDFMRI" ]; then
5158823STruong.Q.Nguyen@Sun.COM		iana_name=`svcprop -p inetd/name $service 2>/dev/null`
5168823STruong.Q.Nguyen@Sun.COM		isrpc=`svcprop -p inetd/isrpc $service 2>/dev/null`
5178823STruong.Q.Nguyen@Sun.COM	else
5188823STruong.Q.Nguyen@Sun.COM		iana_name=`svcprop -p $FW_CONTEXT_PG/name $service 2>/dev/null`
5198823STruong.Q.Nguyen@Sun.COM		isrpc=`svcprop -p $FW_CONTEXT_PG/isrpc $service 2>/dev/null`
5208823STruong.Q.Nguyen@Sun.COM	fi
5218823STruong.Q.Nguyen@Sun.COM
5228823STruong.Q.Nguyen@Sun.COM	#
5238823STruong.Q.Nguyen@Sun.COM	# Bail if iana_name isn't defined. Services with static rules
5248823STruong.Q.Nguyen@Sun.COM	# like nis/client don't need to generate rules using
5258823STruong.Q.Nguyen@Sun.COM	# iana name and protocol information.
5268823STruong.Q.Nguyen@Sun.COM	#
5278823STruong.Q.Nguyen@Sun.COM	[ -z "$iana_name" ] && return 1
5288823STruong.Q.Nguyen@Sun.COM
5298823STruong.Q.Nguyen@Sun.COM	#
5308823STruong.Q.Nguyen@Sun.COM	# RPC services
5318823STruong.Q.Nguyen@Sun.COM	#
5328823STruong.Q.Nguyen@Sun.COM	if [ "$isrpc" = "true" ]; then
5338823STruong.Q.Nguyen@Sun.COM		tports=`$SERVINFO -R -p -t -s $iana_name 2>/dev/null`
5348823STruong.Q.Nguyen@Sun.COM		if [ -n "$tports" ]; then
5358823STruong.Q.Nguyen@Sun.COM			for tport in $tports; do
5368823STruong.Q.Nguyen@Sun.COM				generate_rules $service $policy "tcp" \
5378823STruong.Q.Nguyen@Sun.COM				    $ip $tport $file
5388823STruong.Q.Nguyen@Sun.COM			done
5398823STruong.Q.Nguyen@Sun.COM		fi
5408823STruong.Q.Nguyen@Sun.COM
5418823STruong.Q.Nguyen@Sun.COM		uports=`$SERVINFO -R -p -u -s $iana_name 2>/dev/null`
5428823STruong.Q.Nguyen@Sun.COM		if [ -n "$uports" ]; then
5438823STruong.Q.Nguyen@Sun.COM			for uport in $uports; do
5448823STruong.Q.Nguyen@Sun.COM				generate_rules $service $policy "udp" \
5458823STruong.Q.Nguyen@Sun.COM				    $ip $uport $file
5468823STruong.Q.Nguyen@Sun.COM			done
5478823STruong.Q.Nguyen@Sun.COM		fi
5488823STruong.Q.Nguyen@Sun.COM
5498823STruong.Q.Nguyen@Sun.COM		return 0
5508823STruong.Q.Nguyen@Sun.COM	fi
5518823STruong.Q.Nguyen@Sun.COM
5528823STruong.Q.Nguyen@Sun.COM	#
5538823STruong.Q.Nguyen@Sun.COM	# Get the IANA port and supported protocols(tcp and udp)
5548823STruong.Q.Nguyen@Sun.COM	# No support for IPv6 at this point.
5558823STruong.Q.Nguyen@Sun.COM	#
5568823STruong.Q.Nguyen@Sun.COM	tport=`$SERVINFO -p -t -s $iana_name 2>&1`
5578823STruong.Q.Nguyen@Sun.COM	if [ $? -eq 0 -a -n "$tport" ]; then
5588823STruong.Q.Nguyen@Sun.COM		generate_rules $service $policy "tcp" $ip $tport $file
5598823STruong.Q.Nguyen@Sun.COM	fi
5608823STruong.Q.Nguyen@Sun.COM
5618823STruong.Q.Nguyen@Sun.COM	uport=`$SERVINFO -p -u -s $iana_name 2>&1`
5628823STruong.Q.Nguyen@Sun.COM	if [ $? -eq 0 -a -n "$uport" ]; then
5638823STruong.Q.Nguyen@Sun.COM		generate_rules $service $policy "udp" $ip $uport $file
5648823STruong.Q.Nguyen@Sun.COM	fi
5658823STruong.Q.Nguyen@Sun.COM
5668823STruong.Q.Nguyen@Sun.COM	return 0
5678823STruong.Q.Nguyen@Sun.COM}
5688823STruong.Q.Nguyen@Sun.COM
5698823STruong.Q.Nguyen@Sun.COM#
5708823STruong.Q.Nguyen@Sun.COM# Given a service's name, policy, protocol and port, generate ipf rules
5718823STruong.Q.Nguyen@Sun.COM# - list of host/network/interface to apply policy
5728823STruong.Q.Nguyen@Sun.COM#
5738823STruong.Q.Nguyen@Sun.COM# A 'use_global' policy inherits the system-wided Global Default policy
5748823STruong.Q.Nguyen@Sun.COM# from network/ipfilter. For {deny | allow} policies, the rules are
5758823STruong.Q.Nguyen@Sun.COM# ordered as:
5768823STruong.Q.Nguyen@Sun.COM#
5778823STruong.Q.Nguyen@Sun.COM# - make exceptions to policy for those in "exceptions" list
5788823STruong.Q.Nguyen@Sun.COM# - apply policy to those specified in "apply_to" list
5798823STruong.Q.Nguyen@Sun.COM# - policy rule
5808823STruong.Q.Nguyen@Sun.COM#
5818823STruong.Q.Nguyen@Sun.COMgenerate_rules()
5828823STruong.Q.Nguyen@Sun.COM{
5838823STruong.Q.Nguyen@Sun.COM	service=$1
5848823STruong.Q.Nguyen@Sun.COM	mypolicy=$2
5858823STruong.Q.Nguyen@Sun.COM	proto=$3
5868823STruong.Q.Nguyen@Sun.COM	ip=$4
5878823STruong.Q.Nguyen@Sun.COM	port=$5
5888823STruong.Q.Nguyen@Sun.COM	out=$6
5898823STruong.Q.Nguyen@Sun.COM
5908823STruong.Q.Nguyen@Sun.COM	#
5918823STruong.Q.Nguyen@Sun.COM	# Default mode is to inherit from global's policy
5928823STruong.Q.Nguyen@Sun.COM	#
5938823STruong.Q.Nguyen@Sun.COM	[ "$mypolicy" = "use_global" ] && return 0
5948823STruong.Q.Nguyen@Sun.COM
5958823STruong.Q.Nguyen@Sun.COM	tcp_opts=""
5968823STruong.Q.Nguyen@Sun.COM	[ "$proto" = "tcp" ] && tcp_opts="flags S keep state keep frags"
5978823STruong.Q.Nguyen@Sun.COM
5988823STruong.Q.Nguyen@Sun.COM	#
5998823STruong.Q.Nguyen@Sun.COM	# Allow all if policy is 'none'
6008823STruong.Q.Nguyen@Sun.COM	#
6018823STruong.Q.Nguyen@Sun.COM	if [ "$mypolicy" = "none" ]; then
6028823STruong.Q.Nguyen@Sun.COM		echo "pass in log quick proto ${proto} from any to ${ip}" \
6038823STruong.Q.Nguyen@Sun.COM		    "port = ${port} ${tcp_opts}" >>${out}
6048823STruong.Q.Nguyen@Sun.COM		return 0
6058823STruong.Q.Nguyen@Sun.COM	fi
6068823STruong.Q.Nguyen@Sun.COM
6078823STruong.Q.Nguyen@Sun.COM	#
6088823STruong.Q.Nguyen@Sun.COM	# For now, let's concern only with incoming traffic.
6098823STruong.Q.Nguyen@Sun.COM	#
6108823STruong.Q.Nguyen@Sun.COM	[ "$mypolicy" = "deny" ] && { ecmd="pass"; acmd="block"; }
6118823STruong.Q.Nguyen@Sun.COM	[ "$mypolicy" = "allow" ] && { ecmd="block"; acmd="pass"; }
6128823STruong.Q.Nguyen@Sun.COM
6138823STruong.Q.Nguyen@Sun.COM	for name in `get_exceptions $service`; do
6148823STruong.Q.Nguyen@Sun.COM		[ -z "$name" -o "$name" = '""' ] && continue
6158823STruong.Q.Nguyen@Sun.COM
6168823STruong.Q.Nguyen@Sun.COM		ifc=`get_interface $name`
6178823STruong.Q.Nguyen@Sun.COM		if [ $? -eq 0 -a -n "$ifc" ]; then
6188823STruong.Q.Nguyen@Sun.COM			echo "${ecmd} in log quick on ${ifc} from any to" \
6198823STruong.Q.Nguyen@Sun.COM			    "${ip} port = ${port}" >>${out}
6208823STruong.Q.Nguyen@Sun.COM			continue
6218823STruong.Q.Nguyen@Sun.COM		fi
6228823STruong.Q.Nguyen@Sun.COM
6238823STruong.Q.Nguyen@Sun.COM		addr=`get_IP ${name}`
6248823STruong.Q.Nguyen@Sun.COM		if [ $? -eq 0 -a -n "$addr" ]; then
6258823STruong.Q.Nguyen@Sun.COM			echo "${ecmd} in log quick proto ${proto} from ${addr}" \
6268823STruong.Q.Nguyen@Sun.COM			    "to ${ip} port = ${port} ${tcp_opts}" >>${out}
6278823STruong.Q.Nguyen@Sun.COM		fi
6288823STruong.Q.Nguyen@Sun.COM	done
6298823STruong.Q.Nguyen@Sun.COM
6308823STruong.Q.Nguyen@Sun.COM	for name in `get_apply2_list $service`; do
6318823STruong.Q.Nguyen@Sun.COM		[ -z "$name" -o "$name" = '""' ] && continue
6328823STruong.Q.Nguyen@Sun.COM
6338823STruong.Q.Nguyen@Sun.COM		ifc=`get_interface $name`
6348823STruong.Q.Nguyen@Sun.COM		if [ $? -eq 0 -a -n "$ifc" ]; then
6358823STruong.Q.Nguyen@Sun.COM			echo "${acmd} in log quick on ${ifc} from any to" \
6368823STruong.Q.Nguyen@Sun.COM			    "${ip} port = ${port}" >>${out}
6378823STruong.Q.Nguyen@Sun.COM			continue
6388823STruong.Q.Nguyen@Sun.COM		fi
6398823STruong.Q.Nguyen@Sun.COM
6408823STruong.Q.Nguyen@Sun.COM		addr=`get_IP ${name}`
6418823STruong.Q.Nguyen@Sun.COM		if [ $? -eq 0 -a -n "$addr" ]; then
6428823STruong.Q.Nguyen@Sun.COM			echo "${acmd} in log quick proto ${proto} from ${addr}" \
6438823STruong.Q.Nguyen@Sun.COM			    "to ${ip} port = ${port} ${tcp_opts}" >>${out}
6448823STruong.Q.Nguyen@Sun.COM		fi
6458823STruong.Q.Nguyen@Sun.COM	done
6468823STruong.Q.Nguyen@Sun.COM
6478823STruong.Q.Nguyen@Sun.COM	echo "${ecmd} in log quick proto ${proto} from any to ${ip}" \
6488823STruong.Q.Nguyen@Sun.COM	    "port = ${port} ${tcp_opts}" >>${out}
6498823STruong.Q.Nguyen@Sun.COM
6508823STruong.Q.Nguyen@Sun.COM	return 0
6518823STruong.Q.Nguyen@Sun.COM}
6528823STruong.Q.Nguyen@Sun.COM
6538823STruong.Q.Nguyen@Sun.COM#
6548823STruong.Q.Nguyen@Sun.COM# Service has either IANA ports and proto or its own firewall method to
6558823STruong.Q.Nguyen@Sun.COM# generate the rules.
6568823STruong.Q.Nguyen@Sun.COM#
6578823STruong.Q.Nguyen@Sun.COM# - if service has a custom method, use it to populate its rules
6588823STruong.Q.Nguyen@Sun.COM# - if service has a firewall_config pg, use process_server_svc
6598823STruong.Q.Nguyen@Sun.COM#
6608823STruong.Q.Nguyen@Sun.COM# Argument - fmri
6618823STruong.Q.Nguyen@Sun.COM#
6628823STruong.Q.Nguyen@Sun.COMprocess_service()
6638823STruong.Q.Nguyen@Sun.COM{
6648823STruong.Q.Nguyen@Sun.COM	#
6658823STruong.Q.Nguyen@Sun.COM	# Don't process network/ipfilter
6668823STruong.Q.Nguyen@Sun.COM	#
6678823STruong.Q.Nguyen@Sun.COM	[ "$1" = "$IPF_FMRI" ] && return 0
6688823STruong.Q.Nguyen@Sun.COM
6698823STruong.Q.Nguyen@Sun.COM	service_check_state $1 $SMF_MAINT && return 1
6708823STruong.Q.Nguyen@Sun.COM
6718823STruong.Q.Nguyen@Sun.COM	method=`svcprop -p $FW_CONTEXT_PG/$METHOD_PROP $1 2>/dev/null | \
6728823STruong.Q.Nguyen@Sun.COM	    sed 's/\\\//g'`
6738823STruong.Q.Nguyen@Sun.COM	if [ -n "$method" -a "$method" != '""' ]; then
6748823STruong.Q.Nguyen@Sun.COM		( exec $method $1 >/dev/null )
6758823STruong.Q.Nguyen@Sun.COM	else
6768823STruong.Q.Nguyen@Sun.COM		svcprop -p $FW_CONFIG_PG $1 >/dev/null 2>&1 || return 1
6778823STruong.Q.Nguyen@Sun.COM		process_server_svc $1 || return 1
6788823STruong.Q.Nguyen@Sun.COM	fi
6798823STruong.Q.Nguyen@Sun.COM	return 0
6808823STruong.Q.Nguyen@Sun.COM}
6818823STruong.Q.Nguyen@Sun.COM
6828823STruong.Q.Nguyen@Sun.COM#
6838823STruong.Q.Nguyen@Sun.COM# Generate rules for protocol/port defined in firewall_config_default/open_ports
6848823STruong.Q.Nguyen@Sun.COM# property. These are non-service programs whose network resource info are
6858823STruong.Q.Nguyen@Sun.COM# defined as "{tcp | upd}:{PORT | PORT-PORT}". Essentially, these programs need
6868823STruong.Q.Nguyen@Sun.COM# some specific local ports to be opened. For example, BitTorrent clients need to
6878823STruong.Q.Nguyen@Sun.COM# have 6881-6889 opened.
6888823STruong.Q.Nguyen@Sun.COM#
6898823STruong.Q.Nguyen@Sun.COMprocess_nonsvc_progs()
6908823STruong.Q.Nguyen@Sun.COM{
6918823STruong.Q.Nguyen@Sun.COM	out=$1
6928823STruong.Q.Nguyen@Sun.COM	echo "# Non-service programs rules" >>${out}
693*12848STony.Q.Nguyen@oracle.com	progs=`global_get_prop_value $FW_CONFIG_DEF_PG $OPEN_PORTS_PROP`
6948823STruong.Q.Nguyen@Sun.COM
6958823STruong.Q.Nguyen@Sun.COM	for prog in $progs; do
6968823STruong.Q.Nguyen@Sun.COM		[ -z "$prog" -o "$prog" = '""' ] && continue
6978823STruong.Q.Nguyen@Sun.COM
6988823STruong.Q.Nguyen@Sun.COM		port=`tuple_get_port $prog`
6998823STruong.Q.Nguyen@Sun.COM		[ $? -eq 1 -o -z "$port" ] && continue
7008823STruong.Q.Nguyen@Sun.COM
7018823STruong.Q.Nguyen@Sun.COM		proto=`tuple_get_proto $prog`
7028823STruong.Q.Nguyen@Sun.COM		[ $? -eq 1 ] && continue
7038823STruong.Q.Nguyen@Sun.COM
7048823STruong.Q.Nguyen@Sun.COM		set -- $port
7058823STruong.Q.Nguyen@Sun.COM		if  [ $# -gt 1 ]; then
7068823STruong.Q.Nguyen@Sun.COM			if [ -z "$proto" ]; then
7078823STruong.Q.Nguyen@Sun.COM				echo "pass in log quick from any to any" \
7088823STruong.Q.Nguyen@Sun.COM				    "port ${1} >< ${2}" >>${out}
7098823STruong.Q.Nguyen@Sun.COM			else
7108823STruong.Q.Nguyen@Sun.COM				echo "pass in log quick proto ${proto} from any" \
7118823STruong.Q.Nguyen@Sun.COM				    "to any port ${1} >< ${2}" >>${out}
7128823STruong.Q.Nguyen@Sun.COM			fi
7138823STruong.Q.Nguyen@Sun.COM		else
7148823STruong.Q.Nguyen@Sun.COM			if [ -z "$proto" ]; then
7158823STruong.Q.Nguyen@Sun.COM				echo "pass in log quick from any to any" \
7168823STruong.Q.Nguyen@Sun.COM				    "port = ${1}" >>${out}
7178823STruong.Q.Nguyen@Sun.COM			else
7188823STruong.Q.Nguyen@Sun.COM				echo "pass in log quick proto ${proto} from any" \
7198823STruong.Q.Nguyen@Sun.COM				    "to any port = ${1}" >>${out}
7208823STruong.Q.Nguyen@Sun.COM			fi
7218823STruong.Q.Nguyen@Sun.COM		fi
7228823STruong.Q.Nguyen@Sun.COM	done
7238823STruong.Q.Nguyen@Sun.COM
7248823STruong.Q.Nguyen@Sun.COM	return 0
7258823STruong.Q.Nguyen@Sun.COM}
7268823STruong.Q.Nguyen@Sun.COM
7278823STruong.Q.Nguyen@Sun.COM#
7288823STruong.Q.Nguyen@Sun.COM# Generate a new /etc/ipf/ipf.conf. If firewall policy is 'none',
7298823STruong.Q.Nguyen@Sun.COM# ipf.conf is empty .
7308823STruong.Q.Nguyen@Sun.COM#
7318823STruong.Q.Nguyen@Sun.COMcreate_global_rules()
7328823STruong.Q.Nguyen@Sun.COM{
733*12848STony.Q.Nguyen@oracle.com	if [ "$GLOBAL_POLICY" = "custom" ]; then
734*12848STony.Q.Nguyen@oracle.com		file=`global_get_prop_value $FW_CONFIG_DEF_PG $CUSTOM_FILE_PROP`
7358823STruong.Q.Nguyen@Sun.COM
7368823STruong.Q.Nguyen@Sun.COM		[ -n "$file" ] && custom_set_symlink $file
7378823STruong.Q.Nguyen@Sun.COM		return 0
7388823STruong.Q.Nguyen@Sun.COM	fi
7398823STruong.Q.Nguyen@Sun.COM
7408823STruong.Q.Nguyen@Sun.COM	TEMP=`mktemp /var/run/ipf.conf.pid$$.XXXXXX`
7418823STruong.Q.Nguyen@Sun.COM	process_nonsvc_progs $TEMP
7428823STruong.Q.Nguyen@Sun.COM
7438823STruong.Q.Nguyen@Sun.COM	echo "# Global Default rules" >>${TEMP}
744*12848STony.Q.Nguyen@oracle.com	if [ "$GLOBAL_POLICY" != "none" ]; then
7458823STruong.Q.Nguyen@Sun.COM		echo "pass out log quick all keep state" >>${TEMP}
7468823STruong.Q.Nguyen@Sun.COM	fi
7478823STruong.Q.Nguyen@Sun.COM
748*12848STony.Q.Nguyen@oracle.com	case "$GLOBAL_POLICY" in
7498823STruong.Q.Nguyen@Sun.COM	'none')
7508823STruong.Q.Nguyen@Sun.COM		# No rules
7518823STruong.Q.Nguyen@Sun.COM		replace_file ${IPFILCONF} ${TEMP}
7528823STruong.Q.Nguyen@Sun.COM		return $?
7538823STruong.Q.Nguyen@Sun.COM		;;
7548823STruong.Q.Nguyen@Sun.COM
7558823STruong.Q.Nguyen@Sun.COM	'deny')
7568823STruong.Q.Nguyen@Sun.COM		ecmd="pass"
7578823STruong.Q.Nguyen@Sun.COM		acmd="block"
7588823STruong.Q.Nguyen@Sun.COM		;;
7598823STruong.Q.Nguyen@Sun.COM
7608823STruong.Q.Nguyen@Sun.COM	'allow')
7618823STruong.Q.Nguyen@Sun.COM		ecmd="block"
7628823STruong.Q.Nguyen@Sun.COM		acmd="pass"
7638823STruong.Q.Nguyen@Sun.COM		;;
7648823STruong.Q.Nguyen@Sun.COM	*)
7658823STruong.Q.Nguyen@Sun.COM		return 1;
7668823STruong.Q.Nguyen@Sun.COM		;;
7678823STruong.Q.Nguyen@Sun.COM	esac
7688823STruong.Q.Nguyen@Sun.COM
769*12848STony.Q.Nguyen@oracle.com	for name in `global_get_prop_value $FW_CONFIG_DEF_PG $EXCEPTIONS_PROP`; do
7708823STruong.Q.Nguyen@Sun.COM		[ -z "$name" -o "$name" = '""' ] && continue
7718823STruong.Q.Nguyen@Sun.COM
7728823STruong.Q.Nguyen@Sun.COM		ifc=`get_interface $name`
7738823STruong.Q.Nguyen@Sun.COM		if [ $? -eq 0 -a -n "$ifc" ]; then
7748823STruong.Q.Nguyen@Sun.COM			echo "${ecmd} in log quick on ${ifc} all" >>${TEMP}
7758823STruong.Q.Nguyen@Sun.COM			continue
7768823STruong.Q.Nguyen@Sun.COM		fi
7778823STruong.Q.Nguyen@Sun.COM
7788823STruong.Q.Nguyen@Sun.COM		addr=`get_IP ${name}`
7798823STruong.Q.Nguyen@Sun.COM		if [ $? -eq 0 -a -n "$addr" ]; then
7808823STruong.Q.Nguyen@Sun.COM			echo "${ecmd} in log quick from ${addr} to any" >>${TEMP}
7818823STruong.Q.Nguyen@Sun.COM		fi
7828823STruong.Q.Nguyen@Sun.COM
7838823STruong.Q.Nguyen@Sun.COM	done
7848823STruong.Q.Nguyen@Sun.COM
785*12848STony.Q.Nguyen@oracle.com	for name in `global_get_prop_value $FW_CONFIG_DEF_PG $APPLY2_PROP`; do
7868823STruong.Q.Nguyen@Sun.COM		[ -z "$name" -o "$name" = '""' ] && continue
7878823STruong.Q.Nguyen@Sun.COM
7888823STruong.Q.Nguyen@Sun.COM		ifc=`get_interface $name`
7898823STruong.Q.Nguyen@Sun.COM		if [ $? -eq 0 -a -n "$ifc" ]; then
7908823STruong.Q.Nguyen@Sun.COM			echo "${acmd} in log quick on ${ifc} all" >>${TEMP}
7918823STruong.Q.Nguyen@Sun.COM			continue
7928823STruong.Q.Nguyen@Sun.COM		fi
7938823STruong.Q.Nguyen@Sun.COM
7948823STruong.Q.Nguyen@Sun.COM		addr=`get_IP ${name}`
7958823STruong.Q.Nguyen@Sun.COM		if [ $? -eq 0 -a -n "$addr" ]; then
7968823STruong.Q.Nguyen@Sun.COM			echo "${acmd} in log quick from ${addr} to any" >>${TEMP}
7978823STruong.Q.Nguyen@Sun.COM		fi
7988823STruong.Q.Nguyen@Sun.COM	done
7998823STruong.Q.Nguyen@Sun.COM
800*12848STony.Q.Nguyen@oracle.com	if [ "$GLOBAL_POLICY" = "allow" ]; then
8018823STruong.Q.Nguyen@Sun.COM		#
8028823STruong.Q.Nguyen@Sun.COM		# Allow DHCP traffic if running as a DHCP client
8038823STruong.Q.Nguyen@Sun.COM		#
8048823STruong.Q.Nguyen@Sun.COM		/sbin/netstrategy | grep dhcp >/dev/null 2>&1
8058823STruong.Q.Nguyen@Sun.COM		if [ $? -eq 0 ]; then
8068823STruong.Q.Nguyen@Sun.COM			echo "pass out log quick from any port = 68" \
8078823STruong.Q.Nguyen@Sun.COM			    "keep state" >>${TEMP}
8088823STruong.Q.Nguyen@Sun.COM			echo "pass out log quick from any port = 546" \
8098823STruong.Q.Nguyen@Sun.COM			    "keep state" >>${TEMP}
8108823STruong.Q.Nguyen@Sun.COM			echo "pass in log quick from any to any port = 68" >>${TEMP}
8118823STruong.Q.Nguyen@Sun.COM			echo "pass in log quick from any to any port = 546" >>${TEMP}
8128823STruong.Q.Nguyen@Sun.COM		fi
8138823STruong.Q.Nguyen@Sun.COM		echo "block in log all" >>${TEMP}
8148823STruong.Q.Nguyen@Sun.COM	fi
8158823STruong.Q.Nguyen@Sun.COM
8168823STruong.Q.Nguyen@Sun.COM	replace_file ${IPFILCONF} ${TEMP}
8178823STruong.Q.Nguyen@Sun.COM	return $?
8188823STruong.Q.Nguyen@Sun.COM}
8198823STruong.Q.Nguyen@Sun.COM
8208823STruong.Q.Nguyen@Sun.COM#
8218823STruong.Q.Nguyen@Sun.COM# Generate a new /etc/ipf/ipf_ovr.conf, the override system-wide policy. It's
8228823STruong.Q.Nguyen@Sun.COM# a simplified policy that doesn't support 'exceptions' entities.
8238823STruong.Q.Nguyen@Sun.COM#
8248823STruong.Q.Nguyen@Sun.COM# If firewall policy is "none", no rules are generated.
8258823STruong.Q.Nguyen@Sun.COM#
8268823STruong.Q.Nguyen@Sun.COM# Note that "pass" rules don't have "quick" as we don't want
8278823STruong.Q.Nguyen@Sun.COM# them to override services' block rules.
8288823STruong.Q.Nguyen@Sun.COM#
8298823STruong.Q.Nguyen@Sun.COMcreate_global_ovr_rules()
8308823STruong.Q.Nguyen@Sun.COM{
8318823STruong.Q.Nguyen@Sun.COM	#
8328823STruong.Q.Nguyen@Sun.COM	# Simply empty override file if global policy is 'custom'
8338823STruong.Q.Nguyen@Sun.COM	#
834*12848STony.Q.Nguyen@oracle.com	if [ "$GLOBAL_POLICY" = "custom" ]; then
8358823STruong.Q.Nguyen@Sun.COM		echo "# 'custom' global policy" >$IPFILOVRCONF
8368823STruong.Q.Nguyen@Sun.COM		return 0
8378823STruong.Q.Nguyen@Sun.COM	fi
8388823STruong.Q.Nguyen@Sun.COM
8398823STruong.Q.Nguyen@Sun.COM	#
8408823STruong.Q.Nguyen@Sun.COM	# Get and process override policy
8418823STruong.Q.Nguyen@Sun.COM	#
842*12848STony.Q.Nguyen@oracle.com	ovr_policy=`global_get_prop_value $FW_CONFIG_OVR_PG $POLICY_PROP`
84310256STruong.Q.Nguyen@Sun.COM	if [ "$ovr_policy" = "none" ]; then
84410256STruong.Q.Nguyen@Sun.COM		echo "# global override policy is 'none'" >$IPFILOVRCONF
84510256STruong.Q.Nguyen@Sun.COM		return 0
84610256STruong.Q.Nguyen@Sun.COM	fi
84710256STruong.Q.Nguyen@Sun.COM
8488823STruong.Q.Nguyen@Sun.COM	TEMP=`mktemp /var/run/ipf_ovr.conf.pid$$.XXXXXX`
8498823STruong.Q.Nguyen@Sun.COM	[ "$ovr_policy" = "deny" ] && acmd="block in log quick"
8508823STruong.Q.Nguyen@Sun.COM	[ "$ovr_policy" = "allow" ] && acmd="pass in log"
8518823STruong.Q.Nguyen@Sun.COM
852*12848STony.Q.Nguyen@oracle.com	apply2_list=`global_get_prop_value $FW_CONFIG_OVR_PG $APPLY2_PROP`
8538823STruong.Q.Nguyen@Sun.COM	for name in $apply2_list; do
8548823STruong.Q.Nguyen@Sun.COM		[ -z "$name" -o "$name" = '""' ] && continue
8558823STruong.Q.Nguyen@Sun.COM
8568823STruong.Q.Nguyen@Sun.COM		ifc=`get_interface $name`
8578823STruong.Q.Nguyen@Sun.COM		if [ $? -eq 0 -a -n "$ifc" ]; then
8588823STruong.Q.Nguyen@Sun.COM			echo "${acmd} on ${ifc} all" >>${TEMP}
8598823STruong.Q.Nguyen@Sun.COM			continue
8608823STruong.Q.Nguyen@Sun.COM		fi
8618823STruong.Q.Nguyen@Sun.COM
8628823STruong.Q.Nguyen@Sun.COM		addr=`get_IP ${name}`
8638823STruong.Q.Nguyen@Sun.COM		if [ $? -eq 0 -a -n "$addr" ]; then
8648823STruong.Q.Nguyen@Sun.COM			echo "${acmd} from ${addr} to any" >>${TEMP}
8658823STruong.Q.Nguyen@Sun.COM		fi
8668823STruong.Q.Nguyen@Sun.COM	done
8678823STruong.Q.Nguyen@Sun.COM
8688823STruong.Q.Nguyen@Sun.COM	replace_file ${IPFILOVRCONF} ${TEMP}
8698823STruong.Q.Nguyen@Sun.COM	return $?
8708823STruong.Q.Nguyen@Sun.COM}
8718823STruong.Q.Nguyen@Sun.COM
8728823STruong.Q.Nguyen@Sun.COM#
8738823STruong.Q.Nguyen@Sun.COM# Service is put into maintenance state due to its invalid firewall
8748823STruong.Q.Nguyen@Sun.COM# definition and/or policy.
8758823STruong.Q.Nguyen@Sun.COM#
8768823STruong.Q.Nguyen@Sun.COMsvc_mark_maintenance()
8778823STruong.Q.Nguyen@Sun.COM{
8788823STruong.Q.Nguyen@Sun.COM	svcadm mark maintenance $1 >/dev/null 2>&1
8798823STruong.Q.Nguyen@Sun.COM
8808823STruong.Q.Nguyen@Sun.COM	date=`date`
8818823STruong.Q.Nguyen@Sun.COM	echo "[ $date ${0}: $1 has invalid ipf configuration. ]"
8828823STruong.Q.Nguyen@Sun.COM	echo "[ $date ${0}: placing $1 in maintenance. ]"
8838823STruong.Q.Nguyen@Sun.COM
8848823STruong.Q.Nguyen@Sun.COM	#
8858823STruong.Q.Nguyen@Sun.COM	# Move service's rule files to another location since
8868823STruong.Q.Nguyen@Sun.COM	# they're most likely invalid.
8878823STruong.Q.Nguyen@Sun.COM	#
8888823STruong.Q.Nguyen@Sun.COM	ipfile=`fmri_to_file $1 $IPF_SUFFIX`
8898823STruong.Q.Nguyen@Sun.COM	[ -f "$ipfile" ] && mv $ipfile "$ipfile.bak"
8908823STruong.Q.Nguyen@Sun.COM
8918823STruong.Q.Nguyen@Sun.COM	natfile=`fmri_to_file $1 $NAT_SUFFIX`
8928823STruong.Q.Nguyen@Sun.COM	[ -f "$natfile" ] && mv $natfile "$natfile.bak"
8938823STruong.Q.Nguyen@Sun.COM
8948823STruong.Q.Nguyen@Sun.COM	return 0
8958823STruong.Q.Nguyen@Sun.COM}
8968823STruong.Q.Nguyen@Sun.COM
8978823STruong.Q.Nguyen@Sun.COMsvc_is_server()
8988823STruong.Q.Nguyen@Sun.COM{
8998823STruong.Q.Nguyen@Sun.COM	svcprop -p $FW_CONFIG_PG $1 >/dev/null 2>&1
9008823STruong.Q.Nguyen@Sun.COM}
9018823STruong.Q.Nguyen@Sun.COM
9028823STruong.Q.Nguyen@Sun.COM#
9038823STruong.Q.Nguyen@Sun.COM# Create rules for enabled firewalling and client services.
9048823STruong.Q.Nguyen@Sun.COM# - obtain the list of enabled services and process them
9058823STruong.Q.Nguyen@Sun.COM# - save the list of rules file for later use
9068823STruong.Q.Nguyen@Sun.COM#
9078823STruong.Q.Nguyen@Sun.COMcreate_services_rules()
9088823STruong.Q.Nguyen@Sun.COM{
9098823STruong.Q.Nguyen@Sun.COM	#
9108823STruong.Q.Nguyen@Sun.COM	# Do nothing if global policy is 'custom'
9118823STruong.Q.Nguyen@Sun.COM	#
912*12848STony.Q.Nguyen@oracle.com	[ "$GLOBAL_POLICY" = "custom" ] && return 0
9138823STruong.Q.Nguyen@Sun.COM
9148823STruong.Q.Nguyen@Sun.COM	ipf_get_lock
9158823STruong.Q.Nguyen@Sun.COM
9168823STruong.Q.Nguyen@Sun.COM	#
9178823STruong.Q.Nguyen@Sun.COM	# Get all enabled services
9188823STruong.Q.Nguyen@Sun.COM	#
9198823STruong.Q.Nguyen@Sun.COM	allsvcs=`svcprop -cf -p general/enabled -p general_ovr/enabled '*' \
9208823STruong.Q.Nguyen@Sun.COM	    2>/dev/null | sed -n 's,^\(svc:.*\)/:properties/.* true$,\1,p' | sort -u`
9218823STruong.Q.Nguyen@Sun.COM
9228823STruong.Q.Nguyen@Sun.COM	#
9238823STruong.Q.Nguyen@Sun.COM	# Process enabled services
9248823STruong.Q.Nguyen@Sun.COM	#
9258823STruong.Q.Nguyen@Sun.COM	for s in $allsvcs; do
9268823STruong.Q.Nguyen@Sun.COM		service_is_enabled $s || continue
9278823STruong.Q.Nguyen@Sun.COM		process_service $s || continue
9288823STruong.Q.Nguyen@Sun.COM
9298823STruong.Q.Nguyen@Sun.COM		ipfile=`fmri_to_file $s $IPF_SUFFIX`
9308823STruong.Q.Nguyen@Sun.COM		if [ -n "$ipfile" -a -r "$ipfile" ]; then
9318823STruong.Q.Nguyen@Sun.COM			check_ipf_syntax $ipfile
9328823STruong.Q.Nguyen@Sun.COM			if [ $? -ne 0 ]; then
9338823STruong.Q.Nguyen@Sun.COM				svc_mark_maintenance $s
9348823STruong.Q.Nguyen@Sun.COM				continue
9358823STruong.Q.Nguyen@Sun.COM			fi
9368823STruong.Q.Nguyen@Sun.COM
9378823STruong.Q.Nguyen@Sun.COM			svc_is_server $s
9388823STruong.Q.Nguyen@Sun.COM			if [ $? -eq 0 ]; then
9398823STruong.Q.Nguyen@Sun.COM				check_ipf_rules $ipfile
9408823STruong.Q.Nguyen@Sun.COM				if [ $? -ne 0 ]; then
9418823STruong.Q.Nguyen@Sun.COM					svc_mark_maintenance $s
9428823STruong.Q.Nguyen@Sun.COM					continue
9438823STruong.Q.Nguyen@Sun.COM				fi
9448823STruong.Q.Nguyen@Sun.COM			fi
9458823STruong.Q.Nguyen@Sun.COM			CONF_FILES="$CONF_FILES $ipfile"
9468823STruong.Q.Nguyen@Sun.COM		fi
9478823STruong.Q.Nguyen@Sun.COM
9488823STruong.Q.Nguyen@Sun.COM		natfile=`fmri_to_file $s $NAT_SUFFIX`
9498823STruong.Q.Nguyen@Sun.COM		if [ -n "$natfile" -a -r "$natfile" ]; then
9508823STruong.Q.Nguyen@Sun.COM			check_nat_syntax $natfile
9518823STruong.Q.Nguyen@Sun.COM			if [ $? -ne 0 ]; then
9528823STruong.Q.Nguyen@Sun.COM				svc_mark_maintenance $s
9538823STruong.Q.Nguyen@Sun.COM				continue
9548823STruong.Q.Nguyen@Sun.COM			fi
9558823STruong.Q.Nguyen@Sun.COM
9568823STruong.Q.Nguyen@Sun.COM			NAT_FILES="$NAT_FILES $natfile"
9578823STruong.Q.Nguyen@Sun.COM		fi
9588823STruong.Q.Nguyen@Sun.COM	done
9598823STruong.Q.Nguyen@Sun.COM
9608823STruong.Q.Nguyen@Sun.COM	ipf_remove_lock
9618823STruong.Q.Nguyen@Sun.COM	return 0
9628823STruong.Q.Nguyen@Sun.COM}
9638823STruong.Q.Nguyen@Sun.COM
9648823STruong.Q.Nguyen@Sun.COM#
9658823STruong.Q.Nguyen@Sun.COM# We update a services ipf ruleset in the following manners:
9668823STruong.Q.Nguyen@Sun.COM# - service is disabled, tear down its rules.
9678823STruong.Q.Nguyen@Sun.COM# - service is disable or refreshed(online), setup or update its rules.
9688823STruong.Q.Nguyen@Sun.COM#
9698823STruong.Q.Nguyen@Sun.COMservice_update_rules()
9708823STruong.Q.Nguyen@Sun.COM{
9718823STruong.Q.Nguyen@Sun.COM	svc=$1
9728823STruong.Q.Nguyen@Sun.COM
9738823STruong.Q.Nguyen@Sun.COM	ipfile=`fmri_to_file $svc $IPF_SUFFIX`
9748823STruong.Q.Nguyen@Sun.COM	[ -z "$ipfile" ] && return 0
9758823STruong.Q.Nguyen@Sun.COM
9768823STruong.Q.Nguyen@Sun.COM	remove_rules $ipfile
9778823STruong.Q.Nguyen@Sun.COM
9788823STruong.Q.Nguyen@Sun.COM	natfile=`fmri_to_file $svc $NAT_SUFFIX`
9798823STruong.Q.Nguyen@Sun.COM	[ -n "$natfile" ] && remove_nat_rules $natfile
9808823STruong.Q.Nguyen@Sun.COM
9818823STruong.Q.Nguyen@Sun.COM	#
9828823STruong.Q.Nguyen@Sun.COM	# Don't go further if service is disabled or in maintenance.
9838823STruong.Q.Nguyen@Sun.COM	#
9848823STruong.Q.Nguyen@Sun.COM	service_is_enabled $svc || return 0
9858823STruong.Q.Nguyen@Sun.COM	service_check_state $1 $SMF_MAINT && return 0
9868823STruong.Q.Nguyen@Sun.COM
9878823STruong.Q.Nguyen@Sun.COM	process_service $svc || return 1
9888823STruong.Q.Nguyen@Sun.COM	if [ -f "$ipfile" ]; then
9898823STruong.Q.Nguyen@Sun.COM		check_ipf_syntax $ipfile
9908823STruong.Q.Nguyen@Sun.COM		if [ $? -ne 0 ]; then
9918823STruong.Q.Nguyen@Sun.COM			svc_mark_maintenance $svc
9928823STruong.Q.Nguyen@Sun.COM			return 1
9938823STruong.Q.Nguyen@Sun.COM		fi
9948823STruong.Q.Nguyen@Sun.COM	fi
9958823STruong.Q.Nguyen@Sun.COM
9968823STruong.Q.Nguyen@Sun.COM	if [ -f "$natfile" ]; then
9978823STruong.Q.Nguyen@Sun.COM		check_nat_syntax $natfile
9988823STruong.Q.Nguyen@Sun.COM		if [ $? -ne 0 ]; then
9998823STruong.Q.Nguyen@Sun.COM			svc_mark_maintenance $svc
10008823STruong.Q.Nguyen@Sun.COM			return 1
10018823STruong.Q.Nguyen@Sun.COM		fi
10028823STruong.Q.Nguyen@Sun.COM	fi
10038823STruong.Q.Nguyen@Sun.COM
10048823STruong.Q.Nguyen@Sun.COM	if [ -f "$ipfile" ]; then
10058823STruong.Q.Nguyen@Sun.COM		svc_is_server $svc
10068823STruong.Q.Nguyen@Sun.COM		if [ $? -eq 0 ]; then
10078823STruong.Q.Nguyen@Sun.COM			update_check_ipf_rules $ipfile
10088823STruong.Q.Nguyen@Sun.COM			if [ $? -ne 0 ]; then
10098823STruong.Q.Nguyen@Sun.COM				svc_mark_maintenance $svc
10108823STruong.Q.Nguyen@Sun.COM				return 1
10118823STruong.Q.Nguyen@Sun.COM			fi
10128823STruong.Q.Nguyen@Sun.COM		fi
10138823STruong.Q.Nguyen@Sun.COM
10148823STruong.Q.Nguyen@Sun.COM		prepend_new_rules $ipfile
10158823STruong.Q.Nguyen@Sun.COM
10168823STruong.Q.Nguyen@Sun.COM		#
10178823STruong.Q.Nguyen@Sun.COM		# reload Global Override rules to
10188823STruong.Q.Nguyen@Sun.COM		# maintain correct ordering.
10198823STruong.Q.Nguyen@Sun.COM		#
10208823STruong.Q.Nguyen@Sun.COM		remove_rules $IPFILOVRCONF
10218823STruong.Q.Nguyen@Sun.COM		prepend_new_rules $IPFILOVRCONF
10228823STruong.Q.Nguyen@Sun.COM	fi
10238823STruong.Q.Nguyen@Sun.COM
10248823STruong.Q.Nguyen@Sun.COM	[ -f "$natfile" ] && append_new_nat_rules $natfile
10258823STruong.Q.Nguyen@Sun.COM
10268823STruong.Q.Nguyen@Sun.COM	return 0
10278823STruong.Q.Nguyen@Sun.COM}
10288823STruong.Q.Nguyen@Sun.COM
10298823STruong.Q.Nguyen@Sun.COM#
10308823STruong.Q.Nguyen@Sun.COM# Call the service_update_rules with appropriate svc fmri.
10318823STruong.Q.Nguyen@Sun.COM#
10328823STruong.Q.Nguyen@Sun.COM# This is called from '/lib/svc/method/ipfilter fw_update' whenever
10338823STruong.Q.Nguyen@Sun.COM# a service is disabled/enabled/refreshed.
10348823STruong.Q.Nguyen@Sun.COM#
10358823STruong.Q.Nguyen@Sun.COMservice_update()
10368823STruong.Q.Nguyen@Sun.COM{
10378823STruong.Q.Nguyen@Sun.COM	svc=$1
10388823STruong.Q.Nguyen@Sun.COM	ret=0
10398823STruong.Q.Nguyen@Sun.COM
104012469STruong.Q.Nguyen@Sun.COM	#
104112469STruong.Q.Nguyen@Sun.COM	# If ipfilter isn't online or global policy is 'custom',
104212469STruong.Q.Nguyen@Sun.COM	# nothing should be done.
104312469STruong.Q.Nguyen@Sun.COM	#
1044*12848STony.Q.Nguyen@oracle.com	[ "$GLOBAL_POLICY" = "custom" ] && return 0
104512469STruong.Q.Nguyen@Sun.COM	service_check_state $SMF_FMRI $SMF_ONLINE || return 0
104612469STruong.Q.Nguyen@Sun.COM
10478823STruong.Q.Nguyen@Sun.COM	ipf_get_lock
10488823STruong.Q.Nguyen@Sun.COM	service_update_rules $svc || ret=1
10498823STruong.Q.Nguyen@Sun.COM
10508823STruong.Q.Nguyen@Sun.COM	ipf_remove_lock
10518823STruong.Q.Nguyen@Sun.COM	return $ret
10528823STruong.Q.Nguyen@Sun.COM}
1053*12848STony.Q.Nguyen@oracle.com
1054*12848STony.Q.Nguyen@oracle.com#
1055*12848STony.Q.Nguyen@oracle.com# Initialize global configuration
1056*12848STony.Q.Nguyen@oracle.com#
1057*12848STony.Q.Nguyen@oracle.comglobal_init
1058*12848STony.Q.Nguyen@oracle.com
1059