1 #!/sbin/sh
2 #
3 # CDDL HEADER START
4 #
5 # The contents of this file are subject to the terms of the
6 # Common Development and Distribution License (the "License").
7 # You may not use this file except in compliance with the License.
8 #
9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 # or http://www.opensolaris.org/os/licensing.
11 # See the License for the specific language governing permissions
12 # and limitations under the License.
13 #
14 # When distributing Covered Code, include this CDDL HEADER in each
15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 # If applicable, add the following below this CDDL HEADER, with the
17 # fields enclosed by brackets "[]" replaced with your own identifying
18 # information: Portions Copyright [yyyy] [name of copyright owner]
19 #
20 # CDDL HEADER END
21 #
22
23 #
24 # Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
25 # Copyright 2015 Nexenta Systems, Inc. All rights reserved.
26 # Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
27 #
28
29 # Start/stop processes required for server NFS
30
31 . /lib/svc/share/smf_include.sh
32 . /lib/svc/share/ipf_include.sh
33 zone=`smf_zonename`
34
35 case "$1" in
36 'start')
37 # The NFS server is not supported in a local zone
38 if smf_is_nonglobalzone; then
39 /usr/sbin/svcadm disable -t svc:/network/nfs/server
40 echo "The NFS server is not supported in a local zone"
41 sleep 5 &
42 exit $SMF_EXIT_OK
43 fi
44
45 # Share all file systems enabled for sharing. sharemgr understands
46 # regular shares and ZFS shares and will handle both. Technically,
47 # the shares would have been started long before getting here since
48 # nfsd has a dependency on them.
49
50 # restart stopped shares from the repository
51 /usr/sbin/sharemgr start -P nfs -a
52
53 # Options for nfsd are now set in SMF
54
55 /usr/lib/nfs/mountd
56 rc=$?
57 if [ $rc != 0 ]; then
58 /usr/sbin/svcadm mark -t maintenance svc:/network/nfs/server
59 echo "$0: mountd failed with $rc"
60 sleep 5 &
61 exit $SMF_EXIT_ERR_FATAL
62 fi
63
64 /usr/lib/nfs/nfsd
65 rc=$?
66 if [ $rc != 0 ]; then
67 /usr/sbin/svcadm mark -t maintenance svc:/network/nfs/server
68 echo "$0: nfsd failed with $rc"
69 sleep 5 &
70 exit $SMF_EXIT_ERR_FATAL
71 fi
72 ;;
73
74 'refresh')
75 /usr/sbin/sharemgr start -P nfs -a
76 ;;
77
78 'stop')
79 /usr/bin/pkill -x -u 0,1 -z $zone '(nfsd|mountd)'
80
81 # Unshare all shared file systems using NFS
82
83 /usr/sbin/sharemgr stop -P nfs -a
84
85 # Kill any processes left in service contract
86 smf_kill_contract $2 TERM 1
87 [ $? -ne 0 ] && exit 1
88 ;;
89
90 'ipfilter')
91 #
92 # NFS related services are RPC. nfs/server has nfsd which has
93 # well-defined port number but mountd is an RPC daemon.
94 #
95 # Essentially, we generate rules for the following "services"
96 # - nfs/server which has nfsd and mountd
97 # - nfs/rquota
98 #
99 # The following services are enabled for both nfs client and
100 # server, if nfs/client is enabled we'll treat them as client
101 # services and simply allow incoming traffic.
102 # - nfs/status
103 # - nfs/nlockmgr
104 # - nfs/cbd
105 #
106 NFS_FMRI="svc:/network/nfs/server:default"
107 NFSCLI_FMRI="svc:/network/nfs/client:default"
108 RQUOTA_FMRI="svc:/network/nfs/rquota:default"
109 FMRI=$2
110
111 file=`fmri_to_file $FMRI $IPF_SUFFIX`
112 file6=`fmri_to_file $FMRI $IPF6_SUFFIX`
113 echo "# $FMRI" >$file
114 echo "# $FMRI" >$file6
115 policy=`get_policy $NFS_FMRI`
116
117 #
118 # nfs/server configuration is processed in the start method.
119 #
120 if [ "$FMRI" = "$NFS_FMRI" ]; then
121 service_check_state $FMRI $SMF_ONLINE
122 if [ $? -ne 0 ]; then
123 rm $file
124 exit $SMF_EXIT_OK
125 fi
126
127 nfs_name=`svcprop -p $FW_CONTEXT_PG/name $FMRI 2>/dev/null`
128 tport=`$SERVINFO -p -t -s $nfs_name 2>/dev/null`
129 if [ -n "$tport" ]; then
130 generate_rules $FMRI $policy "tcp" $tport $file
131 fi
132
133 tport6=`$SERVINFO -p -t6 -s $nfs_name 2>/dev/null`
134 if [ -n "$tport6" ]; then
135 generate_rules $FMRI $policy "tcp" $tport6 $file6 _6
136 fi
137
138 uport=`$SERVINFO -p -u -s $nfs_name 2>/dev/null`
139 if [ -n "$uport" ]; then
140 generate_rules $FMRI $policy "udp" $uport $file
141 fi
142
143 uport6=`$SERVINFO -p -u6 -s $nfs_name 2>/dev/null`
144 if [ -n "$uport6" ]; then
145 generate_rules $FMRI $policy "udp" $uport6 $file6 _6
146 fi
147
148 # mountd IPv6 ports are also reachable through IPv4, so include
149 # them when generating IPv4 rules.
150 tports=`$SERVINFO -R -p -t -s "mountd" 2>/dev/null`
151 tports6=`$SERVINFO -R -p -t6 -s "mountd" 2>/dev/null`
152 if [ -n "$tports" -o -n "$tports6" ]; then
153 tports=`unique_ports $tports $tports6`
154 for tport in $tports; do
155 generate_rules $FMRI $policy "tcp" \
156 $tport $file
157 done
158 fi
159
160 if [ -n "$tports6" ]; then
161 for tport6 in $tports6; do
162 generate_rules $FMRI $policy "tcp" \
163 $tport6 $file6 _6
164 done
165 fi
166
167 uports=`$SERVINFO -R -p -u -s "mountd" 2>/dev/null`
168 uports6=`$SERVINFO -R -p -u6 -s "mountd" 2>/dev/null`
169 if [ -n "$uports" -o -n "$uports6" ]; then
170 uports=`unique_ports $uports $uports6`
171 for uport in $uports; do
172 generate_rules $FMRI $policy "udp" \
173 $uport $file
174 done
175 fi
176
177 if [ -n "$uports6" ]; then
178 for uport6 in $uports6; do
179 generate_rules $FMRI $policy "udp" \
180 $uport6 $file6 _6
181 done
182 fi
183
184 elif [ "$FMRI" = "$RQUOTA_FMRI" ]; then
185 iana_name=`svcprop -p inetd/name $FMRI`
186
187 # rquota IPv6 ports are also reachable through IPv4, so include
188 # them when generating IPv4 rules.
189 tports=`$SERVINFO -R -p -t -s $iana_name 2>/dev/null`
190 tports6=`$SERVINFO -R -p -t6 -s $iana_name 2>/dev/null`
191 if [ -n "$tports" -o -n "$tports6" ]; then
192 tports=`unique_ports $tports $tports6`
193 for tport in $tports; do
194 generate_rules $NFS_FMRI $policy "tcp" \
195 $tport $file
196 done
197 fi
198
199 if [ -n "$tports6" ]; then
200 for tport6 in $tports6; do
201 generate_rules $NFS_FMRI $policy "tcp" \
202 $tport6 $file6 _6
203 done
204 fi
205
206 uports=`$SERVINFO -R -p -u -s $iana_name 2>/dev/null`
207 uports6=`$SERVINFO -R -p -u6 -s $iana_name 2>/dev/null`
208 if [ -n "$uports" -o -n "$uports6" ]; then
209 uports=`unique_ports $uports $uports6`
210 for uport in $uports; do
211 generate_rules $NFS_FMRI $policy "udp" \
212 $uport $file
213 done
214 fi
215
216 if [ -n "$uports6" ]; then
217 for uport6 in $uports6; do
218 generate_rules $NFS_FMRI $policy "udp" \
219 $uport6 $file6 _6
220 done
221 fi
222 else
223 #
224 # Handle the client services here
225 #
226 if service_check_state $NFSCLI_FMRI $SMF_ONLINE; then
227 policy=none
228 ip=any
229 fi
230
231 restarter=`svcprop -p general/restarter $FMRI 2>/dev/null`
232 if [ "$restarter" = "$INETDFMRI" ]; then
233 iana_name=`svcprop -p inetd/name $FMRI`
234 isrpc=`svcprop -p inetd/isrpc $FMRI`
235 else
236 iana_name=`svcprop -p $FW_CONTEXT_PG/name $FMRI`
237 isrpc=`svcprop -p $FW_CONTEXT_PG/isrpc $FMRI`
238 fi
239
240 if [ "$isrpc" = "true" ]; then
241 tports=`$SERVINFO -R -p -t -s $iana_name 2>/dev/null`
242 tports6=`$SERVINFO -R -p -t6 -s $iana_name 2>/dev/null`
243 uports=`$SERVINFO -R -p -u -s $iana_name 2>/dev/null`
244 uports6=`$SERVINFO -R -p -u6 -s $iana_name 2>/dev/null`
245 else
246 tports=`$SERVINFO -p -t -s $iana_name 2>/dev/null`
247 tports6=`$SERVINFO -p -t6 -s $iana_name 2>/dev/null`
248 uports=`$SERVINFO -p -u -s $iana_name 2>/dev/null`
249 uports6=`$SERVINFO -p -u6 -s $iana_name 2>/dev/null`
250 fi
251
252 # IPv6 ports are also reachable through IPv4, so include
253 # them when generating IPv4 rules.
254 if [ -n "$tports" -o -n "$tports6" ]; then
255 tports=`unique_ports $tports $tports6`
256 for tport in $tports; do
257 generate_rules $FMRI $policy "tcp" $tport $file
258 done
259 fi
260
261 if [ -n "$tports6" ]; then
262 for tport6 in $tports6; do
263 generate_rules $FMRI $policy "tcp" $tport6 $file6 _6
264 done
265 fi
266
267 if [ -n "$uports" -o -n "$uports6" ]; then
268 uports=`unique_ports $uports $uports6`
269 for uport in $uports; do
270 generate_rules $FMRI $policy "udp" $uport $file
271 done
272 fi
273
274 if [ -n "$uports6" ]; then
275 for uport6 in $uports6; do
276 generate_rules $FMRI $policy "udp" $uport6 $file6 _6
277 done
278 fi
279 fi
280
281 ;;
282
283 *)
284 echo "Usage: $0 { start | stop | refresh }"
285 exit 1
286 ;;
287 esac
288 exit $SMF_EXIT_OK