xref: /illumos-gate/usr/src/cmd/tsol/labeld/svc-labeld (revision 36d41b68)
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# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23# Use is subject to license terms.
24#
25
26. /lib/svc/share/smf_include.sh
27
28ROOT_PATH=""
29if [ $# -gt 1 ]; then
30	if [ $# -ne 3 -o "$2" != "-R" ]; then
31		echo "$0: invalid syntax"
32		exit $SMF_EXIT_ERR_CONFIG
33	fi
34	if [ "$3" != "/" ]; then
35		ROOT_PATH=$3
36	fi
37fi
38if [ -n "$ROOT_PATH" -a "$1" != "start" ]; then
39	echo "$0: invalid syntax: -R allowed for start method only"
40	exit $SMF_EXIT_ERR_CONFIG
41fi
42if [ -n "$ROOT_PATH" -a ! -d "$ROOT_PATH" ]; then
43	echo "$0: invalid -R rootpath dir specified"
44	exit $SMF_EXIT_ERR_CONFIG
45fi
46
47if smf_is_nonglobalzone; then
48	echo "$0: not supported in a local zone"
49	exit $SMF_EXIT_ERR_CONFIG
50fi
51
52rewrite_logindev()
53{
54	from="$1"
55	to="$2"
56	# Comment out audio, usb, removable-media, and hotpluggable device
57	# entries in /etc/logindevperm.
58	LOGINDEVPERM=$ROOT_PATH/etc/logindevperm
59	if [ ! -f $LOGINDEVPERM ]; then
60		return
61	fi
62	for line in \
63		"/dev/sound/" \
64		"/dev/removable-media/" \
65		"/dev/hotpluggable/" \
66		"/dev/usb/\[0-9a-f\]" \
67			; do
68		sed -e "s!^$from\([^# 	]\{1,\}[ 	}\{1,\}[0-9]\{1,\}[ 	]\{1,\}\)$line!$to\1$line!" \
69		    $LOGINDEVPERM > /tmp/tmp.$$
70		cp /tmp/tmp.$$ $LOGINDEVPERM
71	done
72	rm -f /tmp/tmp.$$
73}
74
75do_logindev()
76{
77	rewrite_logindev "" "#"
78}
79
80do_otherservices()
81{
82	# Setup dependent services
83	cat >> $ROOT_PATH/var/svc/profile/upgrade <<\__ENABLE_OTHERS
84		/usr/sbin/svcadm enable -s svc:/network/tnd:default
85		/usr/sbin/svcadm enable -s svc:/system/tsol-zones:default
86		/usr/sbin/svccfg -s svc:/application/x11/x11-server \
87		    setprop options/tcp_listen = true
88		/usr/sbin/svcadm enable svc:/network/rpc/rstat:default
89__ENABLE_OTHERS
90
91}
92
93do_bsmconv()
94{
95	# Run bsmconv so audit and device allocation is enabled by
96	# default with Trusted Extensions.
97	if [ "$ROOT_PATH" = "/" -o "$ROOT_PATH" = "" ]; then
98		BSMDIR=""
99	else
100		BSMDIR=$ROOT_PATH
101	fi
102	echo "Running bsmconv ..."
103	echo `TEXTDOMAIN="SUNW_OST_OSCMD" gettext "y"` | \
104	    $ROOT_PATH/etc/security/bsmconv $ROOT_PATH
105}
106
107do_nscd()
108{
109# For Trusted Extensions, make nscd service transient in local zones.
110cat >> $ROOT_PATH/var/svc/profile/upgrade <<\_DEL_LOCAL_NSCD
111	if [ `/sbin/zonename` != "global" ]; then
112		nscd="svc:/system/name-service-cache"
113		duration=""
114		if /bin/svcprop -q -c -p startd/duration $nscd ; then
115			duration=`/bin/svcprop -c -p startd/duration $nscd`
116		fi
117		if [ "$duration" != "transient" ]; then
118			/usr/sbin/svccfg -s $nscd addpg startd framework
119			/usr/sbin/svccfg -s $nscd setprop \
120			    startd/duration = astring: transient
121			/usr/sbin/svccfg -s $nscd setprop stop/exec = :true
122			/usr/sbin/svcadm refresh $nscd
123		fi
124	fi
125_DEL_LOCAL_NSCD
126}
127
128do_bootupd()
129{
130	if [ -f $ROOT_PATH/platform/`/sbin/uname -m`/boot_archive ]; then
131		if [ -z "$ROOT_PATH" -o "$ROOT_PATH" = "/" ]; then
132			/sbin/bootadm update-archive
133		else
134			/sbin/bootadm update-archive -R $ROOT_PATH
135		fi
136	fi
137}
138
139setup_tx_changes(){
140#
141# No comments or blanks lines allowed in entries below
142#
143cat > ${TX_ENTRIES} << EOF
144dtlogin		account		requisite	pam_roles.so.1
145dtlogin		account		required	pam_unix_account.so.1
146dtsession	account		requisite	pam_roles.so.1
147dtsession	account		required	pam_unix_account.so.1
148gdm		account		requisite	pam_roles.so.1
149gdm		account		required	pam_unix_account.so.1
150xscreensaver	account		requisite	pam_roles.so.1
151xscreensaver	account		required	pam_unix_account.so.1
152passwd		account		requisite	pam_roles.so.1
153passwd		account		required	pam_unix_account.so.1
154dtpasswd	account		requisite	pam_roles.so.1
155dtpasswd	account		required	pam_unix_account.so.1
156tsoljds-tstripe	account		requisite	pam_roles.so.1
157tsoljds-tstripe	account		required	pam_unix_account.so.1
158other		account		required	pam_tsol_account.so.1
159EOF
160}
161
162do_addpam()
163{
164	PAM_TMP=/tmp/pam_conf.$$
165	TX_ENTRIES=$PAM_TMP/sct.$$
166	PAM_DEST=$ROOT_PATH/etc/pam.conf
167
168	mkdir $PAM_TMP  || exit $SMF_EXIT_ERR_FATAL
169	setup_tx_changes
170
171	# verify that pam.conf file exists...
172	if [ ! -f ${PAM_DEST} ]; then
173		echo "$0: ${PAM_DEST} not found; aborting"
174		exit $SMF_EXIT_ERR_FATAL
175	fi
176
177	#
178	# Update pam.conf to append Trusted Extensions entries if not
179	# already present.
180	#
181	rm -f /tmp/pamconf.$$
182	while read e1 e2 e3 e4 e5
183	do
184		# If this is the 'other' entry, add it unless it already
185		# exists.
186		if [ $e1 = "other" ]; then
187			grep \
188"^[# 	]*$e1[ 	][ 	]*$e2[ 	][ 	]*$e3[ 	][ 	]*$e4" \
189			    $PAM_DEST >/dev/null 2>&1
190			if [ $? = 1 ] ; then
191				# Doesn't exist, enter into pam.conf
192				echo "$e1\t$e2 $e3\t\t$e4 $e5" \
193				    >> /tmp/pamconf.$$
194			fi
195		else
196			# Add other entries unless they already have a
197			# stack of their own.
198			grep "^[# 	]*$e1[ 	][ 	]*$e2[ 	]" \
199			    $PAM_DEST >/dev/null 2>&1
200			if [ $? = 1 ] ; then
201				echo "$e1\t$e2 $e3\t\t$e4 $e5" \
202				    >> /tmp/pamconf.$$
203			fi
204		fi
205	done < ${TX_ENTRIES}
206	# Append TX lines if any were not present already.
207	if [ -f /tmp/pamconf.$$ ] ; then
208		echo "# Entries for Trusted Extensions" >> $PAM_DEST
209		cat /tmp/pamconf.$$ >> $PAM_DEST
210		echo "$0: updating $PAM_DEST entries for Trusted Extensions;"
211		echo "$0: please examine/update any new entries"
212    		rm -f /tmp/pamconf.$$
213    	fi
214
215	rm -rf $PAM_TMP
216}
217
218do_pamremove()
219{
220	PAM_TMP=/tmp/pam_conf.$$
221	TX_ENTRIES=$PAM_TMP/sct.$$
222	PAM_DEST=$ROOT_PATH/etc/pam.conf
223	TMPFILE=$PAM_TMP/pam.conf
224
225	mkdir $PAM_TMP  || exit $SMF_EXIT_ERR_FATAL
226
227	# verify that pam.conf file exists...
228	if [ ! -f ${PAM_DEST} ]; then
229		echo "$0: ${PAM_DEST} not found; aborting"
230		exit $SMF_EXIT_ERR_FATAL
231	fi
232
233
234	grep '^[a-z].*pam_tsol_account' $PAM_DEST > /dev/null 2>&1
235	if [ $? -ne 0 ]; then
236		echo "$0: pam_tsol_account module not present,"
237		echo "$0: No changes were made to $PAM_DEST."
238		return
239	fi
240
241	grep -v pam_tsol_account $PAM_DEST > $TMPFILE
242	echo "$0: $PAM_DEST "tsol" entries removed"
243	cp $TMPFILE $PAM_DEST
244
245	rm -rf $PAM_TMP
246}
247
248do_commonstart()
249{
250	echo "$0: Updating $ROOT_PATH/etc/system..."
251	if [ ! -f ${ROOT_PATH}/etc/system ]; then
252		touch ${ROOT_PATH}/etc/system
253	fi
254
255	# Set sys_labeling in etc/system
256	grep -v "sys_labeling=" ${ROOT_PATH}/etc/system > /tmp/etc.system.$$
257	echo "set sys_labeling=1" >> /tmp/etc.system.$$
258	mv /tmp/etc.system.$$ ${ROOT_PATH}/etc/system
259	grep "set sys_labeling=1" ${ROOT_PATH}/etc/system > /dev/null 2>&1
260	if [ $? -ne 0 ]; then
261    		echo "$0: ERROR: cannot set sys_labeling in $ROOT_PATH/etc/system"
262		exit $SMF_EXIT_ERR_FATAL
263	fi
264
265	# Setup dependent services
266	do_otherservices
267
268	do_logindev
269	do_bsmconv
270	do_nscd
271	do_addpam
272
273	do_bootupd
274}
275
276do_servicetag_register()
277{
278	ROOTDIR=$1
279	SOL_ARCH=`/sbin/uname -p`
280	SOL_VERS=`/sbin/uname -r`
281	TX_PROD_URN="urn:uuid:fc720df3-410f-11dc-9b8e-080020a9ed93"
282
283	if [ ! -x /usr/bin/stclient ]; then
284		return
285	fi
286
287	# if already registered then do nothing more here
288	inst=`/usr/bin/svcprop -p labeld/svctag_inst $SMF_FMRI 2>/dev/null`
289	if [ -n "$inst" ]; then
290		# this instance id was saved in a SMF property
291		/usr/bin/stclient -g -i $inst -r $ROOTDIR >/dev/null 2>&1
292		if [ $? = 0 ]; then
293			# matching service tag found, so do nothing
294			return
295		else
296			# no match for instance id saved in SMF property
297			/usr/sbin/svccfg -s $SMF_FMRI delprop \
298			    labeld/svctag_inst
299			/usr/sbin/svcadm refresh $SMF_FMRI
300		fi
301	fi
302
303
304	# fall through: no service tag, or does not match saved instance id
305
306	# determine the urn of the parent (Solaris)
307	SOL_PROD_URN=""
308	case $SOL_VERS in
309	5.11)
310		SOL_PROD_URN="-F urn:uuid:6df19e63-7ef5-11db-a4bd-080020a9ed93"
311		;;
312	5.10)
313		SOL_PROD_URN="-F urn:uuid:5005588c-36f3-11d6-9cec-fc96f718e113"
314		;;
315	esac
316
317	# add the service tag
318	RC=`/usr/bin/stclient -a -p "Solaris Trusted Extensions"	\
319	    -e $SOL_VERS -t $TX_PROD_URN -P Solaris $SOL_PROD_URN	\
320	    -m Sun -A $SOL_ARCH -z global -S $0 -r $ROOTDIR`
321	if [ $? = 0 ]; then
322		# save instance id in SMF property
323		inst=`echo "$RC" | grep -i urn|awk -F=  '{print $2}'`
324		/usr/sbin/svccfg -s $SMF_FMRI setprop \
325		    labeld/svctag_inst = astring: "$inst"
326		/usr/sbin/svcadm refresh $SMF_FMRI
327	fi
328}
329
330do_servicetag_delete()
331{
332	if [ ! -x /usr/bin/stclient ]; then
333		return
334	fi
335
336	inst=`/usr/bin/svcprop -p labeld/svctag_inst $SMF_FMRI 2>/dev/null`
337
338	if [ -n "$inst" ]; then
339		# delete service tag
340		/usr/bin/stclient -d -i $inst
341		# delete saved instance id
342		/usr/sbin/svccfg -s $SMF_FMRI delprop labeld/svctag_inst
343		/usr/sbin/svcadm refresh $SMF_FMRI
344	fi
345}
346
347
348daemon_start()
349{
350	# If a labeld door exists, check for a labeld process and exit
351	# if the daemon is already running.
352	if [ -r /var/tsol/doors/labeld ]; then
353		if /usr/bin/pgrep -x -u 0 -P 1 labeld >/dev/null 2>&1; then
354			echo "$0: labeld is already running"
355			exit $SMF_EXIT_ERR_FATAL
356		fi
357	fi
358	/usr/bin/rm -f /var/tsol/doors/labeld
359	/usr/lib/labeld
360}
361
362PATH=/usr/sbin:/usr/bin; export PATH
363
364case "$1" in
365'start')
366	if [ -z "$ROOT_PATH" -o "$ROOT_PATH" = "/" ]; then
367		# native
368
369		if [ -z "$SMF_FMRI" ]; then
370			echo "$0: this script can only be invoked by smf(5)"
371			exit $SMF_EXIT_ERR_NOSMF
372		fi
373
374		tx_enabled=`/usr/bin/svcprop -c -p general/enabled $SMF_FMRI`
375		if [ "$tx_enabled" = "false" ]; then
376			# A sign of trying temporary enablement...no-no
377			echo "$0: Temporarily enabling Trusted Extensions is not allowed."
378			exit $SMF_EXIT_ERR_CONFIG
379		fi
380
381		if (smf_is_system_labeled); then
382			do_servicetag_register /
383			daemon_start
384			exit $SMF_EXIT_OK
385		fi
386
387		# Make changes to enable Trusted Extensions
388		grep "^set sys_labeling=1" ${ROOT_PATH}/etc/system > /dev/null 2>&1
389		if [ $? -eq 0 ]; then
390			echo "$0: already enabled. Exiting."
391			exit $SMF_EXIT_OK
392		fi
393
394		if [ "`/usr/sbin/zoneadm list -c`" != "global" ]; then
395			echo "$0: Must remove zones before enabling Trusted Extensions."
396			exit $SMF_EXIT_ERR_CONFIG
397		fi
398
399		do_commonstart
400
401		do_servicetag_register /
402
403		# start daemon proccess so our service doesn't go into
404		# maintenance state
405		daemon_start
406
407		echo "$0: Started.  Must reboot and configure Trusted Extensions."
408	else
409		# Support jumpstart etc
410
411		# Make changes to enable Trusted Extensions
412		grep "^set sys_labeling=1" ${ROOT_PATH}/etc/system > /dev/null 2>&1
413		if [ $? -eq 0 ]; then
414			echo "$0: already enabled. Exiting."
415			exit $SMF_EXIT_OK
416		fi
417
418		# Setup dependent services
419		cat >> $ROOT_PATH/var/svc/profile/upgrade <<\__TRUSTED_ENABLE
420			/usr/sbin/svcadm enable -s svc:/system/labeld:default
421__TRUSTED_ENABLE
422
423		do_commonstart
424		do_servicetag_register $ROOT_PATH
425		echo "$0: Started.  Must configure Trusted Extensions before booting."
426	fi
427	;;
428
429'stop')
430	tx_enabled=`/usr/bin/svcprop -c -p general/enabled $SMF_FMRI`
431	if [ "$tx_enabled" = "true" ]; then
432		/usr/bin/pkill -x -u 0 -P 1 -z `smf_zonename` labeld
433		exit $SMF_EXIT_OK
434	fi
435
436	if [ "`/usr/sbin/zoneadm list -c`" != "global" ]; then
437		echo "$0: Must remove zones before disabling Trusted Extensions."
438		exit $SMF_EXIT_ERR_CONFIG
439	fi
440
441	# Stop Trusted services.
442	/usr/sbin/svcadm disable svc:/system/tsol-zones:default 2>/dev/null
443	/usr/sbin/svcadm disable svc:/network/tnd:default 2>/dev/null
444
445	# Uncomment audio, usb, removable-media, and hotpluggable device
446	# entries in /etc/logindevperm.
447	rewrite_logindev "#" ""
448
449	# Remove sys_labeling from /etc/system
450	grep -v "sys_labeling" ${ROOT_PATH}/etc/system > /tmp/etc.system.$$
451	mv /tmp/etc.system.$$ ${ROOT_PATH}/etc/system
452	grep "sys_labeling" ${ROOT_PATH}/etc/system > /dev/null 2>&1
453	if [ $? -eq 0 ]; then
454    		echo "$0: ERROR: cannot remove sys_labeling in $ROOT_PATH/etc/system"
455		exit $SMF_EXIT_ERR_FATAL
456	fi
457
458	do_pamremove
459	do_servicetag_delete
460
461	do_bootupd
462
463	/usr/bin/pkill -x -u 0 -P 1 -z `smf_zonename` labeld
464	echo "$0: Stopped.  Will take effect at next boot."
465	;;
466
467*)
468	echo "Usage: $0 { start | stop }"
469	exit 1
470	;;
471esac
472
473exit $SMF_EXIT_OK
474
475
476