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