1#!/usr/bin/ksh
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#
27# This command provides an simple interface to configure, destroy, and to obtain
28# the status of a master or slave Kerberos KDC server.
29#
30
31function usage {
32
33	app=`basename $0`
34
35	printf "\n$(gettext "Usage: %s [ -a admprincipal ] [ -e enctype ] [ -h ]")\n" $app
36	printf "\t$(gettext "[ -p pwfile ] [ -r realm ] subcommand")\n\n"
37
38	printf "\t$(gettext "-a: Create non-default admin principal.")\n"
39	printf "\t$(gettext "-e: Encryption type used to encrypt the master key")\n"
40	printf "\t$(gettext "-h: This help message.")\n"
41	printf "\t$(gettext "-p: File that contains the admin principal and master key password.")\n"
42	printf "\t$(gettext "-r: Set the default realm for this server.")\n\n"
43
44	printf "\t$(gettext "where 'subcommand' is one of the following:")\n\n"
45
46	printf "\t$(gettext "create [ master ]")\n"
47	printf "\t$(gettext "create [ -m masterkdc ] slave")\n"
48	printf "\t$(gettext "destroy")\n"
49	printf "\t$(gettext "status")\n\n"
50
51	cleanup 1
52}
53
54function ask {
55
56	# ask question, set global answer
57	typeset question=$1 default_answer=$2
58	if [[ -z $default_answer ]]; then
59		print "$question \c"
60	else
61		print "$question [$default_answer]: \c"
62	fi
63	read answer
64	[ -z "$answer" ] && answer="$default_answer"
65}
66
67function yesno {
68
69	typeset question="$1"
70	# answer is a global set by ask
71	answer=
72	yn=`printf "$(gettext "y/n")"`
73	y=`printf "$(gettext "y")"`
74	n=`printf "$(gettext "n")"`
75	yes=`printf "$(gettext "yes")"`
76	no=`printf "$(gettext "no")"`
77
78	while [[ -z $answer ]]; do
79		ask "$question" $yn
80		case $answer in
81			$y|$yes)	answer=yes;;
82			$n|$no)		answer=no;;
83			*)		answer=;;
84		esac
85	done
86}
87
88function query {
89
90	yesno "$*"
91	if [[ $answer = no ]]; then
92		printf "\t$(gettext "No action performed").\n"
93	fi
94}
95
96function cleanup {
97
98	integer ret=$1
99
100	kdestroy -q -c $TMP_CCACHE 1>$TMP_FILE 2>&1
101        rm -f $TMP_FILE
102
103        exit $ret
104}
105
106function error_message {
107
108        printf "---------------------------------------------------\n"
109        printf "$(gettext "Setup FAILED").\n\n"
110
111	cleanup 1
112}
113
114function check_bin {
115
116	bin=$1
117
118	if [[ ! -x $bin ]]; then
119		printf "$(gettext "Could not access/execute %s").\n" $bin
120		error_message
121	fi
122}
123
124function check_ret {
125
126	integer ret=$1
127	prog=$2
128
129	if [[ $ret -ne 0 ]]; then
130		printf "\n$(gettext "%s failed with return value %d, exiting").\n\n" $prog $ret
131		error_message
132	fi
133}
134
135
136function ok_to_proceed {
137
138	yesno "$@"
139
140	if [[ $answer = no ]]; then
141		printf "\n$(gettext "Exiting, no action performed")\n\n"
142		cleanup 0
143	fi
144}
145
146function check_value {
147
148	typeset arg="$1"
149
150	if [[ -z $arg ]]; then
151		printf "\n$(gettext "No input obtained for %s, exiting").\n" $checkval
152		error_message
153	else
154		echo "$arg">$TMP_FILE
155		if egrep -s '[*$^#!]+' $TMP_FILE; then
156			printf "\n$(gettext "Invalid input obtained for %s, exiting").\n" $checkval
157			error_message
158		fi
159	fi
160}
161
162function setup_kdc_conf {
163
164	printf "\n$(gettext "Setting up %s").\n" $KRB5_KDC_CONF
165
166	if [[ -r $KRB5_KDC_CONF ]]; then
167		cat $KRB5_KDC_CONF > $KRB5_KDC_CONF.sav
168		cannot_create $KRB5_KDC_CONF.sav $?
169	fi
170
171	exec 3>$KRB5_KDC_CONF
172	if [[ $? -ne 0 ]]; then
173		printf "\n$(gettext "Cannot write to %s, exiting").\n" $KRB5_KDC_CONF
174		error_message
175	fi
176
177	printf "\n[kdcdefaults]\n\tkdc_ports = 88,750\n\n" 1>&3
178	printf "[realms]\n\t$REALM = {\n" 1>&3
179	printf "\t\tprofile = $KRB5_KRB_CONF\n" 1>&3
180	printf "\t\tdatabase_name = $PRINCDB\n" 1>&3
181	printf "\t\tmaster_key_type = $ENCTYPE\n" 1>&3
182	printf "\t\tacl_file = $KADM5ACL\n" 1>&3
183	printf "\t\tkadmind_port = 749\n" 1>&3
184	printf "\t\tmax_life = 8h 0m 0s\n" 1>&3
185	printf "\t\tmax_renewable_life = 7d 0h 0m 0s\n" 1>&3
186	printf "\t\tdefault_principal_flags = +preauth\n" 1>&3
187
188	printf "\t\tsunw_dbprop_enable = true\n" 1>&3
189	if [[ $master = yes ]]; then
190		printf "\t\tsunw_dbprop_master_ulogsize = 1000\n" 1>&3
191	fi
192	if [[ $slave = yes ]]; then
193		printf "\t\tsunw_dbprop_slave_poll = 2m\n" 1>&3
194	fi
195
196	printf "\t}\n" 1>&3
197}
198
199function setup_krb_conf {
200
201	printf "\n$(gettext "Setting up %s").\n" $KRB5_KRB_CONF
202
203	if [[ -r $KRB5_KRB_CONF ]]; then
204		cat $KRB5_KRB_CONF > $KRB5_KRB_CONF.sav
205		cannot_create $KRB5_KRB_CONF.sav $?
206	fi
207
208	exec 3>$KRB5_KRB_CONF
209	if [[ $? -ne 0 ]]; then
210		printf "\n$(gettext "Cannot write to %s, exiting").\n" $KRB5_KRB_CONF
211		error_message
212	fi
213
214	printf "[libdefaults]\n" 1>&3
215	printf "\tdefault_realm = $REALM\n\n" 1>&3
216
217	printf "[realms]\n" 1>&3
218	printf "\t$REALM = {\n" 1>&3
219	if [[ $slave = yes ]]; then
220		printf "\t\tkdc = $master_hn\n" 1>&3
221	fi
222	printf "\t\tkdc = $fqhn\n" 1>&3
223	if [[ $master = yes ]]; then
224		printf "\t\tadmin_server = $fqhn\n" 1>&3
225	else
226		printf "\t\tadmin_server = $master_hn\n" 1>&3
227	fi
228	printf "\t}\n\n" 1>&3
229
230	printf "[domain_realm]\n" 1>&3
231	printf "\t.$domain = $REALM\n\n" 1>&3
232
233	printf "[logging]\n" 1>&3
234	printf "\tdefault = FILE:/var/krb5/kdc.log\n" 1>&3
235	printf "\tkdc = FILE:/var/krb5/kdc.log\n" 1>&3
236	printf "\tkdc_rotate = {\n\t\tperiod = 1d\n\t\tversions = 10\n\t}\n\n" 1>&3
237
238	printf "[appdefaults]\n" 1>&3
239	printf "\tkinit = {\n\t\trenewable = true\n\t\tforwardable = true\n" 1>&3
240	printf "\t}\n" 1>&3
241}
242
243function cannot_create {
244
245	typeset filename="$1"
246	typeset stat="$2"
247	if [[ $stat -ne 0 ]]; then
248		printf "\n$(gettext "Cannot create/edit %s, exiting").\n" $filename
249		error_message
250	fi
251}
252
253function check_admin {
254
255	message=$1
256
257	if [[ -z $ADMIN_PRINC ]]; then
258		printf "$message"
259		read ADMIN_PRINC
260		checkval="ADMIN_PRINC"; check_value $ADMIN_PRINC
261	fi
262
263	echo "$ADMIN_PRINC">$TMP_FILE
264
265	if egrep -s '\/admin' $TMP_FILE; then
266		# Already in "/admin" format, do nothing
267		:
268	else
269		if egrep -s '\/' $TMP_FILE; then
270			printf "\n$(gettext "Improper entry for krb5 admin principal, exiting").\n"
271			error_message
272		else
273			ADMIN_PRINC=$(echo "$ADMIN_PRINC/admin")
274		fi
275	fi
276
277}
278
279function ping_check {
280
281	typeset machine="$1"
282
283	if $PING $machine > /dev/null 2>&1; then
284		:
285	else
286		printf "\n$(gettext "%s %s is unreachable, exiting").\n" $string $machine
287		error_message
288	fi
289}
290
291function check_host {
292
293	echo "$host">$TMP_FILE
294	if egrep -s '[^.]\.[^.]+$' $TMP_FILE; then
295		# do nothing, host is in fqhn format
296		:
297	else
298		if egrep -s '\.+' $TMP_FILE; then
299			printf "\n$(gettext "Improper format of host name: '%s'").\n"
300			printf "$(gettext "Expecting the following format: 'somehost.example.com' or 'somehost', exiting").\n"
301			error_message
302		else
303			# Attach fqdn to host, to get the Fully Qualified Domain
304			# Name of the host requested
305			host=$(echo "$host.$domain")
306		fi
307	fi
308
309	#
310	# Ping to see if the host is alive!
311	#
312	ping_check $host
313}
314
315function kill_daemons {
316
317	# Kill daemons so they won't go into maintenance mode
318	$SVCADM disable -s krb5kdc
319	if [[ $? -ne 0 ]]; then
320		printf "\n$(gettext "Error in disabling krb5kdc, exiting").\n"
321		error_message
322	fi
323	$SVCADM disable -s kadmin
324	if [[ $? -ne 0 ]]; then
325		printf "\n$(gettext "Error in disabling kadmind, exiting").\n"
326		error_message
327	fi
328	$SVCADM disable -s krb5_prop
329	if [[ $? -ne 0 ]]; then
330		printf "\n$(gettext "Error in disabling kpropd, exiting").\n"
331		error_message
332	fi
333
334	# Make sure that none of the daemons outside of SMF are running either
335	pkill kadmind
336	if [[ $? -gt 1 ]]; then
337		printf "\n$(gettext "Error in killing kadmind, exiting").\n"
338		error_message
339	fi
340	pkill krb5kdc
341	if [[ $? -gt 1 ]]; then
342		printf "\n$(gettext "Error in killing krb5kdc, exiting").\n"
343		error_message
344	fi
345	pkill kpropd
346	if [[ $? -gt 1 ]]; then
347		printf "\n$(gettext "Error in killing kpropd, exiting").\n"
348		error_message
349	fi
350}
351
352function setup_mkeytab {
353
354	check_admin "\n$(gettext "Enter the krb5 administrative principal to be created"): \c"
355
356	if [[ -z $PWFILE ]]; then
357		echo
358		$KADMINL -q "ank $ADMIN_PRINC"
359		check_ret $? $KADMINL
360	else
361		cat $PWFILE $PWFILE | $KADMINL -q "ank $ADMIN_PRINC" > /dev/null 2>&1
362		check_ret $? $KADMINL
363	fi
364
365	$KADMINL -q "ank -randkey host/$fqhn" 1>$TMP_FILE 2>&1
366	check_ret $? $KADMINL
367	$KADMINL -q "ktadd host/$fqhn" 1>$TMP_FILE 2>&1
368	check_ret $? $KADMINL
369}
370
371function setup_skeytab {
372
373	check_admin "\n$(gettext "Enter the krb5 administrative principal to be used"): \c"
374
375	printf "$(gettext "Obtaining TGT for %s") ...\n" $ADMIN_PRINC
376
377	if [[ -z $PWFILE ]]; then
378		kinit -c $TMP_CCACHE -S kadmin/$master_hn $ADMIN_PRINC
379		check_ret $? kinit
380	else
381		cat $PWFILE | kinit -c $TMP_CCACHE -S kadmin/$master_hn \
382			$ADMIN_PRINC > /dev/null 2>&1
383	fi
384	klist -c $TMP_CCACHE 1>$TMP_FILE 2>&1
385	if egrep -s "$(gettext "Valid starting")" $TMP_FILE && \
386	   egrep -s "kadmin/$master_hn@$REALM" $TMP_FILE; then
387		:
388	else
389		printf "\n$(gettext "kinit of %s failed, exiting").\n" $ADMIN_PRINC
390		error_message
391	fi
392
393	$KADMIN -c $TMP_CCACHE -q "ank -randkey kiprop/$fqhn" 1>$TMP_FILE 2>&1
394	check_ret $? $KADMIN
395	$KADMIN -c $TMP_CCACHE -q "ktadd kiprop/$fqhn" 1>$TMP_FILE 2>&1
396	check_ret $? $KADMIN
397
398	$KADMIN -c $TMP_CCACHE -q "ank -randkey host/$fqhn" 1>$TMP_FILE 2>&1
399	check_ret $? $KADMIN
400	$KADMIN -c $TMP_CCACHE -q "ktadd host/$fqhn" 1>$TMP_FILE 2>&1
401	check_ret $? $KADMIN
402
403	kdestroy -q -c $TMP_CCACHE 1>$TMP_FILE 2>&1
404	check_ret $? $kdestroy
405}
406
407function setup_kadm5acl {
408
409	printf "\n$(gettext "Setting up %s").\n" $KADM5ACL
410
411	if [[ -r $KADM5ACL ]]; then
412		cat $KADM5ACL > $KADM5ACL.sav
413		cannot_create $KADM5ACL.sav $?
414	fi
415
416	exec 3>$KADM5ACL
417	if [[ $? -ne 0 ]]; then
418		printf "\n$(gettext "Cannot write to %s, exiting").\n" $KADM5ACL
419		error_message
420	fi
421
422	if [[ $master = yes ]]; then
423		printf "\n$ADMIN_PRINC@$REALM\t\tacmil\n" 1>&3
424		printf "\nkiprop/*@$REALM\t\tp\n" 1>&3
425	else
426		printf "\n*/admin@___default_realm___\t\t*\n" 1>&3
427	fi
428}
429
430function setup_kpropdacl {
431
432	printf "\n$(gettext "Setting up %s").\n\n" $KPROPACL
433
434	if [[ -r $KPROPACL ]]; then
435		cat $KPROPACL > $KPROPACL.sav
436		cannot_create $KPROPACL.sav $?
437	fi
438
439	exec 3>$KPROPACL
440	if [[ $? -ne 0 ]]; then
441		printf "\n$(gettext "Cannot write to %s, exiting").\n" $KPROPACL
442		error_message
443	fi
444	printf "\nhost/$master_hn@$REALM\n" 1>&3
445}
446
447function setup_master {
448
449	# create principal DB (KDB)
450	if [[ -z $PWFILE ]]; then
451		echo
452		kdb5_util create
453		check_ret $? kdb5_util
454	else
455		cat $PWFILE $PWFILE | kdb5_util create > /dev/null
456		check_ret $? kdb5_util
457	fi
458
459	setup_mkeytab
460	setup_kadm5acl
461
462	$SVCADM enable -r -s krb5kdc
463	$SVCADM enable -r -s kadmin
464}
465
466function setup_slave {
467
468	integer count=1
469
470	setup_skeytab
471
472	# Clear the kadm5acl, since the start methods look at this file
473	# to see if the server has been configured as a master server
474	setup_kadm5acl
475
476	setup_kpropdacl
477
478	$SVCADM enable -r -s krb5_prop
479
480	# Wait for full propagation of the database, in some environments
481	# this could take a few seconds
482	while [[ ! -f /var/krb5/principal ]]; do
483		if [[ count -gt $LOOPCNT ]]; then
484			printf "\n$(gettext "Could not receive updates from the master").\n"
485                        error_message
486			((count = count + 1))
487		fi
488		printf "$(gettext "Waiting for database from master")...\n"
489		sleep $SLEEPTIME
490	done
491
492	# The database is propagated now we need to create the stash file
493	if [[ -z $PWFILE ]]; then
494		kdb5_util stash
495		check_ret $? kdb5_util
496	else
497		cat $PWFILE | kdb5_util stash > /dev/null 2>&1
498		check_ret $? kdb5_util
499	fi
500
501	$SVCADM enable -r -s krb5kdc
502}
503
504function kdb5_destroy {
505	typeset status=0
506	typeset arg=
507
508	[[ -n $REALM ]] && arg="-r $REALM"
509	printf "$(gettext "yes")\n" | kdb5_util $arg destroy > /dev/null 2>&1
510
511	status=$?
512	[[ $status -eq 0 ]] && return $status
513
514	# Could mean that the admin could have already removed part of the
515	# configuration.  Better to check to see if anything else should be
516	# destroyed.  We check by looking at any other stash files in /var/krb5
517	stashfiles=`ls $STASH`
518	for stash in $stashfiles
519	do
520		realm=${stash#*.k5.}
521		[[ -z $realm ]] && continue
522
523		printf "$(gettext "Found non-default realm: %s")\n" $realm
524		query "$(gettext "Do you wish to destroy realm"): $realm ?"
525		if [[ $answer == yes ]]; then
526			printf "$(gettext "yes")\n" | kdb5_util -r $realm destroy > /dev/null 2>&1
527			status=$?
528			if [[ $status -ne 0 ]]; then
529				printf "$(gettext "Could not destroy realm: %s")\n" $realm
530				return $status
531			fi
532		else
533			printf "$(gettext "%s will not be destroyed").\n" $realm
534			status=0
535		fi
536	done
537
538	return $status
539}
540
541function destroy_kdc {
542	typeset status
543
544	# Check first to see if this is an existing KDC or server
545	if [[ -f $KRB5KT || -f $PRINCDB || -f $OLDPRINCDB ]]
546	then
547		if [[ -z $PWFILE ]]; then
548			printf "\n$(gettext "Some of the following files are present on this system"):\n"
549			echo "\t$KRB5KT\n\t$PRINCDB\n\t$OLDPRINCDB\n\t$STASH\n"
550			if [[ -z $d_option ]]; then
551				printf "$(gettext "You must first run 'kdcmgr destroy' to remove all of these files before creating a KDC server").\n\n"
552				cleanup 1
553			else
554				ok_to_proceed "$(gettext "All of these files will be removed, okay to proceed?")"
555			fi
556		fi
557	else
558		if [[ -n $d_option ]]; then
559			printf "\n$(gettext "No KDC related files exist, exiting").\n\n"
560			cleanup 0
561		fi
562		return
563	fi
564
565	kdb5_destroy
566	status=$?
567
568	rm -f $KRB5KT
569
570	[[ $status -ne 0 ]] && cleanup 1
571}
572
573function kadm5_acl_configed {
574
575	if [[ -s $KADM5ACL ]]; then
576		grep -v '^[    ]*#' $KADM5ACL | \
577			egrep '_default_realm_' > /dev/null 2>&1
578		if [[ $? -gt 0 ]]; then
579			return 0
580		fi
581	fi
582
583	return 1
584}
585
586function status_kdc {
587
588	integer is_master=0
589
590	printf "\n$(gettext "KDC Status Information")\n"
591	echo "--------------------------------------------"
592	svcs -xv svc:/network/security/krb5kdc:default
593
594	if kadm5_acl_configed; then
595		is_master=1
596		printf "\n$(gettext "KDC Master Status Information")\n"
597		echo "--------------------------------------------"
598		svcs -xv svc:/network/security/kadmin:default
599	else
600		printf "\n$(gettext "KDC Slave Status Information")\n"
601		echo "--------------------------------------------"
602		svcs -xv svc:/network/security/krb5_prop:default
603	fi
604
605	printf "\n$(gettext "Transaction Log Information")\n"
606	echo "--------------------------------------------"
607	/usr/sbin/kproplog -h
608
609	printf "$(gettext "Kerberos Related File Information")\n"
610	echo "--------------------------------------------"
611	printf "$(gettext "(will display any missing files below)")\n"
612	FILELIST="$KRB5_KDC_CONF $KRB5_KRB_CONF $KADM5ACL $KRB5KT $PRINCDB "
613	for file in $FILELIST; do
614		if [[ ! -s $file ]]; then
615			printf "$(gettext "%s not found").\n" $file
616		fi
617	done
618	if [[ $is_master -eq 0 && ! -s $KPROPACL ]]; then
619		printf "$(gettext "%s not found").\n" $KPROPACL
620	fi
621
622	test ! -s $STASH &&
623	    printf "$(gettext "Stash file not found") (/var/krb5/.k5.*).\n"
624	echo
625
626	cleanup 0
627}
628
629# Start of Main script
630
631typeset -u REALM
632typeset -l host
633typeset -l fqhn
634
635# Defaults
636KRB5_KDC_CONF=/etc/krb5/kdc.conf
637KRB5_KRB_CONF=/etc/krb5/krb5.conf
638KADM5ACL=/etc/krb5/kadm5.acl
639KPROPACL=/etc/krb5/kpropd.acl
640
641KRB5KT=/etc/krb5/krb5.keytab
642PRINCDB=/var/krb5/principal
643OLDPRINCDB=/var/krb5/principal.old
644STASH=/var/krb5/.k5.*
645
646KADMINL=/usr/sbin/kadmin.local;	check_bin $KADMINL
647KADMIN=/usr/sbin/kadmin;	check_bin $KADMIN
648KDCRES=/usr/lib/krb5/klookup;	check_bin $KDCRES
649SVCADM=/usr/sbin/svcadm;	check_bin $SVCADM
650PING=/usr/sbin/ping;		check_bin $PING
651
652ENCTYPE=aes128-cts-hmac-sha1-96
653LOOPCNT=10
654SLEEPTIME=5
655
656if [[ -x /usr/bin/mktemp ]]; then
657	TMP_FILE=$(/usr/bin/mktemp /etc/krb5/krb5tmpfile.XXXXXX)
658	TMP_CCACHE=$(/usr/bin/mktemp /etc/krb5/krb5tmpccache.XXXXXX)
659else
660	TMP_FILE="/etc/krb5/krb5tmpfile.$$"
661	TMP_CCACHE="/etc/krb5/krb5tmpccache.$$"
662fi
663
664if [[ ! -f /etc/resolv.conf ]]; then
665	printf "$(gettext "Error: need to configure /etc/resolv.conf").\n"
666
667	cleanup 1
668fi
669
670fqhn=`$KDCRES`
671if [[ -n "$fqhn" ]]; then
672	:
673elif [[ -n $(hostname) && -n $(domainname) ]]; then
674	fqhn=$(hostname|cut -f1 -d'.').$(domainname|cut -f2- -d'.')
675else
676	printf "$(gettext "Error: can not determine full hostname (FQHN).  Aborting")\n"
677	printf "$(gettext "Note, trying to use hostname and domainname to get FQHN").\n"
678
679	cleanup 1
680fi
681
682ping_check $fqhn
683
684domain=${fqhn#*.} # remove host part
685
686exitmsg=`printf "$(gettext "Exiting...")"`
687
688trap "echo $exitmsg; rm -f $TMP_FILE $TMP_CCACHE; exit 1" HUP INT QUIT TERM
689
690while getopts :a:e:hp:r:s flag
691do
692	case "$flag" in
693		a)	ADMIN_PRINC=$OPTARG;;
694		e)	ENCTYPE=$OPTARG;;
695		h)	usage;;
696		p)	PWFILE=$OPTARG
697			if [[ ! -r $PWFILE ]]; then
698				printf "\n$(gettext "Password file %s does not exist, exiting").\n\n" $PWFILE
699				cleanup 1
700			fi
701			;;
702		r)	REALM=$OPTARG;;
703		*)	usage;;
704	esac
705done
706shift $(($OPTIND - 1))
707
708case "$*" in
709	create)			master=yes;;
710	"create master")	master=yes;;
711	"create -m "*)		host=$3
712				checkval="MASTER"; check_value $host
713				check_host
714				master_hn=$host
715				if [[ $4 != slave ]]; then
716					usage
717				fi;&
718	"create slave")		slave=yes;;
719	destroy)		d_option=yes
720				kill_daemons
721				destroy_kdc
722				cleanup 0;;
723	status)			status_kdc;;
724	*)			usage;;
725esac
726
727kill_daemons
728
729printf "\n$(gettext "Starting server setup")\n"
730printf "---------------------------------------------------\n"
731
732# Checks for existing kdb and destroys if desired
733destroy_kdc
734
735if [[ -z $REALM ]]; then
736	printf "$(gettext "Enter the Kerberos realm"): \c"
737	read REALM
738	checkval="REALM"; check_value $REALM
739fi
740
741if [[ -z $master && -z $slave ]]; then
742	query "$(gettext "Is this machine to be configured as a master?"): \c"
743	master=$answer
744
745	if [[ $answer = no ]]; then
746		query "$(gettext "Is this machine to be configured as a slave?"): \c"
747		slave=$answer
748		if [[ $answer = no ]]; then
749			printf "\n$(gettext "Machine must either be a master or a slave KDC server").\n"
750			error_message
751		fi
752	fi
753fi
754
755if [[ $slave = yes && -z $master_hn ]]; then
756	printf "$(gettext "What is the master KDC's host name?"): \c"
757	read host
758	checkval="MASTER"; check_value $host
759	check_host
760	master_hn=$host
761fi
762
763setup_kdc_conf
764
765setup_krb_conf
766
767if [[ $master = yes ]]; then
768	setup_master
769else
770	setup_slave
771fi
772
773printf "\n---------------------------------------------------\n"
774printf "$(gettext "Setup COMPLETE").\n\n"
775
776cleanup 0
777