xref: /onnv-gate/usr/src/cmd/krb5/kadmin/kclient/kclient.sh (revision 0:68f95e015346)
1*0Sstevel@tonic-gate#!/bin/ksh -p
2*0Sstevel@tonic-gate#
3*0Sstevel@tonic-gate# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
4*0Sstevel@tonic-gate# Use is subject to license terms.
5*0Sstevel@tonic-gate#
6*0Sstevel@tonic-gate# ident	"%Z%%M%	%I%	%E% SMI"
7*0Sstevel@tonic-gate#
8*0Sstevel@tonic-gate# This script is used to setup the Kerberos client by
9*0Sstevel@tonic-gate# supplying information about the Kerberos realm and kdc.
10*0Sstevel@tonic-gate#
11*0Sstevel@tonic-gate# The kerberos configuration file (/etc/krb5/krb5.conf) would
12*0Sstevel@tonic-gate# be generated and local host's keytab file setup. The script
13*0Sstevel@tonic-gate# can also optionally setup the system to do kerberized nfs and
14*0Sstevel@tonic-gate# bringover a master krb5.conf copy from a specified location.
15*0Sstevel@tonic-gate
16*0Sstevel@tonic-gateerror_message() {
17*0Sstevel@tonic-gate	kdestroy -q -c $TMP_CCACHE 1>$TMP_FILE 2>&1
18*0Sstevel@tonic-gate	rm -f $TMP_FILE
19*0Sstevel@tonic-gate	printf "---------------------------------------------------\n"
20*0Sstevel@tonic-gate	printf "$(gettext "Setup FAILED").\n\n"
21*0Sstevel@tonic-gate	exit 1
22*0Sstevel@tonic-gate}
23*0Sstevel@tonic-gate
24*0Sstevel@tonic-gatecannot_create() {
25*0Sstevel@tonic-gate	typeset filename="$1"
26*0Sstevel@tonic-gate	typeset stat="$2"
27*0Sstevel@tonic-gate	if [ $stat -ne 0 ]; then
28*0Sstevel@tonic-gate		printf "\n$(gettext "Cannot create/edit %s, exiting").\n" $filename
29*0Sstevel@tonic-gate		error_message
30*0Sstevel@tonic-gate	fi
31*0Sstevel@tonic-gate}
32*0Sstevel@tonic-gate
33*0Sstevel@tonic-gatemodify_nfssec_conf() {
34*0Sstevel@tonic-gate	if [ -r $NFSSEC_FILE ]; then
35*0Sstevel@tonic-gate		cat $NFSSEC_FILE > $NFSSEC_FILE.sav
36*0Sstevel@tonic-gate		cannot_create $NFSSEC_FILE.sav $?
37*0Sstevel@tonic-gate	fi
38*0Sstevel@tonic-gate
39*0Sstevel@tonic-gate	cat $NFSSEC_FILE > $TMP_FILE
40*0Sstevel@tonic-gate	cannot_create $TMP_FILE $?
41*0Sstevel@tonic-gate
42*0Sstevel@tonic-gate	if grep -s "#krb5" $NFSSEC_FILE > /dev/null 2>&1; then
43*0Sstevel@tonic-gate		sed "s%^#krb5%krb5%" $TMP_FILE >$NFSSEC_FILE
44*0Sstevel@tonic-gate		cannot_create $NFSSEC_FILE $?
45*0Sstevel@tonic-gate	fi
46*0Sstevel@tonic-gate}
47*0Sstevel@tonic-gate
48*0Sstevel@tonic-gatecall_kadmin() {
49*0Sstevel@tonic-gate	typeset svc="$1"
50*0Sstevel@tonic-gate	typeset bool1 bool2 bool3 bool4
51*0Sstevel@tonic-gate
52*0Sstevel@tonic-gate	for listentry in $fqdnlist; do
53*0Sstevel@tonic-gate
54*0Sstevel@tonic-gate	# Reset conditional vars to 1
55*0Sstevel@tonic-gate	bool1=1; bool2=1; bool3=1; bool4=1
56*0Sstevel@tonic-gate
57*0Sstevel@tonic-gate	service_princ=$(echo "$svc/$listentry")
58*0Sstevel@tonic-gate	getprincsubcommand="getprinc $service_princ"
59*0Sstevel@tonic-gate	anksubcommand="addprinc -randkey $service_princ"
60*0Sstevel@tonic-gate	ktaddsubcommand="ktadd $service_princ"
61*0Sstevel@tonic-gate
62*0Sstevel@tonic-gate	kadmin -c $TMP_CCACHE -q "$getprincsubcommand" 1>$TMP_FILE 2>&1
63*0Sstevel@tonic-gate
64*0Sstevel@tonic-gate	egrep -s "get_principal: Principal does not exist" $TMP_FILE
65*0Sstevel@tonic-gate	bool1=$?
66*0Sstevel@tonic-gate	egrep -s "get_principal: Operation requires ``get" $TMP_FILE
67*0Sstevel@tonic-gate	bool2=$?
68*0Sstevel@tonic-gate
69*0Sstevel@tonic-gate	if [[ $bool1 -eq 0 || $bool2 -eq 0 ]]; then
70*0Sstevel@tonic-gate		kadmin -c $TMP_CCACHE -q "$anksubcommand" 1>$TMP_FILE 2>&1
71*0Sstevel@tonic-gate
72*0Sstevel@tonic-gate		egrep -s "add_principal: Principal or policy already exists while creating \"$service_princ@$REALM\"." $TMP_FILE
73*0Sstevel@tonic-gate		bool3=$?
74*0Sstevel@tonic-gate
75*0Sstevel@tonic-gate		egrep -s "Principal \"$service_princ@$REALM\" created." $TMP_FILE
76*0Sstevel@tonic-gate		bool4=$?
77*0Sstevel@tonic-gate
78*0Sstevel@tonic-gate		if [[ $bool3 -eq 0 || $bool4 -eq 0 ]]; then
79*0Sstevel@tonic-gate			printf "$(gettext "%s entry ADDED to KDC database").\n" $service_princ
80*0Sstevel@tonic-gate		else
81*0Sstevel@tonic-gate			cat $TMP_FILE;
82*0Sstevel@tonic-gate			printf "\n$(gettext "kadmin: add_principal of %s failed, exiting").\n" $service_princ
83*0Sstevel@tonic-gate			error_message
84*0Sstevel@tonic-gate		fi
85*0Sstevel@tonic-gate	else
86*0Sstevel@tonic-gate		printf "$(gettext "%s entry already exists in KDC database").\n" $service_princ
87*0Sstevel@tonic-gate	fi
88*0Sstevel@tonic-gate
89*0Sstevel@tonic-gate	klist -k 1>$TMP_FILE 2>&1
90*0Sstevel@tonic-gate	egrep -s "$service_princ@$REALM" $TMP_FILE
91*0Sstevel@tonic-gate	if [ $? -eq 0 ]; then
92*0Sstevel@tonic-gate		printf "$(gettext "%s entry already present in keytab").\n" $service_princ
93*0Sstevel@tonic-gate	else
94*0Sstevel@tonic-gate		kadmin -c $TMP_CCACHE -q "$ktaddsubcommand" 1>$TMP_FILE 2>&1
95*0Sstevel@tonic-gate		egrep -s "added to keytab WRFILE:$KRB5_KEYTAB_FILE." $TMP_FILE
96*0Sstevel@tonic-gate		if [ $? -ne 0 ]; then
97*0Sstevel@tonic-gate			cat $TMP_FILE;
98*0Sstevel@tonic-gate			printf "\n$(gettext "kadmin: ktadd of %s failed, exiting").\n" $service_princ
99*0Sstevel@tonic-gate			error_message
100*0Sstevel@tonic-gate		else
101*0Sstevel@tonic-gate			printf "$(gettext "%s entry ADDED to keytab").\n" $service_princ
102*0Sstevel@tonic-gate		fi
103*0Sstevel@tonic-gate	fi
104*0Sstevel@tonic-gate
105*0Sstevel@tonic-gate	done
106*0Sstevel@tonic-gate}
107*0Sstevel@tonic-gate
108*0Sstevel@tonic-gatewriteup_krb5_conf() {
109*0Sstevel@tonic-gate	printf "\n$(gettext "Setting up %s").\n" $KRB5_CONFIG_FILE
110*0Sstevel@tonic-gate
111*0Sstevel@tonic-gate	if [ -r $KRB5_CONFIG_FILE ]; then
112*0Sstevel@tonic-gate		cat $KRB5_CONFIG_FILE > $KRB5_CONFIG_FILE.sav
113*0Sstevel@tonic-gate		cannot_create $KRB5_CONFIG_FILE.sav $?
114*0Sstevel@tonic-gate	fi
115*0Sstevel@tonic-gate
116*0Sstevel@tonic-gate	exec > $KRB5_CONFIG_FILE
117*0Sstevel@tonic-gate	if [ $? -ne 0 ]; then
118*0Sstevel@tonic-gate		exec > /dev/tty
119*0Sstevel@tonic-gate		printf "\n$(gettext "Cannot write to %s, exiting").\n" $KRB5_CONFIG_FILE
120*0Sstevel@tonic-gate		error_message
121*0Sstevel@tonic-gate	fi
122*0Sstevel@tonic-gate
123*0Sstevel@tonic-gate	printf "[libdefaults]\n"
124*0Sstevel@tonic-gate	if [ "$dns_lookup" = yes ]; then
125*0Sstevel@tonic-gate	    printf "\t$dnsarg = on\n"
126*0Sstevel@tonic-gate	    if [ "$dnsarg" = dns_lookup_kdc ]; then
127*0Sstevel@tonic-gate		printf "\tdefault_realm = $REALM\n"
128*0Sstevel@tonic-gate		printf "\n[domain_realm]\n"
129*0Sstevel@tonic-gate		printf "\t$KDC = $REALM\n"
130*0Sstevel@tonic-gate		printf "\t$client_machine = $REALM\n"
131*0Sstevel@tonic-gate		printf "\t.$fqdn = $REALM\n\n"
132*0Sstevel@tonic-gate	    else
133*0Sstevel@tonic-gate		if [ "$dnsarg" = dns_lookup_realm ]; then
134*0Sstevel@tonic-gate
135*0Sstevel@tonic-gate		    printf "\n[realms]\n"
136*0Sstevel@tonic-gate		    printf "\t$REALM = {\n"
137*0Sstevel@tonic-gate		    printf "\t\tkdc = $KDC\n"
138*0Sstevel@tonic-gate		    printf "\t\tadmin_server = $KDC\n"
139*0Sstevel@tonic-gate		    printf "\t}\n\n"
140*0Sstevel@tonic-gate		else
141*0Sstevel@tonic-gate		    printf "\n\n"
142*0Sstevel@tonic-gate		fi
143*0Sstevel@tonic-gate	    fi
144*0Sstevel@tonic-gate	else
145*0Sstevel@tonic-gate	    printf "\tdefault_realm = $REALM\n\n"
146*0Sstevel@tonic-gate
147*0Sstevel@tonic-gate	    printf "[realms]\n"
148*0Sstevel@tonic-gate	    printf "\t$REALM = {\n"
149*0Sstevel@tonic-gate	    printf "\t\tkdc = $KDC\n"
150*0Sstevel@tonic-gate	    printf "\t\tadmin_server = $KDC\n"
151*0Sstevel@tonic-gate	    printf "\t}\n\n"
152*0Sstevel@tonic-gate
153*0Sstevel@tonic-gate	    printf "[domain_realm]\n"
154*0Sstevel@tonic-gate	    printf "\t$KDC = $REALM\n"
155*0Sstevel@tonic-gate	    printf "\t$client_machine = $REALM\n"
156*0Sstevel@tonic-gate	    printf "\t.$fqdn = $REALM\n\n"
157*0Sstevel@tonic-gate	fi
158*0Sstevel@tonic-gate
159*0Sstevel@tonic-gate	printf "[logging]\n"
160*0Sstevel@tonic-gate	printf "\tdefault = FILE:/var/krb5/kdc.log\n"
161*0Sstevel@tonic-gate	printf "\tkdc = FILE:/var/krb5/kdc.log\n"
162*0Sstevel@tonic-gate
163*0Sstevel@tonic-gate	#
164*0Sstevel@tonic-gate	# return output to TTY
165*0Sstevel@tonic-gate	#
166*0Sstevel@tonic-gate	exec > /dev/tty
167*0Sstevel@tonic-gate}
168*0Sstevel@tonic-gate
169*0Sstevel@tonic-gateask() {
170*0Sstevel@tonic-gate	question=$1
171*0Sstevel@tonic-gate	default_answer=$2
172*0Sstevel@tonic-gate	if [ -z "$default_answer" ]; then
173*0Sstevel@tonic-gate		printf "$question :\c"
174*0Sstevel@tonic-gate	else
175*0Sstevel@tonic-gate		printf "$question [$default_answer]: \c"
176*0Sstevel@tonic-gate	fi
177*0Sstevel@tonic-gate	read answer
178*0Sstevel@tonic-gate	test -z "$answer" && answer="$default_answer"
179*0Sstevel@tonic-gate}
180*0Sstevel@tonic-gate
181*0Sstevel@tonic-gateyesno() {
182*0Sstevel@tonic-gate	typeset question="$1"
183*0Sstevel@tonic-gate	answer=""
184*0Sstevel@tonic-gate	while [ -z "$answer" ]; do
185*0Sstevel@tonic-gate		ask "$question" y/n
186*0Sstevel@tonic-gate		case "$answer" in
187*0Sstevel@tonic-gate			y|yes)	answer=yes;;
188*0Sstevel@tonic-gate			n|no)	answer=no;;
189*0Sstevel@tonic-gate			*)	answer="";;
190*0Sstevel@tonic-gate		esac
191*0Sstevel@tonic-gate	done
192*0Sstevel@tonic-gate}
193*0Sstevel@tonic-gate
194*0Sstevel@tonic-gatequery() {
195*0Sstevel@tonic-gate	yesno "$*"
196*0Sstevel@tonic-gate	if [ "$answer" = no ]; then
197*0Sstevel@tonic-gate		printf "\t$(gettext "No action performed").\n"
198*0Sstevel@tonic-gate	fi
199*0Sstevel@tonic-gate}
200*0Sstevel@tonic-gate
201*0Sstevel@tonic-gate
202*0Sstevel@tonic-gateread_profile() {
203*0Sstevel@tonic-gate	typeset param value
204*0Sstevel@tonic-gate	typeset file="$1"
205*0Sstevel@tonic-gate	if [[ ! -d $file && -r $file ]]; then
206*0Sstevel@tonic-gate		while read param value
207*0Sstevel@tonic-gate		do
208*0Sstevel@tonic-gate			case "$param" in
209*0Sstevel@tonic-gate			REALM)  if [ -z "$REALM" ]; then
210*0Sstevel@tonic-gate					REALM="$value"
211*0Sstevel@tonic-gate					checkval="REALM"; check_value $REALM
212*0Sstevel@tonic-gate				fi
213*0Sstevel@tonic-gate				;;
214*0Sstevel@tonic-gate			KDC)    if [ -z "$KDC" ]; then
215*0Sstevel@tonic-gate					KDC="$value"
216*0Sstevel@tonic-gate					checkval="KDC"; check_value $KDC
217*0Sstevel@tonic-gate				fi
218*0Sstevel@tonic-gate				;;
219*0Sstevel@tonic-gate			ADMIN)  if [ -z "$ADMIN_PRINC" ]; then
220*0Sstevel@tonic-gate					ADMIN_PRINC="$value"
221*0Sstevel@tonic-gate					checkval="ADMIN_PRINC"
222*0Sstevel@tonic-gate    					check_value $ADMIN_PRINC
223*0Sstevel@tonic-gate				fi
224*0Sstevel@tonic-gate				;;
225*0Sstevel@tonic-gate			FILEPATH)  if [ -z "$filepath" ]; then
226*0Sstevel@tonic-gate					filepath="$value"
227*0Sstevel@tonic-gate				   fi
228*0Sstevel@tonic-gate				   ;;
229*0Sstevel@tonic-gate			NFS)    if [ -z "$add_nfs" ]; then
230*0Sstevel@tonic-gate				    if [ "$value" = 1 ]; then
231*0Sstevel@tonic-gate					    add_nfs=yes
232*0Sstevel@tonic-gate				    else
233*0Sstevel@tonic-gate					    add_nfs=no
234*0Sstevel@tonic-gate				    fi
235*0Sstevel@tonic-gate				fi
236*0Sstevel@tonic-gate				;;
237*0Sstevel@tonic-gate			DNSLOOKUP) if [ -z "$dnsarg" ]; then
238*0Sstevel@tonic-gate					dnsarg="$value"
239*0Sstevel@tonic-gate					checkval="DNS_OPTIONS"
240*0Sstevel@tonic-gate					check_value $dnsarg
241*0Sstevel@tonic-gate				   fi
242*0Sstevel@tonic-gate				   ;;
243*0Sstevel@tonic-gate			FQDN) if [ -z "$fqdnlist" ]; then
244*0Sstevel@tonic-gate					fqdnlist="$value"
245*0Sstevel@tonic-gate					checkval="FQDN"
246*0Sstevel@tonic-gate					check_value $fqdnlist
247*0Sstevel@tonic-gate					verify_fqdnlist "$fqdnlist"
248*0Sstevel@tonic-gate			      fi
249*0Sstevel@tonic-gate			      ;;
250*0Sstevel@tonic-gate			esac
251*0Sstevel@tonic-gate		done <$file
252*0Sstevel@tonic-gate	else
253*0Sstevel@tonic-gate		printf "\n$(gettext "The kclient profile \`%s' is not valid, exiting").\n" $file
254*0Sstevel@tonic-gate		error_message
255*0Sstevel@tonic-gate	fi
256*0Sstevel@tonic-gate}
257*0Sstevel@tonic-gate
258*0Sstevel@tonic-gateping_check() {
259*0Sstevel@tonic-gate	typeset machine="$1"
260*0Sstevel@tonic-gate	typeset string="$2"
261*0Sstevel@tonic-gate	if ping $machine > /dev/null; then
262*0Sstevel@tonic-gate		:
263*0Sstevel@tonic-gate	else
264*0Sstevel@tonic-gate		printf "\n$(gettext "%s %s is unreachable, exiting").\n" $string $machine
265*0Sstevel@tonic-gate		error_message
266*0Sstevel@tonic-gate	fi
267*0Sstevel@tonic-gate
268*0Sstevel@tonic-gate	# Output timesync warning if not using a profile, i.e. in
269*0Sstevel@tonic-gate	# interactive mode.
270*0Sstevel@tonic-gate	if [[ -z "$profile" && "$string" = KDC ]]; then
271*0Sstevel@tonic-gate		# It's difficult to sync up time with KDC esp. if in a
272*0Sstevel@tonic-gate		# zone so just print a warning about KDC time sync.
273*0Sstevel@tonic-gate		printf "\n$(gettext "Note, this system and the KDC's time must be within 5 minutes of each other for Kerberos to function.  Both systems should run some form of time synchronization system like Network Time Protocol (NTP)").\n"
274*0Sstevel@tonic-gate	fi
275*0Sstevel@tonic-gate}
276*0Sstevel@tonic-gate
277*0Sstevel@tonic-gatecheck_value() {
278*0Sstevel@tonic-gate	typeset arg="$1"
279*0Sstevel@tonic-gate	if [ -z "$arg" ]; then
280*0Sstevel@tonic-gate		printf "\n$(gettext "No input obtained for %s, exiting").\n" $checkval
281*0Sstevel@tonic-gate		error_message
282*0Sstevel@tonic-gate	else
283*0Sstevel@tonic-gate		echo "$arg">$TMP_FILE
284*0Sstevel@tonic-gate		if egrep -s '[*$^#!]+' $TMP_FILE; then
285*0Sstevel@tonic-gate			printf "\n$(gettext "Invalid input obtained for %s, exiting").\n" $checkval
286*0Sstevel@tonic-gate			error_message
287*0Sstevel@tonic-gate		fi
288*0Sstevel@tonic-gate	fi
289*0Sstevel@tonic-gate}
290*0Sstevel@tonic-gate
291*0Sstevel@tonic-gateset_dns_value() {
292*0Sstevel@tonic-gate	typeset arg="$1"
293*0Sstevel@tonic-gate	if [[ "$arg" = dns_lookup_kdc  ||  "$arg" = dns_lookup_realm  || "$arg" = dns_fallback ]]; then
294*0Sstevel@tonic-gate		dns_lookup=yes
295*0Sstevel@tonic-gate	else
296*0Sstevel@tonic-gate		arg=$(echo "$arg"|tr '[A-Z]' '[a-z]')
297*0Sstevel@tonic-gate		if [ "$arg" = none ]; then
298*0Sstevel@tonic-gate			dns_lookup=no
299*0Sstevel@tonic-gate		else
300*0Sstevel@tonic-gate			printf "\n$(gettext "Invalid DNS lookup option, exiting").\n"
301*0Sstevel@tonic-gate			error_message
302*0Sstevel@tonic-gate		fi
303*0Sstevel@tonic-gate	fi
304*0Sstevel@tonic-gate}
305*0Sstevel@tonic-gate
306*0Sstevel@tonic-gateverify_fqdnlist() {
307*0Sstevel@tonic-gate	integer count=1
308*0Sstevel@tonic-gate
309*0Sstevel@tonic-gate	list=$(echo "$1" | tr -d " " | tr -d "\t")
310*0Sstevel@tonic-gate	hostname=$(uname -n | tr '[A-Z]' '[a-z]' | cut -d"." -f1)
311*0Sstevel@tonic-gate	fqdnlist=$client_machine
312*0Sstevel@tonic-gate
313*0Sstevel@tonic-gate	eachfqdn=$(echo "$list" | cut -d"," -f$count)
314*0Sstevel@tonic-gate	if [ -z "$eachfqdn" ]; then
315*0Sstevel@tonic-gate		printf "\n$(gettext "If the -f option is used, atleast one FQDN should be listed").\n\n"
316*0Sstevel@tonic-gate
317*0Sstevel@tonic-gate		usage
318*0Sstevel@tonic-gate	else
319*0Sstevel@tonic-gate		while [ ! -z "$eachfqdn" ]; do
320*0Sstevel@tonic-gate			tmpvar=$(echo "$eachfqdn" | cut -d"." -f1)
321*0Sstevel@tonic-gate			if [ -z "$tmpvar" ]; then
322*0Sstevel@tonic-gate				fullhost="$hostname$eachfqdn"
323*0Sstevel@tonic-gate			else
324*0Sstevel@tonic-gate				fullhost="$hostname.$eachfqdn"
325*0Sstevel@tonic-gate			fi
326*0Sstevel@tonic-gate
327*0Sstevel@tonic-gate			ping_check $fullhost "System"
328*0Sstevel@tonic-gate			if [ "$fullhost" = "$client_machine" ]; then
329*0Sstevel@tonic-gate				:
330*0Sstevel@tonic-gate			else
331*0Sstevel@tonic-gate				fqdnlist="$fqdnlist $fullhost"
332*0Sstevel@tonic-gate			fi
333*0Sstevel@tonic-gate
334*0Sstevel@tonic-gate			if [[ "$list" == *,* ]]; then
335*0Sstevel@tonic-gate				((count = count + 1))
336*0Sstevel@tonic-gate				eachfqdn=$(echo "$list" | cut -d"," -f$count)
337*0Sstevel@tonic-gate			else
338*0Sstevel@tonic-gate				break
339*0Sstevel@tonic-gate			fi
340*0Sstevel@tonic-gate		done
341*0Sstevel@tonic-gate	fi
342*0Sstevel@tonic-gate}
343*0Sstevel@tonic-gate
344*0Sstevel@tonic-gateusage() {
345*0Sstevel@tonic-gate	printf "\n$(gettext "Usage: kclient [ -n ] [ -R realm ] [ -k kdc ] [ -a adminuser ] [ -c filepath ] [ -d dnsarg ] [ -f fqdn_list ] [ -p profile ]")\n\n"
346*0Sstevel@tonic-gate	printf "$(gettext "Refer kclient(1M) for details, exiting").\n"
347*0Sstevel@tonic-gate	error_message
348*0Sstevel@tonic-gate}
349*0Sstevel@tonic-gate
350*0Sstevel@tonic-gate###########################
351*0Sstevel@tonic-gate#	Main section	  #
352*0Sstevel@tonic-gate###########################
353*0Sstevel@tonic-gate#
354*0Sstevel@tonic-gate# Set the Kerberos config file and some default strings/files
355*0Sstevel@tonic-gate#
356*0Sstevel@tonic-gateKRB5_CONFIG_FILE="/etc/krb5/krb5.conf"
357*0Sstevel@tonic-gateKRB5_KEYTAB_FILE="/etc/krb5/krb5.keytab"
358*0Sstevel@tonic-gateRESOLV_CONF_FILE="/etc/resolv.conf"
359*0Sstevel@tonic-gateNFSSEC_FILE="/etc/nfssec.conf"
360*0Sstevel@tonic-gatedns_lookup="no"
361*0Sstevel@tonic-gateask_fqdns="no"
362*0Sstevel@tonic-gatecheckval=""
363*0Sstevel@tonic-gateprofile=""
364*0Sstevel@tonic-gate
365*0Sstevel@tonic-gate# Set OS release level to Solaris 10, inorder to track the requirement
366*0Sstevel@tonic-gate# of the root/fqdn service principal for kerberized NFS.
367*0Sstevel@tonic-gaterelease_level=10
368*0Sstevel@tonic-gate
369*0Sstevel@tonic-gateif [ -x /usr/bin/mktemp ]; then
370*0Sstevel@tonic-gate	TMP_FILE=$(/usr/bin/mktemp /etc/krb5/krb5tmpfile.XXXXXX)
371*0Sstevel@tonic-gate	TMP_CCACHE=$(/usr/bin/mktemp /etc/krb5/krb5tmpccache.XXXXXX)
372*0Sstevel@tonic-gateelse
373*0Sstevel@tonic-gate	TMP_FILE="/etc/krb5/krb5tmpfile.$$"
374*0Sstevel@tonic-gate	TMP_CCACHE="/etc/krb5/krb5tmpccache.$$"
375*0Sstevel@tonic-gatefi
376*0Sstevel@tonic-gate
377*0Sstevel@tonic-gateif [[ -z "$TMP_FILE" || -z "$TMP_CCACHE" ]]; then
378*0Sstevel@tonic-gate	printf "\n$(gettext "Temporary file creation failed, exiting").\n" >&2
379*0Sstevel@tonic-gate	exit 1
380*0Sstevel@tonic-gatefi
381*0Sstevel@tonic-gate
382*0Sstevel@tonic-gate#
383*0Sstevel@tonic-gate# If we are interrupted, cleanup after ourselves
384*0Sstevel@tonic-gate#
385*0Sstevel@tonic-gatetrap "/usr/bin/rm -f $TMP_FILE $TMP_CCACHE; exit 1" HUP INT QUIT TERM
386*0Sstevel@tonic-gate
387*0Sstevel@tonic-gateif [ -d /usr/bin ]; then
388*0Sstevel@tonic-gate	if [ -d /usr/sbin ]; then
389*0Sstevel@tonic-gate		PATH=/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
390*0Sstevel@tonic-gate		export PATH
391*0Sstevel@tonic-gate	else
392*0Sstevel@tonic-gate		printf "\n$(gettext "Directory /usr/sbin not found, exiting").\n" >&2
393*0Sstevel@tonic-gate		exit 1
394*0Sstevel@tonic-gate	fi
395*0Sstevel@tonic-gateelse
396*0Sstevel@tonic-gate	printf "\n$(gettext "Directory /usr/bin not found, exiting").\n" >&2
397*0Sstevel@tonic-gate	exit 1
398*0Sstevel@tonic-gatefi
399*0Sstevel@tonic-gate
400*0Sstevel@tonic-gateprintf "\n$(gettext "Starting client setup")\n\n"
401*0Sstevel@tonic-gateprintf "---------------------------------------------------\n"
402*0Sstevel@tonic-gate
403*0Sstevel@tonic-gate#
404*0Sstevel@tonic-gate# Check for uid 0, disallow otherwise
405*0Sstevel@tonic-gate#
406*0Sstevel@tonic-gateid 1>$TMP_FILE 2>&1
407*0Sstevel@tonic-gateif [ $? -eq 0 ]; then
408*0Sstevel@tonic-gate	if egrep -s "uid=0\(root\)" $TMP_FILE; then
409*0Sstevel@tonic-gate		# uid is 0, go ahead ...
410*0Sstevel@tonic-gate		:
411*0Sstevel@tonic-gate	else
412*0Sstevel@tonic-gate		printf "\n$(gettext "Root privileges are required to run this script, exiting").\n"
413*0Sstevel@tonic-gate		error_message
414*0Sstevel@tonic-gate	fi
415*0Sstevel@tonic-gateelse
416*0Sstevel@tonic-gate	cat $TMP_FILE;
417*0Sstevel@tonic-gate	printf "\n$(gettext "uid check failed, exiting").\n"
418*0Sstevel@tonic-gate	error_message
419*0Sstevel@tonic-gatefi
420*0Sstevel@tonic-gate
421*0Sstevel@tonic-gate#
422*0Sstevel@tonic-gate# Check for /etc/resolv.conf
423*0Sstevel@tonic-gate#
424*0Sstevel@tonic-gateif [ -r $RESOLV_CONF_FILE ]; then
425*0Sstevel@tonic-gate	while read label text
426*0Sstevel@tonic-gate	do
427*0Sstevel@tonic-gate		case "$label" in
428*0Sstevel@tonic-gate		domain) # Copy the entry into $fqdn
429*0Sstevel@tonic-gate			if [ -z "$text" ]; then
430*0Sstevel@tonic-gate				printf "\n$(gettext "DNS domain info malformed in %s, exiting").\n" $RESOLV_CONF_FILE
431*0Sstevel@tonic-gate				error_message
432*0Sstevel@tonic-gate			fi
433*0Sstevel@tonic-gate			fqdn=$(echo "$text"|tr '[A-Z]' '[a-z]')
434*0Sstevel@tonic-gate			break
435*0Sstevel@tonic-gate			;;
436*0Sstevel@tonic-gate		esac
437*0Sstevel@tonic-gate	done <$RESOLV_CONF_FILE
438*0Sstevel@tonic-gate
439*0Sstevel@tonic-gate	if [ -z "$fqdn" ]; then
440*0Sstevel@tonic-gate		printf "\n$(gettext "DNS domain info missing in %s, exiting").\n" $RESOLV_CONF_FILE
441*0Sstevel@tonic-gate		error_message
442*0Sstevel@tonic-gate	fi
443*0Sstevel@tonic-gateelse
444*0Sstevel@tonic-gate	#
445*0Sstevel@tonic-gate	# /etc/resolv.conf not present, exit ...
446*0Sstevel@tonic-gate	#
447*0Sstevel@tonic-gate	printf "\n$(gettext "%s does not exist and is required for Kerberos setup")\n" $RESOLV_CONF_FILE
448*0Sstevel@tonic-gate	printf "$(gettext "Refer resolv.conf(4), exiting").\n"
449*0Sstevel@tonic-gate	error_message
450*0Sstevel@tonic-gatefi
451*0Sstevel@tonic-gate
452*0Sstevel@tonic-gateclient_machine=$(uname -n | tr '[A-Z]' '[a-z]' | cut -d"." -f1).$fqdn
453*0Sstevel@tonic-gate
454*0Sstevel@tonic-gate#
455*0Sstevel@tonic-gate# Process the command-line arguments (if any)
456*0Sstevel@tonic-gate#
457*0Sstevel@tonic-gateOPTIND=1
458*0Sstevel@tonic-gatewhile getopts np:R:k:a:c:d:f: OPTIONS
459*0Sstevel@tonic-gatedo
460*0Sstevel@tonic-gate	case $OPTIONS in
461*0Sstevel@tonic-gate	    p) options="$options -p"
462*0Sstevel@tonic-gate	       profile="$OPTARG"
463*0Sstevel@tonic-gate	       read_profile $profile
464*0Sstevel@tonic-gate	       ;;
465*0Sstevel@tonic-gate	    R) options="$options -R"
466*0Sstevel@tonic-gate	       REALM="$OPTARG"
467*0Sstevel@tonic-gate	       checkval="REALM"; check_value $REALM
468*0Sstevel@tonic-gate	       ;;
469*0Sstevel@tonic-gate	    k) options="$options -k"
470*0Sstevel@tonic-gate	       KDC="$OPTARG"
471*0Sstevel@tonic-gate	       checkval="KDC"; check_value $KDC
472*0Sstevel@tonic-gate	       ;;
473*0Sstevel@tonic-gate	    a) options="$options -a"
474*0Sstevel@tonic-gate	       ADMIN_PRINC="$OPTARG"
475*0Sstevel@tonic-gate	       checkval="ADMIN_PRINC"; check_value $ADMIN_PRINC
476*0Sstevel@tonic-gate	       ;;
477*0Sstevel@tonic-gate	    c) options="$options -c"
478*0Sstevel@tonic-gate	       filepath="$OPTARG"
479*0Sstevel@tonic-gate	       ;;
480*0Sstevel@tonic-gate	    d) options="$options -d"
481*0Sstevel@tonic-gate	       dnsarg="$OPTARG"
482*0Sstevel@tonic-gate	       checkval="DNS_OPTIONS"; check_value $dnsarg
483*0Sstevel@tonic-gate	       ;;
484*0Sstevel@tonic-gate	    f) options="$options -f"
485*0Sstevel@tonic-gate	       fqdnlist="$OPTARG"
486*0Sstevel@tonic-gate	       verify_fqdnlist "$fqdnlist"
487*0Sstevel@tonic-gate 	       ;;
488*0Sstevel@tonic-gate	    n) options="$options -n"
489*0Sstevel@tonic-gate	       add_nfs=yes
490*0Sstevel@tonic-gate	       ;;
491*0Sstevel@tonic-gate	    \?) usage
492*0Sstevel@tonic-gate		;;
493*0Sstevel@tonic-gate	    *) usage
494*0Sstevel@tonic-gate	       ;;
495*0Sstevel@tonic-gate	esac
496*0Sstevel@tonic-gatedone
497*0Sstevel@tonic-gate
498*0Sstevel@tonic-gate#correct argument count after options
499*0Sstevel@tonic-gateshift `expr $OPTIND - 1`
500*0Sstevel@tonic-gate
501*0Sstevel@tonic-gateif [ -z "$options" ]; then
502*0Sstevel@tonic-gate	:
503*0Sstevel@tonic-gateelse
504*0Sstevel@tonic-gate	if [ $# -ne 0 ]; then
505*0Sstevel@tonic-gate		usage
506*0Sstevel@tonic-gate	fi
507*0Sstevel@tonic-gatefi
508*0Sstevel@tonic-gate
509*0Sstevel@tonic-gateif [ -z "$dnsarg" ]; then
510*0Sstevel@tonic-gate	query "$(gettext "Do you want to use DNS for kerberos lookups") ?"
511*0Sstevel@tonic-gate	if [ "$answer" = yes ]; then
512*0Sstevel@tonic-gate		printf "\n$(gettext "Valid DNS lookup options are dns_lookup_kdc, dns_lookup_realm\nand dns_fallback. Refer krb5.conf(4) for further details").\n"
513*0Sstevel@tonic-gate		printf "\n$(gettext "Enter required DNS option"): \c"
514*0Sstevel@tonic-gate		read dnsarg
515*0Sstevel@tonic-gate		checkval="DNS_OPTIONS"; check_value $dnsarg
516*0Sstevel@tonic-gate		set_dns_value $dnsarg
517*0Sstevel@tonic-gate	fi
518*0Sstevel@tonic-gateelse
519*0Sstevel@tonic-gate	set_dns_value $dnsarg
520*0Sstevel@tonic-gatefi
521*0Sstevel@tonic-gate
522*0Sstevel@tonic-gateif [ -z "$REALM" ]; then
523*0Sstevel@tonic-gate	printf "$(gettext "Enter the Kerberos realm"): \c"
524*0Sstevel@tonic-gate	read REALM
525*0Sstevel@tonic-gate	checkval="REALM"; check_value $REALM
526*0Sstevel@tonic-gatefi
527*0Sstevel@tonic-gateif [ -z "$KDC" ]; then
528*0Sstevel@tonic-gate	printf "$(gettext "Specify the KDC hostname for the above realm"): \c"
529*0Sstevel@tonic-gate	read KDC
530*0Sstevel@tonic-gate	checkval="KDC"; check_value $KDC
531*0Sstevel@tonic-gatefi
532*0Sstevel@tonic-gate
533*0Sstevel@tonic-gateREALM=$(echo "$REALM"|tr '[a-z]' '[A-Z]')
534*0Sstevel@tonic-gateKDC=$(echo "$KDC"|tr '[A-Z]' '[a-z]')
535*0Sstevel@tonic-gate
536*0Sstevel@tonic-gateecho "$KDC">$TMP_FILE
537*0Sstevel@tonic-gateif egrep -s '[^.]\.[^.]+$' $TMP_FILE; then
538*0Sstevel@tonic-gate	# do nothing, KDC is in fqdn format
539*0Sstevel@tonic-gate	:
540*0Sstevel@tonic-gate	echo "$KDC"
541*0Sstevel@tonic-gateelse
542*0Sstevel@tonic-gate	if egrep -s '\.+' $TMP_FILE; then
543*0Sstevel@tonic-gate		printf "\n$(gettext "Improper format of KDC hostname, exiting").\n"
544*0Sstevel@tonic-gate		error_message
545*0Sstevel@tonic-gate	else
546*0Sstevel@tonic-gate		# Attach fqdn to KDC, to get the Fully Qualified Domain Name
547*0Sstevel@tonic-gate		# of the KDC requested
548*0Sstevel@tonic-gate		KDC=$(echo "$KDC.$fqdn")
549*0Sstevel@tonic-gate	fi
550*0Sstevel@tonic-gatefi
551*0Sstevel@tonic-gate#
552*0Sstevel@tonic-gate# Ping to see if the kdc is alive !
553*0Sstevel@tonic-gate#
554*0Sstevel@tonic-gateping_check $KDC "KDC"
555*0Sstevel@tonic-gate
556*0Sstevel@tonic-gate
557*0Sstevel@tonic-gate#
558*0Sstevel@tonic-gate# Start writing up the krb5.conf file, save the existing one
559*0Sstevel@tonic-gate# if already present
560*0Sstevel@tonic-gate#
561*0Sstevel@tonic-gatewriteup_krb5_conf
562*0Sstevel@tonic-gate
563*0Sstevel@tonic-gate
564*0Sstevel@tonic-gate#
565*0Sstevel@tonic-gate# Done creating krb5.conf, so now we ...
566*0Sstevel@tonic-gate#
567*0Sstevel@tonic-gate# 1. kinit with ADMIN_PRINC
568*0Sstevel@tonic-gate#
569*0Sstevel@tonic-gate
570*0Sstevel@tonic-gateif [ -z "$ADMIN_PRINC" ]; then
571*0Sstevel@tonic-gate	printf "\n$(gettext "Enter the krb5 administrative principal to be used"): \c"
572*0Sstevel@tonic-gate	read ADMIN_PRINC
573*0Sstevel@tonic-gate	checkval="ADMIN_PRINC"; check_value $ADMIN_PRINC
574*0Sstevel@tonic-gatefi
575*0Sstevel@tonic-gate
576*0Sstevel@tonic-gateecho "$ADMIN_PRINC">$TMP_FILE
577*0Sstevel@tonic-gate
578*0Sstevel@tonic-gateif egrep -s '\/admin' $TMP_FILE; then
579*0Sstevel@tonic-gate	# Already in "/admin" format, do nothing
580*0Sstevel@tonic-gate	:
581*0Sstevel@tonic-gateelse
582*0Sstevel@tonic-gate	if egrep -s '\/' $TMP_FILE; then
583*0Sstevel@tonic-gate		printf "\n$(gettext "Improper entry for krb5 admin principal, exiting").\n"
584*0Sstevel@tonic-gate		error_message
585*0Sstevel@tonic-gate	else
586*0Sstevel@tonic-gate		ADMIN_PRINC=$(echo "$ADMIN_PRINC/admin")
587*0Sstevel@tonic-gate	fi
588*0Sstevel@tonic-gatefi
589*0Sstevel@tonic-gate
590*0Sstevel@tonic-gateprintf "$(gettext "Obtaining TGT for %s") ...\n" $ADMIN_PRINC
591*0Sstevel@tonic-gateKDC=$(echo "$KDC"|tr '[A-Z]' '[a-z]')
592*0Sstevel@tonic-gatekinit -c $TMP_CCACHE -S kadmin/$KDC $ADMIN_PRINC
593*0Sstevel@tonic-gateklist -c $TMP_CCACHE 1>$TMP_FILE 2>&1
594*0Sstevel@tonic-gateif egrep -s "Valid starting" $TMP_FILE && egrep -s "kadmin/$KDC@$REALM" $TMP_FILE; then
595*0Sstevel@tonic-gate    	:
596*0Sstevel@tonic-gateelse
597*0Sstevel@tonic-gate	printf "\n$(gettext "kinit of %s failed, exiting").\n" $ADMIN_PRINC
598*0Sstevel@tonic-gate	error_message
599*0Sstevel@tonic-gatefi
600*0Sstevel@tonic-gate
601*0Sstevel@tonic-gate#
602*0Sstevel@tonic-gate# 2. Do we want to create and/or add service principal(s) for fqdn's
603*0Sstevel@tonic-gate#    other than the one listed in resolv.conf(4) ?
604*0Sstevel@tonic-gate#
605*0Sstevel@tonic-gateif [ -z "$options" ]; then
606*0Sstevel@tonic-gate	echo
607*0Sstevel@tonic-gate	query "$(gettext "Do you have multiple DNS domains spanning the Kerberos realm") $REALM ?"
608*0Sstevel@tonic-gate	ask_fqdns=$answer
609*0Sstevel@tonic-gate	if [ "$ask_fqdns" = yes ]; then
610*0Sstevel@tonic-gate		printf "$(gettext "Enter a comma-seperated list of DNS domain names"): \c"
611*0Sstevel@tonic-gate		read fqdnlist
612*0Sstevel@tonic-gate		verify_fqdnlist "$fqdnlist"
613*0Sstevel@tonic-gate	else
614*0Sstevel@tonic-gate		fqdnlist=$client_machine
615*0Sstevel@tonic-gate	fi
616*0Sstevel@tonic-gateelse
617*0Sstevel@tonic-gate	if [ -z "$fqdnlist" ]; then
618*0Sstevel@tonic-gate		fqdnlist=$client_machine
619*0Sstevel@tonic-gate	fi
620*0Sstevel@tonic-gatefi
621*0Sstevel@tonic-gate
622*0Sstevel@tonic-gate#
623*0Sstevel@tonic-gate# 3. Set up keytab/config files for nfs/host/root entries (if requested)
624*0Sstevel@tonic-gate#
625*0Sstevel@tonic-gateecho
626*0Sstevel@tonic-gateif [ -z "$options" ]; then
627*0Sstevel@tonic-gate	query "$(gettext "Do you plan on doing Kerberized nfs") ?"
628*0Sstevel@tonic-gate	add_nfs=$answer
629*0Sstevel@tonic-gatefi
630*0Sstevel@tonic-gate
631*0Sstevel@tonic-gateif [ "$add_nfs" = yes ]; then
632*0Sstevel@tonic-gate	modify_nfssec_conf
633*0Sstevel@tonic-gate	echo; call_kadmin nfs
634*0Sstevel@tonic-gate	#
635*0Sstevel@tonic-gate	# Check to see if the system is a pre-S10 system which would
636*0Sstevel@tonic-gate	# require the root/FQDN svc principal for kerberized NFS.
637*0Sstevel@tonic-gate	#
638*0Sstevel@tonic-gate	current_release=$(uname -r | cut -d"." -f2)
639*0Sstevel@tonic-gate	if [ $current_release -lt $release_level ]; then
640*0Sstevel@tonic-gate		echo; call_kadmin root
641*0Sstevel@tonic-gate	fi
642*0Sstevel@tonic-gatefi
643*0Sstevel@tonic-gate
644*0Sstevel@tonic-gate# Add the host entry to the keytab
645*0Sstevel@tonic-gateecho; call_kadmin host
646*0Sstevel@tonic-gate
647*0Sstevel@tonic-gate#
648*0Sstevel@tonic-gate# 4. Copy over krb5.conf master copy from filepath
649*0Sstevel@tonic-gate#
650*0Sstevel@tonic-gateif [ -z "$options" ]; then
651*0Sstevel@tonic-gate	echo
652*0Sstevel@tonic-gate	query "$(gettext "Do you want to copy over the master krb5.conf file") ?"
653*0Sstevel@tonic-gate	if [ "$answer" = yes ]; then
654*0Sstevel@tonic-gate		printf "$(gettext "Enter the pathname of the file to be copied"): \c"
655*0Sstevel@tonic-gate		read filepath
656*0Sstevel@tonic-gate	fi
657*0Sstevel@tonic-gatefi
658*0Sstevel@tonic-gate
659*0Sstevel@tonic-gateif [ -z "$filepath" ]; then
660*0Sstevel@tonic-gate	:
661*0Sstevel@tonic-gateelse
662*0Sstevel@tonic-gate	if [ -r $filepath ]; then
663*0Sstevel@tonic-gate		cp $filepath $KRB5_CONFIG_FILE
664*0Sstevel@tonic-gate		if [ $? -eq 0 ]; then
665*0Sstevel@tonic-gate			printf "\n$(gettext "Copied %s").\n" $filepath
666*0Sstevel@tonic-gate		else
667*0Sstevel@tonic-gate			printf "\n$(gettext "Copy of %s failed, exiting").\n" $filepath
668*0Sstevel@tonic-gate			error_message
669*0Sstevel@tonic-gate		fi
670*0Sstevel@tonic-gate	else
671*0Sstevel@tonic-gate		printf "\n$(gettext "%s not found, exiting").\n" $filepath
672*0Sstevel@tonic-gate		error_message
673*0Sstevel@tonic-gate	fi
674*0Sstevel@tonic-gatefi
675*0Sstevel@tonic-gate
676*0Sstevel@tonic-gateprintf "\n---------------------------------------------------\n"
677*0Sstevel@tonic-gateprintf "$(gettext "Setup COMPLETE").\n"
678*0Sstevel@tonic-gate
679*0Sstevel@tonic-gate#
680*0Sstevel@tonic-gate# 5. Cleanup, please !
681*0Sstevel@tonic-gate#
682*0Sstevel@tonic-gatekdestroy -q -c $TMP_CCACHE 1>$TMP_FILE 2>&1
683*0Sstevel@tonic-gaterm -f $TMP_FILE
684*0Sstevel@tonic-gateexit 0
685